Using dynamic vertexbuffers

Started by
12 comments, last by Keba 19 years, 6 months ago
Hi, I wounder if i'm using dynamic vertexbuffers correct, take a look at this: the buffer is created with the Dynamic and writeonly flagg each step(1-10) is a call to "the global render function" in my program. each locking is checking if there is enough room for my 600 vertices. Each time i'm Locking with NOOVERWRITE, except on the first lock and when there is no room, then i'm locking with DISCARD. After Locking the buffer i fill it with 600 vertices and then unlock it and render it. At each render i'm setting the stream source, is that bad? When i render i just render the vertices i just added, and when i'm setting the streamsource, i'm setting the offset parameter to the first vertices in this call(in bytes). is this the right way to do it? / thanks
Advertisement
Sounds good. Are you specifying the OffsetToLock and SizeToLock accurately as well? I'm not sure what the driver does if you say NOOVERWRITE, yet pass in a vertex range that *could* overwrite previous data.

I don't think SetStreamSource is going to mind being called over and over again, yet it will likely be a tiny bit slower.

I tend to use the offsets in DrawIndexedPrimtive, rather than the ones in SetStreamSource. The byteoffset in SetStreamSource is new to DX9, and I'm not sure how well older cards will deal with it.
How did you choose the number of step (then 600) ? Are you sure this is the best *paralelism* number ?
600 its just a test number as the 6000 vertices in the whole buffer, just wanted to know if i did right.

btw, is there a "golden" vertices number?

Namethatnobodyelsetook: OffsetToLock and SizeToLock?, do you mean the flags in IDirect3DVertexbuffer9::Lock()?
The arguments in the vertex buffer lock, yes. In the C++ help that's the names they're given. I know C# changes how a few functions work, and probably gives different names to things. For instance SetStreamSource() in C# has atleast two different ways to use it with different sets of arguments... In C++ we don't have that.

So, ignoring the specific details, are you locking only the part of the VB you're going to update, or are you locking the whole thing?
For some more excellent info on dynamic vertex buffers, check out this thread. It's filled with some really useful and effective optimizations.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
circlesoft :
thanks

Namethatnobodyelsetook:
i'm only locking the part that i'm gooing to use, nothing wron in that i guess

I was woundering, on the first lock, the absolutly first after creating my Vertexbuffer, should i use DISCARD, or is it safe to use NOOVERWRITE?

It may be safe to use NOOVERWRITE, however you could just as easily do something like this when creating your VB.

nMaxSize = nVerts;
nWriteTo = nVerts;

On your first use, you'll see you don't have space for even 1 vertex, and discard as you usually do.

Please tell me what i'm doing wrong here, i just can't get the Dynamic Buffer to work, i'm doing as the picture in the begining of this thread shows, heres the code

// Creating:	HRESULT hr = m_pD3DDevice->CreateVertexBuffer(sizeof(TestFVF)*nMaxVertices,D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,D3DPOOL_DEFAULT,&m_pBuffer,NULL);	if(hr != S_OK)		return hr;	D3DCAPS9 *pCaps = new D3DCAPS9;	hr = m_pD3DDevice->GetDeviceCaps(pCaps);	if(hr != S_OK)		return hr;	// Checking if device supports Streamoffset, is this wrong?	if((pCaps->DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) != D3DDEVCAPS2_STREAMOFFSET)	{			}// Rendering:// Checking if there is enough space// nCurrentVertices is the max position for this "batch"TestFVF *Pointer = NULL;HRESULT hr = 0;	if(nCurrentVertices+nVerticesToAdd < nMaxVertices)	{		StartVertices = nCurrentVertices;		Offset = StartVertices*sizeof(TestFVF);		hr = m_pBuffer->Lock(Offset,nVerticesToAdd*sizeof(TestFVF),(VOID**)&Pointer,D3DLOCK_NOOVERWRITE);		nCurrentVertices += nVerticesToAdd;	}	else	{		StartVertices = 0;		Offset = StartVertices;		nCurrentVertices = 0;		hr = m_pBuffer->Lock(Offset,nVerticesToAdd*sizeof(TestFVF),(VOID**)&Pointer,D3DLOCK_DISCARD);		nCurrentVertices += nVerticesToAdd;	}// After locking, adding the verticesif(hr == S_OK && Pointer != NULL)	{		// add		int c=0;		for(c=StartVertices;c<nCurrentVertices;c+=6)		{			Pointer[c].x = 0;			Pointer[c].y = 0;			Pointer[c].z = 0;			Pointer[c].u = 0;			Pointer[c].v = 1;			Pointer[c].Diffuse = 0xFFFFFFFF;			Pointer[c+1].x = 0;			Pointer[c+1].y = 1;			Pointer[c+1].z = 0;			Pointer[c+1].u = 0;			Pointer[c+1].v = 0;			Pointer[c+1].Diffuse = 0xFFFFFFFF;			Pointer[c+2].x = 1;			Pointer[c+2].y = 1;			Pointer[c+2].z = 0;			Pointer[c+2].u = 1;			Pointer[c+2].v = 0;			Pointer[c+2].Diffuse = 0xFFFFFFFF;			Pointer[c+3].x = 1;			Pointer[c+3].y = 1;			Pointer[c+3].z = 0;			Pointer[c+3].u = 1;			Pointer[c+3].v = 0;			Pointer[c+3].Diffuse = 0xFFFFFFFF;			Pointer[c+4].x = 1;			Pointer[c+4].y = 0;			Pointer[c+4].z = 0;			Pointer[c+4].u = 1;			Pointer[c+4].v = 1;			Pointer[c+4].Diffuse = 0xFFFFFFFF;			Pointer[c+5].x = 0;			Pointer[c+5].y = 0;			Pointer[c+5].z = 0;			Pointer[c+5].u = 0;			Pointer[c+5].v = 1;			Pointer[c+5].Diffuse = 0xFFFFFFFF;		}		// unlock		m_pBuffer->Unlock();				// setting FVF and Stream source		m_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);		m_pD3DDevice->SetStreamSource(0,m_pBuffer,Offset,sizeof(TestFVF));		// render		hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,StartVertices,(nCurrentVertices-StartVertices)/3);		if(hr != S_OK)		{			return hr;		}	} // FVF Structurestruct TestFVF{	float x;	float y;	float z;	DWORD Diffuse;	float u;	float v;};


i set these variables in the begining:

	nMaxVertices = 240;	nCurrentVertices = 0;	Offset = 0;	nVerticesToAdd = 60;	StartVertices = 0;


so i wanted to add 60 vertices each time i do a render to a Vertexbuffer with 240 vertices
when the size of nCurrentVertices gets to 240 i do a discard and starts over.

the problem is that after rendering and filling the half buffer i get a "memory couldn't be written error"
it sounds like i'm writting outside the buffer, but i can't find the error.



hmm
i guess i could answer my own question, i checked with the DirecetX Caps viewer and realised that this card(which is a realy old on, RIVA TNT 32 ULTRA or something like that) dosen't support Streamoffset in HAL.

So how should i acomplished a Dynamic vertexbuffer then?
should i just set the streamsource with 0 as the streamsource?

This topic is closed to new replies.

Advertisement