Original Post
I'm been working on a particle system, using indexed primitives to draw each particle as a quad. I fill the buffer as a tri list, so it uses 4 vertices and 6 indices to create a quad. It works great when I fill the entire buffer with 1 lock, then pass it to DIP. However, I'm trying to fill chunks and feeding them to DIP, to make it run faster, and so I can wrap around the buffer later on (to support larger particlesystems while keeping the buffer reasonably small). I've tried using the discard/nooverwrite method to fill a chunk of the buffer then pass it to DIP. It doesn't work, I get weird artifacts all over the screen, whatever values I pass to DIP. Since the indices are fine when the buffer is filled and DIP'd in 1 go, it seems the DIP offsets or locks are somehow faulty. Here's the important part(s) of the Render() function:
[edited by - Dynaguy on September 29, 2002 8:19:25 AM]
pd3dDevice->SetVertexShader(D3DFVF_DEFAULTVERTEX);
pd3dDevice->SetStreamSource(0, pd3dVB, sizeof(DefaultVertex));
pd3dDevice->SetIndices(pd3dIB, 0);
dwBaseVertex = 0; // start at offset 0 in vb
// if I set flush to be 4 * aliveparticles, it fills the entire
// buffer in 1 go and works...
dwFlushVB = 4 * 32; // draw buffer after this many vertices
dwNumVertices = 0;
// currently the buffer and particles are allocated on creation, so we know
the max number of vertices
dwMaxVertices = 4 * dwMaxParticleCount;
dwBaseIndex = (dwBaseVertex * 6) / 4;
dwFlushIB = (dwFlushVB * 6) / 4;
dwNumIndices = (dwNumVertices * 6) / 4;
dwMaxIndices = (dwMaxVertices * 6) / 4;
pd3dVB->Lock(dwBaseVertex * sizeof(D3DFVF_DEFAULTVERTEX), dwFlushVB * sizeof(D3DFVF_DEFAULTVERTEX), (BYTE **)&vb, D3DLOCK_DISCARD);
pd3dIB->Lock(dwBaseIndex * sizeof(WORD), dwFlushIB * sizeof(WORD), (BYTE **)&ib, D3DLOCK_DISCARD);
for each particle
{
if alive
{
fill vb[dwNumVertices...dwNumVertices+3]
ib[dwNumIndices++] = (WORD)(dwBaseVertex+dwNumVertices);
ib[dwNumIndices++] = (WORD)(dwBaseVertex+dwNumVertices+1);
ib[dwNumIndices++] = (WORD)(dwBaseVertex+dwNumVertices+2);
ib[dwNumIndices++] = (WORD)(dwBaseVertex+dwNumVertices);
ib[dwNumIndices++] = (WORD)(dwBaseVertex+dwNumVertices+2);
ib[dwNumIndices++] = (WORD)(dwBaseVertex+dwNumVertices+3);
dwNumVertices += 4;
if (dwNumVertices >= dwFlushVB)
{
pd3dVB->Unlock();
pd3dIB->Unlock();
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
dwBaseVertex, dwNumVertices,
dwBaseIndex, dwNumVertices / 2);
dwBaseVertex += dwNumVertices;
dwBaseIndex += dwNumIndices;
dwNumVertices = 0;
dwNumIndices = 0;
if (dwBaseVertex + dwFlushVB > dwMaxVertices) dwFlushVB =
dwMaxVertices - dwBaseVertex;
if (dwBaseIndex + dwFlushIB > dwMaxIndices) dwFlushIB =
dwMaxIndices - dwBaseIndex;
pd3dVB->Lock(dwBaseVertex * sizeof(D3DFVF_DEFAULTVERTEX),
dwFlushVB * sizeof(D3DFVF_DEFAULTVERTEX),
(BYTE **)&vb, D3DLOCK_NOOVERWRITE);
pd3dIB->Lock(dwBaseIndex * sizeof(WORD),
dwFlushIB * sizeof(WORD),
(BYTE **)&ib, D3DLOCK_NOOVERWRITE);
}
}
}
}
pd3dVB->Unlock();
pd3dIB->Unlock();
// remaining particles
// this is the only part that is called when I fill the entire buffer in 1
go, and works...
if (dwNumVertices > 0)
{
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
dwBaseVertex, dwNumVertices,
dwBaseIndex, dwNumVertices / 2);
}