Bonjour,
ayant eu envie de reprendre mon petit projet de moteur 2D et de l'améliorer, je suis tombé sur une colle lorsque j'ai voulu faire en sorte de locker mon VB une à deux fois par frame plutôt que pour chaque sprite (chaque blitting).
Avant, ça marchait bien en lockant tout le temps même si c'était moins performant je pense mais maintenant ça ne marche plus : seul le dernier quad (deux primitives donc) envoyé dans le VB est réellement affiché.
Mon code source :
L'envoi au GPU est donc fait en fin de boucle.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 HRESULT CGraphics::EndScene() { // On dessine tout // Envoi des vertices dans le VB DWORD dwLockFlags = D3DLOCK_NOOVERWRITE; //queue <int>::size_type nbQuads = Quads.size(); TLVERTEX* pVertices; DWORD dwQuadsCount = 0; if(FAILED( m_VertexBuffer->Lock(0, VBSize * 4 * sizeof(TLVERTEX),(VOID **) &pVertices, D3DLOCK_DISCARD) ) ) { ILogger::m_Errors++; ILogger::Log() << "[ERREUR] Impossible de locker le VB\n"; return E_FAIL; } //m_VertexBuffer->Lock(0, , (VOID**)&pVertices, D3DLOCK_DISCARD); while( !Quads.empty() ) { memcpy( pVertices, Quads.front(), 4 * sizeof(TLVERTEX) ); if( ++dwQuadsCount == VBSize ) { m_VertexBuffer->Unlock(); if(FAILED( m_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, dwQuadsCount*2) ) ) { ILogger::m_Errors++; ILogger::Log() << "[ERREUR] DrawPrimitive Error\n"; return E_FAIL; } if(FAILED( m_VertexBuffer->Lock(0, VBSize * 4 * sizeof(TLVERTEX),(VOID **) &pVertices, D3DLOCK_DISCARD) ) ) { ILogger::m_Errors++; ILogger::Log() << "[ERREUR] Impossible de locker le VB\n"; return E_FAIL; } dwQuadsCount = 0; } delete[] Quads.front(); Quads.pop(); // On supprime le premier élément } m_VertexBuffer->Unlock(); if( dwQuadsCount ) { if(FAILED( m_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, dwQuadsCount*2) ) ) { ILogger::m_Errors++; ILogger::Log() << "[ERREUR] DrawPrimitive Error\n"; return E_FAIL; } } // Fin du rendu m_Device->EndScene(); m_Device->Present(NULL, NULL, NULL, NULL); return S_OK; }
Donc le problème vient du vertex buffer et d'une bêtise que je fait sûrement, mais laquelle ? La doc du SDK ne couvre pas mon problème non plus.
Vous me demanderez sûrement comment j'initialise mon VB :
VBSize = 1000 donc 1000 quads (2000 triangles) mais peu importe.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 void CGraphics::InitDeviceState() { //paramètres définissant les matrices de visualisation D3DXMATRIX m_Ortho2D; D3DXMatrixOrthoLH(&m_Ortho2D, (float)m_Largeur, (float)m_Hauteur, 0.0f, 1.0f); D3DXMatrixIdentity(&m_Identity); m_Device->SetTransform(D3DTS_PROJECTION, &m_Ortho2D); m_Device->SetTransform(D3DTS_WORLD, &m_Identity); m_Device->SetTransform(D3DTS_VIEW, &m_Identity); //Create vertex buffer m_Device->CreateVertexBuffer(4 * sizeof(TLVERTEX) * VBSize, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, D3DFVF_TLVERTEX, D3DPOOL_DEFAULT, &m_VertexBuffer, NULL); m_Device->SetStreamSource(0, m_VertexBuffer, 0, sizeof(TLVERTEX)); //Setup vertex format m_Device->SetVertexShader(NULL); m_Device->SetFVF(D3DFVF_TLVERTEX); // Paramètres daffichage pour l'utilisation de la clé de couleur et de la transparence m_Device->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); // Lance le test Alpha ( permet de tester chaque pixel ) m_Device->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL ); // Permet à l'application d'accepter ou de rejeter un pixel, suivant sa valeur alpha (ici, rejette si non égal à la valeur ci-dessous) m_Device->SetRenderState( D3DRS_ALPHAREF, 0x00000000 ); // Valeur Alpha de référence (octet sur chaque pixel définissant la transparence) m_Device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); // Permet d'autoriser l'alpha blending (couche transparente) m_Device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); m_Device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); m_Device->SetRenderState( D3DRS_ZWRITEENABLE, false ); m_Device->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS ); m_Device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_Device->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_Device->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); // Filtrage bilinéaire pour un effet d'antialiasing lors des distorsions des sprites m_Device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); m_Device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); // Désactivation de la lumière (sinon les sprites seront noirs) m_Device->SetRenderState( D3DRS_LIGHTING, FALSE ); }
Voilà, voilà, si quelqu'un pouvait m'aider...








Répondre avec citation
Partager