Microsoft DirectX 8.0 (C++) |
キューブ マップの個々のサーフェスへは、その他のテクスチャやサーフェス オブジェクトと同じように画像をコピーすることができる。このレンダリングを行う前に実行する最も大切なことは、カメラを正しく配置し、そのサーフェスに対して正しい方向を向くようにトランスフォーム行列を設定することである。正しい方向とは、前方 (+z)、後方 (-z)、左 (-x)、右 (+x)、上方 (+y)、または下方 (-y) である。
次の C++ コードは、レンダリングするサーフェスに応じてビュー行列を用意して設定する。
/* * この例では、pCubeMap は IDirect3DCubeTexture8 インターフェイスへの有効なポインタであり、 * d3dDevice は IDirect3DDevice8 インターフェイスへの * 有効なポインタである。 */ void RenderFaces() { // デバイスのトランスフォーム行列を保存する。 D3DXMATRIX matProjSave, matViewSave; d3dDevice->GetTransform( D3DTS_VIEW, &matViewSave ); d3dDevice->GetTransform( D3DTS_PROJECTION, &matProjSave ); // 現在のバック バッファと z バッファを格納する。 LPDIRECT3DSURFACE8 pBackBuffer, pZBuffer; d3dDevice->GetRenderTarget( &pBackBuffer ); d3dDevice->GetDepthStencilSurface( &pZBuffer );
キューブ環境マップの各サーフェスには 90°の視野が含まれることを思い出すこと。アプリケーションで特殊効果などのために視野の角度を変更しない限り、この角度に応じて射影行列を設定するよう注意が必要である。
次のコードは、最も一般的に使用する射影行列を作成および設定する。
// 90°の視野を射影に使用する。 D3DMATRIX matProj; D3DXMatrixPerspectiveFovLH( matProj, D3DX_PI/2, 1.0f, 0.5f, 1000.0f ); d3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); // キューブ マップの 6 つのサーフェスに対してループ処理を実行する。 for( DWORD i=0; i<6; i++ ) { // 以下のように、標準ビューをオーバーライドする。 D3DVECTOR vEnvEyePt = D3DVECTOR( 0.0f, 0.0f, 0.0f ); D3DVECTOR vLookatPt, vUpVec; switch( i ) { case D3DCUBEMAP_FACE_POSITIVE_X: vLookatPt = D3DVECTOR( 1.0f, 0.0f, 0.0f ); vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f ); break; case D3DCUBEMAP_FACE_NEGATIVE_X: vLookatPt = D3DVECTOR(-1.0f, 0.0f, 0.0f ); vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f ); break; case D3DCUBEMAP_FACE_POSITIVE_Y: vLookatPt = D3DVECTOR( 0.0f, 1.0f, 0.0f ); vUpVec = D3DVECTOR( 0.0f, 0.0f,-1.0f ); break; case D3DCUBEMAP_FACE_NEGATIVE_Y: vLookatPt = D3DVECTOR( 0.0f,-1.0f, 0.0f ); vUpVec = D3DVECTOR( 0.0f, 0.0f, 1.0f ); break; case D3DCUBEMAP_FACE_POSITIVE_Z: vLookatPt = D3DVECTOR( 0.0f, 0.0f, 1.0f ); vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f ); break; case D3DCUBEMAP_FACE_NEGATIVE_Z: vLookatPt = D3DVECTOR( 0.0f, 0.0f,-1.0f ); vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f ); break; } D3DMATRIX matView; D3DXMatrixLookAtLH( matView, vEnvEyePt, vLookatPt, vUpVec ); d3dDevice->SetTransform( D3DTS_VIEW, &matView );
カメラを正しく配置し、射影行列を設定すると、シーンをレンダリングできる。シーンの各オブジェクトは、通常配置するとおりに配置する。次のコードでは、処理全体がわかるように、このタスクの概略を示す。
//レンダリングするサーフェスへのポインタを取得する。 LPDIRECT3DSURFACE8 pFace; pCubeMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pFace ); d3dDevice->SetRenderTarget ( pFace , pZBuffer ); pFace->Release(); d3dDevice->BeginScene(); // ここで、シーンをレンダリングする。 d3dDevice->EndScene(); } // レンダリング ターゲットをメイン バック バッファに戻す。 d3dDevice->SetRenderTarget( pBackBuffer, pZBuffer ); pBackBuffer->Release(); pZBuffer->Release(); // 元のトランスフォーム行列をリストアする。 d3dDevice->SetTransform( D3DTS_VIEW, &matViewSave ); d3dDevice->SetTransform( D3DTS_PROJECTION, &matProjSave ); }
IDirect3DDevice8::SetRenderTarget メソッドの呼び出しには注意すること。キューブ マップ サーフェスにレンダリングするときは、そのサーフェスをカレント レンダリング ターゲット サーフェスとして割り当てる必要がある。深度バッファを使用するアプリケーションでは、そのレンダリング ターゲットに明示的に深度バッファを作成したり、既存の深度バッファをレンダリング ターゲット サーフェスに再割り当てすることができる。上のコードでは、後者の方法を使用している。