Création de surfaces de carte d’environnement cubique (Direct3D 9)
Vous créez une texture de mappage d’environnement cubique en appelant la méthode CreateCubeTexture . Les textures de carte d’environnement cubique doivent être carrées, avec des dimensions qui sont une puissance de deux.
L’exemple de code suivant montre comment votre application C++ peut créer une carte d’environnement cubique simple.
// 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);
Accès à des visages de carte d’environnement cubique
Vous pouvez naviguer entre les visages d’une carte d’environnement cubique à l’aide de la méthode GetCubeMapSurface .
L’exemple de code suivant utilise GetCubeMapSurface pour récupérer la surface de carte de cube utilisée pour la face y positive (face 2).
// Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface
LPDIRECT3DSURFACE9 pFace2;
m_pCubeMap->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &pFace2);
Le premier paramètre accepté par GetCubeMapSurface est une D3DCUBEMAP_FACES valeur énumérée qui décrit la surface attachée que la méthode doit récupérer. Le deuxième paramètre indique à Direct3D le niveau d’une texture de cube mipmapped à récupérer. Le troisième paramètre accepté est l’adresse de l’interface IDirect3DSurface9 , représentant la surface de texture de cube retournée. Étant donné que cette carte de cube n’est pas mipmapped, 0 est utilisé ici.
Notes
Après l’appel de cette méthode, le nombre de références internes sur l’interface IDirect3DSurface9 est augmenté. Lorsque vous avez terminé d’utiliser cette surface, veillez à appeler la méthode IUnknown sur cette interface IDirect3DSurface9 , sinon vous aurez une fuite de mémoire.
Rendu en mappages d’environnement cubique
Vous pouvez copier des images sur les visages individuels de la carte de cube comme vous le feriez pour n’importe quel autre objet de texture ou de surface. La chose la plus importante à faire avant le rendu sur un visage est de définir les matrices de transformation afin que la caméra soit correctement positionnée et pointe dans la direction appropriée pour ce visage : avant (+z), arrière (-z), gauche (-x), droite (+x), haut (+y) ou bas (-y).
L’exemple de code C++ suivant prépare et définit une matrice d’affichage en fonction du visage affiché.
// 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);
N’oubliez pas que chaque face d’une carte d’environnement cubique représente un champ de vue à 90 degrés. À moins que votre application ne nécessite un autre champ d’angle de vue (par exemple pour les effets spéciaux), veillez à définir la matrice de projection en conséquence.
Cet exemple de code crée et définit une matrice de projection pour le cas le plus courant.
// 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);
Lorsque la caméra est en position et que la matrice de projection est définie, vous pouvez restituer la scène. Chaque objet de la scène doit être positionné comme vous le feriez normalement. L’exemple de code suivant, fourni pour l’exhaustivité, décrit cette tâche.
// 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);
}
Notez l’appel à la méthode SetRenderTarget . Lors du rendu sur les visages de mappage de cube, vous devez affecter le visage comme surface cible de rendu actuelle. Les applications qui utilisent des tampons de profondeur peuvent créer explicitement une mémoire tampon de profondeur pour la cible de rendu ou réaffecter une mémoire tampon de profondeur existante à la surface cible de rendu. L’exemple de code ci-dessus utilise cette dernière approche.
Rubriques connexes