レンダリングターゲットの作成 |
変数の定義 |
ID3D11RenderTargetView **m_ppRenderTargetView; ovrSwapTextureSet *m_pTextureSet; ovrLayerEyeFov m_OVRLayer; |
レンダリングターゲットのサイズを決定 |
// デバイス固有の情報を取得 // ovrHmdDesc ovrDesc = ovr_GetHmdDesc( m_OVRSessionId ); // 左右のレンダリングサイズを取得 // ovrSizei recommenedTex0Size, recommenedTex1Size; recommenedTex0Size = ovr_GetFovTextureSize( m_OVRSessionId, ovrEye_Left, ovrDesc.DefaultEyeFov[ovrEye_Left], 1.0f ); recommenedTex1Size = ovr_GetFovTextureSize( m_OVRSessionId, ovrEye_Right, ovrDesc.DefaultEyeFov[ovrEye_Right], 1.0f ); // 1枚のレンダリングターゲットに左目用、右目用2枚の映像を配置するように bufferSize を決定 // ovrSizei bufferSize; bufferSize.w = recommenedTex0Size.w + recommenedTex1Size.w; bufferSize.h = max ( recommenedTex0Size.h, recommenedTex1Size.h ); |
通常 DK2 では左右共に 1182 x 1464 で、レンダリングターゲットのサイズは 2364 x 1464 になります ただし、ここで取得できる解像度は推奨値のようで、適当な値に変更してもその後の処理に問題は発生しないようです 当然サイズを小さくすれば解像度は粗くなります ここで取得した ovrDesc から HMD のリフレッシュレート(ovrDesc.DisplayRefreshRate)を取得することができます 通常 DK2 では 75.0 固定ですが、デバイスからの情報を忠実に適用したい場合はこの数値をもとにして同期をとるといいでしょう |
スワップバッファの作成 |
// bufferSize サイズのバックバッファを作成 // D3D11_TEXTURE2D_DESC TexDesc; memset( &TexDesc, 0, sizeof(TexDesc) ); TexDesc.Width = bufferSize.w; TexDesc.Height = bufferSize.h; TexDesc.MipLevels = 1; TexDesc.ArraySize = 1; TexDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; TexDesc.SampleDesc.Count = 1; TexDesc.SampleDesc.Quality = 0; TexDesc.Usage = D3D11_USAGE_DEFAULT; TexDesc.CPUAccessFlags = 0; TexDesc.MiscFlags = 0; TexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; // ID3D11Device *pD3D11Device = ...; // ID3D11Device を取得、ここはアプリの設計依存 // if (ovr_CreateSwapTextureSetD3D11( m_OVRSessionId, pD3D11Device, &TexDesc, 0, &m_pTextureSet ) != ovrSuccess) { // error return; } |
通常 DK2 では 2 枚のスワップバッファが作成されます 何枚のスワップバッファが作成されたかは m_pTextureSet->TextureCount でわかります |
レンダリングターゲットの作成 |
// レンダリングターゲットへのポインタ配列を確保 // m_ppRenderTargetView = new ID3D11RenderTargetView * [ m_pTextureSet->TextureCount ]; // レンダリングターゲットを作成 // for(int i=0;i<m_pTextureSet->TextureCount;i++) { ovrD3D11Texture *pD3DTex = (ovrD3D11Texture*)&m_pTextureSet->Textures[i]; ID3D11Texture2D *pTexture = pD3DTex->D3D11.pTexture; // if (pDevice->CreateRenderTargetView( pTexture, NULL, m_ppRenderTargetView + i ) != S_OK) { // error return; } } |
深度バッファの作成 |
レンダリングターゲットに合わせた深度バッファが必要な場合は、( bufferSize.w , bufferSize.h ) サイズで作成します 基本的に VR デバイスは深度バッファに感知しないので、作成も管理も破棄もアプリ側でします 深度バッファが不要なら作成しなくても構いません この部分のコードは普通に DirectX11 で深度バッファを作成するだけなので省略します |
その他のレンダリングパラメータ |
ovrEyeRenderDesc eyeRenderDesc[2]; eyeRenderDesc[0] = ovr_GetRenderDesc( m_OVRSessionId, ovrEye_Left, ovrDesc.DefaultEyeFov[0] ); eyeRenderDesc[1] = ovr_GetRenderDesc( m_OVRSessionId, ovrEye_Right, ovrDesc.DefaultEyeFov[1] ); // m_OVRLayer.Header.Type = ovrLayerType_EyeFov; m_OVRLayer.Header.Flags = 0; m_OVRLayer.ColorTexture[0] = m_pTextureSet; m_OVRLayer.ColorTexture[1] = m_pTextureSet; m_OVRLayer.Fov[0] = eyeRenderDesc[0].Fov; m_OVRLayer.Fov[1] = eyeRenderDesc[1].Fov; // 1枚のレンダリングターゲットに対する左右それぞれのレンダリング範囲を設定 // m_OVRLayer.Viewport[0].Pos.x = 0; m_OVRLayer.Viewport[0].Pos.y = 0; m_OVRLayer.Viewport[0].Size.w = recommenedTex0Size.w; m_OVRLayer.Viewport[0].Size.h = recommenedTex0Size.h; m_OVRLayer.Viewport[1].Pos.x = recommenedTex0Size.w; m_OVRLayer.Viewport[1].Pos.y = 0; m_OVRLayer.Viewport[1].Size.w = recommenedTex1Size.w; m_OVRLayer.Viewport[1].Size.h = recommenedTex1Size.h; |
後始末 |
// レンダリングターゲットの破棄 // delete [] m_ppRenderTargetView; |
アプリの終了時に実行する後始末の処理です |