レンダリングターゲットの作成


上記初期化処理の後に、レンダリングターゲットを作成します。

変数の定義
	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;
アプリの終了時に実行する後始末の処理です


back