Condividi tramite


Creazione di superfici della mappa dell'ambiente cubico (Direct3D 9)

Per creare una trama della mappa di ambiente cubica, chiamare il metodo CreateCubeTexture . Le trame della mappa dell'ambiente cubico devono essere quadrate, con dimensioni che rappresentano una potenza di due.

L'esempio di codice seguente illustra come l'applicazione C++ potrebbe creare una semplice mappa di ambiente cubica.

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

Accesso ai visi della mappa dell'ambiente cubico

È possibile spostarsi tra i visi di una mappa di ambiente cubica usando il metodo GetCubeMapSurface .

L'esempio di codice seguente usa GetCubeMapSurface per recuperare la superficie della mappa del cubo usata per il viso y positivo (viso 2).

// Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface

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

Il primo parametro accettato da GetCubeMapSurface è un valore D3DCUBEMAP_FACES enumerato che descrive la superficie associata che il metodo deve recuperare. Il secondo parametro indica a Direct3D quale livello di una trama del cubo mipmapped recuperare. Il terzo parametro accettato è l'indirizzo dell'interfaccia IDirect3DSurface9 , che rappresenta la superficie di trama del cubo restituita. Poiché questa mappa del cubo non è errata, viene usato 0 qui.

Nota

Dopo aver chiamato questo metodo, viene aumentato il conteggio dei riferimenti interni nell'interfaccia IDirect3DSurface9 . Al termine dell'uso di questa superficie, assicurarsi di chiamare il metodo IUnknown su questa interfaccia IDirect3DSurface9 o si avrà una perdita di memoria.

 

Rendering in mappe dell'ambiente cubico

È possibile copiare immagini nei singoli visi della mappa del cubo esattamente come qualsiasi altro oggetto trama o superficie. La cosa più importante da eseguire prima del rendering in un viso è impostare le matrici di trasformazione in modo che la fotocamera sia posizionata correttamente e punti nella direzione appropriata per il viso: avanti (+z), indietro (-z), sinistra (-x), destra (+x), su (+y) o giù (-y).

Nell'esempio di codice C++ seguente viene preparata e impostata una matrice di visualizzazione in base al rendering del viso.

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

Tenere presente che ogni faccia di una mappa di ambiente cubica rappresenta un campo di visualizzazione a 90 gradi. A meno che l'applicazione non richieda un campo diverso di angolo di visualizzazione, ad esempio per effetti speciali, prestare attenzione a impostare la matrice di proiezione di conseguenza.

Questo esempio di codice crea e imposta una matrice di proiezione per il caso più comune.

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

Quando la fotocamera è posizionata e la matrice di proiezione impostata, è possibile eseguire il rendering della scena. Ogni oggetto nella scena deve essere posizionato come si farebbe normalmente. Nell'esempio di codice seguente, fornito per completezza, viene delineata questa attività.

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

Prendere nota della chiamata al metodo SetRenderTarget . Quando si esegue il rendering dei visi della mappa del cubo, è necessario assegnare il viso come superficie di destinazione di rendering corrente. Le applicazioni che usano buffer di profondità possono creare in modo esplicito un buffer di profondità per la destinazione di rendering o riassegnare un buffer di profondità esistente alla superficie di destinazione di rendering. L'esempio di codice precedente usa quest'ultimo approccio.

Mapping dell'ambiente cubico