您可以呼叫 CreateCubeTexture 方法來建立立方環境地圖紋理。 立方環境地圖紋理必須是正方形,且維度為兩個乘冪。
下列程式代碼範例示範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);
存取立方體環境映射面
您可以使用 getCubeMapSurface 方法,在立方體環境地圖的臉部之間巡覽。
下列程式碼範例會使用 GetCubeMapSurface 來擷取用於立方體貼圖面的正向 y 面 (面 2) 的表面。
// Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface
LPDIRECT3DSURFACE9 pFace2;
m_pCubeMap->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &pFace2);
GetCubeMapSurface 接受的第一個參數是描述方法應擷取之附加介面的 D3DCUBEMAP_FACES 列舉值。 第二個參數會告訴 Direct3D 要擷取的 Mipmapped 立方體貼圖層級。 接受的第三個參數是 IDirect3DSurface9 介面的位址,代表傳回的 Cube 紋理表面。 由於這個立方圖沒有使用 mipmap,因此在這裡使用 0。
注意
呼叫此方法之後,IDirect3DSurface9 介面上的內部參考計數就會增加。 當您完成使用這個表面後,務必在此 IDirect3DSurface9 介面上呼叫 IUnknown 方法,否則會有記憶體洩漏。
渲染至立方體環境圖
您可以將影像複製到 Cube 地圖的個別臉部,就像任何其他紋理或表面對象一樣。 轉譯到臉部之前最重要的事情是設定轉換矩陣,讓相機正確定位,並指向該臉部的適當方向:正向(+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);
}
請注意呼叫 SetRenderTarget 方法。 轉譯至 Cube 地圖臉部時,您必須將臉部指派為目前的轉譯目標表面。 使用深度緩衝區的應用程式可以明確建立轉譯目標的深度緩衝區,或將現有的深度緩衝區重新指派給轉譯目標表面。 上述程式代碼範例會使用後者的方法。
相關主題