共用方式為


建立立方環境地圖表面 (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 立方體貼圖層級。 接受的第三個參數是 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 地圖臉部時,您必須將臉部指派為目前的轉譯目標表面。 使用深度緩衝區的應用程式可以明確建立轉譯目標的深度緩衝區,或將現有的深度緩衝區重新指派給轉譯目標表面。 上述程式代碼範例會使用後者的方法。

立方環境對應