Delen via


Kubieke omgevingskaart oppervlakken maken (Direct3D 9)

U maakt een kubieke omgevingskaartpatroon door de methode CreateCubeTexture aan te roepen. De structuur van de kubieke omgevingskaart moet vierkant zijn, met dimensies die een kracht van twee zijn.

In het volgende codevoorbeeld ziet u hoe uw C++-toepassing een eenvoudige kubieke omgevingstoewijzing kan maken.

// 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);

Toegang tot kubieke omgevingskaartvlakken

U kunt navigeren tussen gezichten van een kubieke omgevingskaart met behulp van de methode GetCubeMapSurface.

In het volgende codevoorbeeld wordt GetCubeMapSurface gebruikt om het cubemap-oppervlak op te halen dat wordt gebruikt voor het positieve y-gezicht (gezicht 2).

// Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface

LPDIRECT3DSURFACE9 pFace2;
m_pCubeMap->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &pFace2);

De eerste parameter die GetCubeMapSurface accepteert, is een D3DCUBEMAP_FACES opgesomde waarde die het bijgevoegde oppervlak beschrijft dat door de methode moet worden opgehaald. De tweede parameter vertelt Direct3D welk niveau van een mipmapped kubuspatroon moet worden opgehaald. De derde geaccepteerde parameter is het adres van de IDirect3DSurface9 interface, die het geretourneerde kubuspatroonoppervlak vertegenwoordigt. Omdat deze kubuskaart niet is gemipmapped, wordt hier 0 gebruikt.

Notitie

Nadat u deze methode hebt aangeroepen, wordt het aantal interne verwijzingen op de IDirect3DSurface9 interface verhoogd. Wanneer u klaar bent met dit oppervlak, moet u de methode IUnknown op deze IDirect3DSurface9 interface aanroepen, anders hebt u een geheugenlek.

 

Rendering naar kubusvormige omgevingskaarten

U kunt afbeeldingen kopiëren naar de afzonderlijke gezichten van de kubuskaart, net zoals elk ander patroon of oppervlakobject. Het belangrijkste wat u moet doen voordat een gezicht wordt weergegeven, is de transformatiematrices zo instellen dat de camera correct wordt geplaatst en wijst in de juiste richting voor dat gezicht: vooruit (+z), achteruit (-z), links (-x), rechts (+x), omhoog (+y) of omlaag (-y).

In het volgende C++-codevoorbeeld wordt een weergavematrix voorbereid en ingesteld op basis van het gezicht dat wordt weergegeven.

// 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);

Onthoud dat elk gezicht van een kubieke omgevingskaart een weergaveveld van 90 graden vertegenwoordigt. Tenzij voor uw toepassing een ander weergaveveld is vereist, bijvoorbeeld voor speciale effecten, moet u ervoor zorgen dat de projectiematrix dienovereenkomstig wordt ingesteld.

In dit codevoorbeeld wordt een projectiematrix gemaakt en ingesteld voor de meest voorkomende case.

    // 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);

Wanneer de camera op positie is en de projectiematrixset, kunt u de scène weergeven. Elk object in de scène moet worden geplaatst zoals u ze normaal zou plaatsen. In het volgende codevoorbeeld, dat is opgegeven voor volledigheid, wordt deze taak beschreven.

        // 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);
}

Noteer de aanroep van de methode SetRenderTarget. Wanneer u naar de vlakjes van de kubuskaart rendert, moet u het vlakje als het huidige renderdoeloppervlak toewijzen. Toepassingen die dieptebuffers gebruiken, kunnen expliciet een dieptebuffer maken voor het render-doel of een bestaande dieptebuffer opnieuw toewijzen aan het render-doeloppervlak. In het bovenstaande codevoorbeeld wordt de laatste benadering gebruikt.

kubieke omgevingstoewijzing