LockVertexBuffer--> multiple calls...

Started by
5 comments, last by edwinnie 20 years, 10 months ago
ok! i am trying to optimise by dumping all the vertices (which all are from separate objects), into ONE big vertex buffer. anyone has such a thing, can shrae how to lock the vertex buffer using the offset and sizeToLock parameters? this is what i have so far(simplified):

//--------------------------------------------

//"vbuffer" is the created empty vertex buffer

//--------------------------------------------

for(int j=0; j<number of surfaces; j++)
{
    if(surfaces[j]->verts != NULL)
    {
        BYTE* pool = NULL;
        int previousSize = sizeof(vbuffer);  //??needed

	
        //-------------

	//how to lock??

        //-------------	

	vbuffer->Lock(previousSize, previousSize, (void**)&pool, 0);
	memcpy(pool, 
	       surfaces[j]->verts, 
               surfaces[j]->vertex_count * vertex_size);
	vbuffer->Unlock();
    }
}
much help needed!! thx! edwinz
Advertisement
I was having the same problem. I eventually got sick of fuddling around with it so I copied them to one giant array first and copied that to the vertex buffer.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
Your lock is very odd. Why are you using the sizeof(vbuffer)?

size is the size in bytes.
offset is the offset from the beginning of the buffer in bytes.
Your code should be like this.

DWORD offset = 0;BYTE *dataptr;for(int j=0; j<number of surfaces; j++){  if(surfaces[j]->verts != NULL)  {    size = vertex_size * surfaces[j]->vertex_count;    vbuffer->Lock(offset, size, &dataptr, 0);    memcpy(dataptr, surfaces[j]->verts, size);    vbuffer->Unlock();    offset += size;  }}


or, even better, locking just once.

DWORD offset = 0;BYTE *dataptr;vbuffer->Lock(0, 0, &dataptr, 0);for(int j=0; j<number of surfaces; j++){  if(surfaces[j]->verts != NULL)  {    size = vertex_size * surfaces[j]->vertex_count;    memcpy(&dataptr[offset], surfaces[j]->verts, size);    offset += size;  }}vbuffer->Unlock();


You''ll probably want to save the offset in your surface structure so that you can render it later.
well basicly the two function definition you'll need are this:
IDirect3DDevice8::CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer )
IDirect3DVertexBuffer8::Lock( UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags )

so it should look basicly like this

LPDIRECT3DDEVICE8 g_pd3dDevice;LPDIRECT3DVERTEXBUFFER8 g_pVB;CObject Objects[];void CreateBuffer(){    g_pd3dDevice->CreateVertexBuffer( sizeof(myVertex)*nbVertices, D3DUSAGE_WRITEONLY, MY_VERTEX, D3DPOOL_DEFAULT, &g_pVB );    BYTE* pool = null;    DWORD offset = 0;    DWORD size = 0;    g_pVB->Lock( 0, sizeof(myVertex)*nbVertices, &pool, NULL );    for( int i=0; i<nbObjects; i++ )    {        size = Object[i].nbVerts * sizeof(myVertex);        memcpy( &pool[offset], Object[i].Verts, Object[i].nbVerts * sizeof(myVertex) );        offet += size;    }    g_pVB->Unlock();}


myVertex is a struct containing the different information for each of your vertex
MY_VERTEX are the D3D_FVF flags for your vertex type

so it is not really necessary to keep track of the offset that way. altho you need to know how many vertices there are in all your objects to lock enough memory space.

EDIT: doh... yea AP got it right... you need the offset for when you do your memcpy... forgot about that

Yann L POWNS Carmack

[edited by - sross on June 17, 2003 1:45:36 PM]

[edited by - sross on June 17, 2003 1:47:02 PM]
Stéphane RossGame Gurus Entertainment
thx alot fer the replies!

but one thing i noticed
wats the difference by locking at offset 0 with a specified size and with one that has size-zero?

eg
//----------------------------------------------------//this one locks with notification of the total vertex //buffer size, and is outside the for loop//----------------------------------------------------g_pVB->Lock( 0, sizeof(myVertex)*nbVertices, &pool, NULL );


thx again!
edwinz
updates:
//-----------------//working variables//-----------------int size     = sizeof(CVertex);BYTE* pool   = NULL;DWORD offset = 0;vbuffer->Lock(0, 0, (void**)&pool, 0);//---------------------//for each mesh surface//---------------------for(int j=0; j<cmesh->SurfaceCount; j++){   if(cmesh->Surfaces[j]->Vertices != NULL)   {			DWORD sizeToCopy = cmesh->Surfaces[j]->VertexCount * size; 	memcpy(&pool[offset], cmesh->Surfaces[j]->Vertices, sizeToCopy);	offset += sizeToCopy;	node->surfacesVec[j].offset = offset;   }}vbuffer->Unlock();
The SDK says that locking with offset 0, size 0, will lock the entire buffer.

In your update, you probably want to record the offset BEFORE adding the size to the offset. The offset would be used in your drawprimitive call as the "first vertex" parameter.

This topic is closed to new replies.

Advertisement