共用方式為


(Direct3D 9) 建立立方體環境地圖介面

您可以藉由呼叫 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 Cube 紋理層級。 接受的第三個參數是 IDirect3DSurface9 介面的位址,代表傳回的立方體紋理表面。 由於此 Cube-map 不是 mipmapped,因此會在這裡使用 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 地圖臉部時,您必須將臉部指派為目前的轉譯目標表面。 使用深度緩衝區的應用程式可以明確建立轉譯目標的深度緩衝區,或將現有的深度緩衝區重新指派給轉譯目標表面。 上述程式碼範例會使用後者的方法。

立方體環境對應