Ici on va créer les feux produits par les turbines des modules. Pour cela on
placera dans le monde une image sur un plan auquel on lui associe une couleur
clé. On prendra le noir, ce qui signifie que tous les pixels de couleur noir ne
seront pas affichés. En clair, plus la couleur est foncée, et plus il y aura
d'effet de transparence.
On commence par charger la texture du fichier dans le pointeur de type
LPDIRECT3DTEXTURE9.
Ensuite on crée le vertexbuffer qui recevra les 4 vertices du plan. en
précisant qu'il s'agit d'un FVF (flexible vertex format). Notre image ne sera
pas dépendante de la lumière projetée dans le monde et diffusera sa propre
lumière, d'où le D3DFVF_DIFFUSE. Le drapeau D3DFVF_TEX1
permet d'indiquer qu'on utilisera le système de texture U, V. Ce qui permet de
recadrer la texture sur le plan en utilisant les coefficiants allant de 0 à 1.
Ensuite pour créer les vertices il nous faut verrouiller DirectVertexBuffer.
vertices.cpp
#include "vertices.h"
#include "decl_vertices.h"
HRESULT init_vertices(LPDIRECT3DDEVICE9 *_obj_Direct3DDevice, LPDIRECT3DVERTEXBUFFER9 *_obj_DirectVB, LPDIRECT3DTEXTURE9 *pTexture,
const char *nom, float lng, float larg) {
HRESULT hr;
if( FAILED( D3DXCreateTextureFromFile(*_obj_Direct3DDevice, nom, pTexture ) ) )
return E_FAIL;
hr = (*_obj_Direct3DDevice)->CreateVertexBuffer( 4 * sizeof(VERTICES), 0, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, D3DPOOL_DEFAULT, _obj_DirectVB, NULL);
if (FAILED(hr)) return E_FAIL;
VERTICES* pVertices;
hr = (*_obj_DirectVB)->Lock( 0, 0, (void**)&pVertices, 0);
if(FAILED(hr)) return E_FAIL;
pVertices[0].v = D3DXVECTOR3( -larg/2, -lng/2, 0);
pVertices[0].couleur = 0xffffffff;
pVertices[0].tu = 0;
pVertices[0].tv = 0;
pVertices[1].v = D3DXVECTOR3( -larg/2, lng/2, 0);
pVertices[1].couleur = 0xffffffff;
pVertices[1].tu = 0;
pVertices[1].tv = 1;
pVertices[2].v = D3DXVECTOR3( larg/2, -lng/2, 0);
pVertices[2].couleur = 0xffffffff;
pVertices[2].tu = 1;
pVertices[2].tv = 0;
pVertices[3].v = D3DXVECTOR3( larg/2, lng/2, 0);
pVertices[3].couleur = 0xffffffff;
pVertices[3].tu = 1;
pVertices[3].tv = 1;
(*_obj_DirectVB)->Unlock();
return S_OK;
}
vertices.h
#include <d3dx9tex.h>
#include <d3d9.h>
// pointeur sur direct3Dvertexbuffer
static LPDIRECT3DVERTEXBUFFER9 obj_DirectVB, obj_DirectVB2;
// pointeur sur texture
static LPDIRECT3DTEXTURE9 obj_texture, obj_texture2;
struct VERTICES
{
D3DXVECTOR3 v;
D3DCOLOR couleur;
FLOAT tu, tv;
};
decl_vertices.h
HRESULT init_vertices(LPDIRECT3DDEVICE9*, LPDIRECT3DVERTEXBUFFER9*, LPDIRECT3DTEXTURE9*, float, float);
La fonction rendu doit prendre en compte deux nouveaux paramètres :
VOID Rendu(HWND hWnd, unsigned int param, LPDIRECT3DDEVICE9 *D3DD,
LPDIRECT3DTEXTURE9 *pText, LPDIRECT3DVERTEXBUFFER9
*pVB, _module_ *rp, _module_ *rp2, _mesh_ *mtm_modulea, _mesh_ *mtm_laby, _mesh_ *mtm_missile, _mesh_ *mtm_moduleb, _mesh_ *mtm_coeur, clavier *etm)
{
On commence par retirer la lumière de la scène,
puisque le plan n'aura pas d'interaction avec.
Ensuite on crée l'effet Alpha de transparence.
D3DRS_ALPHABLENDENABLE : permet d'effectuer un test sur les pixels pour
effectuer l'effet alpha.
D3DRS_SRCBLEND, D3DRS_DESTBLEND : permet d'indiquer qu'il faut mélanger les
pixels alpha du plan aux autres pixels.
On associe ensuite le buffer vertex à Direct Device, puis on indique à
DirectDevice le type de vertices comme FVF et on associe la texture.
rp2->monde._41=vx*cos(rp->module_rot)+vz*sin(rp->module_rot);
rp2->monde._43=-vx*sin(rp->module_rot)+vz*cos(rp->module_rot);
rotation_Y(&rp2->monde, rp->module_rot - cell2->t_rot);
projection(&rp2->monde, &(*D3DD));
obj2device_dessin_mesh(mtm_missile->nbr_de_mat, mtm_missile, &(*D3DD), &mtm_missile->obj_mesh);
cell2 = cell2->suivant;
}
(*D3DD)->SetRenderState( D3DRS_LIGHTING, FALSE );
(*D3DD)->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
(*D3DD)->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
(*D3DD)->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
(*D3DD)->SetStreamSource( 0, *pVB, 0, sizeof(VERTICES) );
(*D3DD)->SetFVF( D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1 );
(*D3DD)->SetTexture( 0, *pText);
Lorsque le module tourne il faut que le feu
arrière puisse suivre, on le place donc sur le cercle de centre (0, 0, 0) sans
effectuer de rotation sur lui même puisqu'il faut que le plan soit toujours
face à la caméra pour un meilleur effet. On fait revenir le hallo vers la
caméra lorsque le module tourne pour éviter que le plan ne s'interpose avec
celui-ci. Suivant qu'on tourne à gauche ou à droite l'ordre d'affichage des
deux hallos gauche et droit est à prendre en compte.
if(rp->rot_cam>0) {
rp->monde._41 = _A_ * cos(_fi_+rp->rot_cam/4);
rp->monde._43 = _A_ * sin(_fi_+rp->rot_cam/4) - rp->rot_cam/2;
rp->monde._13 = rp->monde._31 = 0.0f;
rp->monde._11 = rp->monde._22 = rp->monde._33 = rp->coef_vitesse_module * .1f;
projection(&rp->monde, &(*D3DD));
(*D3DD)->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
rp->monde._41 = -_A_ * cos(_fi_-rp->rot_cam/4);
rp->monde._43 = _A_ * sin(_fi_-rp->rot_cam/4) - rp->rot_cam/1.5;
rp->monde._13 = rp->monde._31 = 0.0f;
rp->monde._11 = rp->monde._22 = rp->monde._33 = rp->coef_vitesse_module * .1f;
projection(&rp->monde, &(*D3DD));
(*D3DD)->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
}
else {
rp->monde._41 = -_A_ * cos(_fi_-rp->rot_cam/4);
rp->monde._43 = _A_ * sin(_fi_-rp->rot_cam/4) + rp->rot_cam/2;
rp->monde._13 = rp->monde._31 = 0.0f;
rp->monde._11 = rp->monde._22 = rp->monde._33 = rp->coef_vitesse_module * .1f;
projection(&rp->monde, &(*D3DD));
(*D3DD)->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
rp->monde._41 = _A_ * cos(_fi_+rp->rot_cam/4);
rp->monde._43 = _A_ * sin(_fi_+rp->rot_cam/4) + rp->rot_cam/1.5;
rp->monde._13 = rp->monde._31 = 0.0f;
rp->monde._11 = rp->monde._22 = rp->monde._33 = rp->coef_vitesse_module * .1f;
projection(&rp->monde, &(*D3DD));
(*D3DD)->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
}
rp->monde._11 = rp->monde._22 = rp->monde._33 = 1.0f;
(*D3DD)->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
(*D3DD)->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
(*D3DD)->SetRenderState( D3DRS_LIGHTING, TRUE );
// fin de la scène
(*D3DD)->EndScene();
// affiche le back buffer à l'écran
(*D3DD)->Present(NULL, NULL, NULL, NULL);
Dans la fonction main on aura :
for(i = 0; i < NBR_SNDS; i++)
if(LoadDirectSound(&obj_DirectSound, &(DSbuffer[i]), chemin_wav[i]) != S_OK)
return -1;
init_vertices(&obj_Direct3DDevice, &obj_DirectVB, &obj_texture, "glow.bmp", 20, 20);
init_vertices(&obj_Direct3DDevice2, &obj_DirectVB2, &obj_texture2, "glow.bmp", 20, 20);
...
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else {
Rendu(hCtrl_2, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, &obj_Direct3DDevice,
&obj_texture, &obj_DirectVB, module1, module2, mtm[0], mtm[4], mtm[6], mtm[2], mtm[8], &et_module);
Rendu(hCtrl_1, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, &obj_Direct3DDevice2,
&obj_texture2, &obj_DirectVB2, module2, module1, mtm[3], mtm[5], mtm[7], mtm[1], mtm[9], &et_module2);
}
}
Téléchargez la source, cliquez ci-dessous :