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 :

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 d’affichage 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 );
}
VBSize = 1000 donc 1000 quads (2000 triangles) mais peu importe.

Voilà, voilà, si quelqu'un pouvait m'aider...