次の方法で共有


キューブ環境サーフェスの作成 (Direct3D 9)

キューブ環境マップ テクスチャーを作成するには、IDirect3DDevice9::CreateCubeTexture メソッドを呼び出します。キューブ環境マップ テクスチャーは矩形でなければならず、その大きさは 2 の累乗です。

次のコード例は、C++ アプリケーションで単純なキューブ環境マップを作成する方法を示しています。

 // Init m_d3dDevice to point to an IDirect3DDevice9 interface  LPDIRECT3DCUBETEXTURE9 m_pCubeMap;  m_d3dDevice->CreateCubeTexture(256, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R8G8B8,                                 D3DPOOL_DEFAULT, &m_pCubeMap); 

キューブ環境マップ面へのアクセス

IDirect3DCubeTexture9::GetCubeMapSurface メソッドを使ってキューブ環境マップの面から面に移動できます。

次のコード例は、IDirect3DCubeTexture9::GetCubeMapSurface を使って、正方向の y 面 (面 2) に使用するキューブ マップ サーフェスを取得します。

 // Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface  LPDIRECT3DSURFACE9 pFace2; m_pCubeMap->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &pFace2); 

IDirect3DCubeTexture9::GetCubeMapSurface が受け取る第 1 パラメーターは、このメソッドで取得する必要があるアタッチされたサーフェスを記述する D3DCUBEMAP_FACES 列挙値です。第 2 パラメーターは、取得するミップマップ化キューブ テクスチャーのレベルを Direct3D に指示します。第 3 パラメーターは、返されるキューブ テクスチャー サーフェスを表す IDirect3DSurface9 インターフェイスのアドレスです。この場合、このキューブ マップはミップマップ化されていないので、0 が使われます。

    

このメソッドを呼び出した後は、IDirect3DSurface9 インターフェイスの内部リファレンス カウントが増えます。このサーフェスの使用後は、必ずこの IDirect3DSurface9 インターフェイスに対して IUnknown メソッドを呼び出す必要があります。呼び出さないと、メモリー リークが発生します。

キューブ環境マップへのレンダリング

キューブ マップの各面へは、その他のテクスチャーやサーフェス オブジェクトと同じように画像をコピーすることができます。この面へのレンダリングを行う前に実行する最も大切なことは、カメラを正しく配置し、その面に対して正しい方向を向くようにトランスフォーム行列を設定することです。正しい方向とは、前方 (+z)、後方 (-z)、左 (-x)、右 (+x)、上方 (+y)、または下方 (-y) です。

次の C++ コード例は、レンダリングする面に応じてビュー行列を用意して設定します。

 // Init pCubeMap to point to an IDirect3DCubeTexture9 interface // Init d3dDevice to point to an IDirect3DDevice9 interface  void RenderFaces() {     // Save transformation matrices of the device     D3DXMATRIX matProjSave, matViewSave;     d3dDevice->GetTransform(D3DTS_VIEW,       &matViewSave ;     d3dDevice->GetTransform(D3DTS_PROJECTION, &matProjSave);      // Store the current back buffer and z-buffer     LPDIRECT3DSURFACE9 pBackBuffer, pZBuffer;     d3dDevice->GetRenderTarget(&pBackBuffer);     d3dDevice->GetDepthStencilSurface(&pZBuffer); 

キューブ環境マップの各面は 90°の視野を表すことを思い出してください。アプリケーションで特殊効果などのために視野の角度を変更しない限り、この角度に応じて射影行列を設定するよう注意が必要です。

次のコード例は、最も一般的に使う射影行列を作成および設定します。

     // Use 90-degree field of view in the projection     D3DMATRIX matProj;     D3DXMatrixPerspectiveFovLH(matProj, D3DX_PI/2, 1.0f, 0.5f, 1000.0f);     d3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);      // Loop through the six faces of the cube map     for(DWORD i=0; i<6; i++)     {         // Standard view that will be overridden below         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); 

カメラを正しく配置し、射影行列を設定すると、シーンをレンダリングできます。シーンの各オブジェクトは、通常どおりに配置します。次のコード例では、処理全体がわかるように、このタスクの概略を示します。

         // Get pointer to surface in order to render to it         LPDIRECT3DSURFACE9 pFace;         pCubeMap->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0, &pFace);         d3dDevice->SetRenderTarget (pFace , pZBuffer);         SAFE_RELEASE(pFace);          d3dDevice->BeginScene();         // Render scene here      ...         d3dDevice->EndScene();     }      // Change the render target back to the main back buffer.     d3dDevice->SetRenderTarget(pBackBuffer, pZBuffer);     SAFE_RELEASE(pBackBuffer);     SAFE_RELEASE(pZBuffer);      // Restore the original transformation matrices     d3dDevice->SetTransform(D3DTS_VIEW,       &matViewSave);     d3dDevice->SetTransform(D3DTS_PROJECTION, &matProjSave); } 

IDirect3DDevice9::SetRenderTarget メソッドの呼び出しに注意してください。キューブ マップ面にレンダリングするときは、その面をカレント レンダー ターゲット サーフェスとして割り当てる必要があります。深度バッファーを使うアプリケーションでは、そのレンダー ターゲットに明示的に深度バッファーを作成したり、既存の深度バッファーをレンダー ターゲット サーフェスに再割り当てたりすることができます。上のコード例では、後者の方法を使っています。