VertexBuffer Question

Started by
8 comments, last by Krisc 19 years ago
I have some questions: Is there an easy way to have multiple objects write to one vertex buffer and then draw the one vertex buffer? As of now I have a class called iQuad which can draw a quad using DPUP but if I were to do that several times in one loop, clearly I would take a major performance hit so is there anyway I can have like a unified vertex buffer that I pass to the class and it adds it's specific data to that buffer? Also, can I have multiple vb's. maybe one for a 2d map and another for like player characters and others as needed? Thanks, John Sedlak
Advertisement
It'd be easiest to have some kind of quad/sprite manager, that keeps track of a VB, and adds quads to itself. How you do this is up to you, but it should be fairly straightforward. There's nothing saying that one VB needs to be associated with one C++ class instance either.
If it were me, I'd make a CVertexBuffer class, that holds the IDirect3DVertexBuffer9 pointer, the size of the buffer, and the next offset to add vertices to. Then you could pass a CVertexBuffer pointer to your iQuad class to render into.

You can have as many vertex buffers as you like, but there's a performance penalty involved in switching vertex buffers (With SetStreamSource()), so it's best to have as few as possible. If you're using the fixed-function pipeline, then you'll really need one vertex buffer for each vertex type.

In a rendering engine I made (which I lost the source code of, unfortunately), I could call CRender::CreateVertexBuffer(), which would return a class representing a section of a IDirect3DVertexBuffer9. This way I could cram several CVertexBuffers into one IDirect3DVertexBuffer9 more or less transparently.

Hope this helps.
How would I go about this? Do I keep track of the vertices added in a seperate array and then add them all to the buffer at once? When I create the buffer, all I see is a function SetData and nothing along the lines of Add() which will allows me to add on to the end of the buffer data.

Thanks,
John
Quote:Original post by Krisc
How would I go about this? Do I keep track of the vertices added in a seperate array and then add them all to the buffer at once? When I create the buffer, all I see is a function SetData and nothing along the lines of Add() which will allows me to add on to the end of the buffer data.
The way ID3DXSprite works (you might be better using that actually) is when you call ID3DXSprite::Begin(), it locks its internal vertex buffer. Then, for every Draw() call you make, it adds the quad to the vertex buffer. If it runs out of space in the vertex buffer, or you call call ID3DXSprite::End(), it'll unlock the VB, and draw all of the sprites.

So, you could either just add all of the vertices to an array, then lock your vertex buffer, copy the vertices, unlock and render, or you could lock the VB, and add vertices to it, then when you come to render you unlock the VB and render.

When I say "add vertices to the VB", I mean lock the vetex buffer and copy vertices into it. Or just lock the whole buffer at the start, and copy vertices into the next unused part of the buffer when you need.
Sorry if this question sounds really dumb but how do I add data to the buffer, codewise. As I said, all I see is a SetData() function, nothing along the lines of AddData(). I am assuming that SetData() does not care what is already in the vertex buffer and whipes it away with the new data of course.

note, I am in C# if that matters at all here...did not think it would though...

Thanks,
John
Evil? Anyone?...
Ok, I think I may have a clue as to how to do what I need to do...

in pseudoish code:

create vertex buffer of some size large enough for my vertices...integer i = 0call VertexBuffer.Lock(0, LockFlags.NoOverwrite)for each set of vertices m_verts     call VertexBuffer.SetData(m_verts, i, LockFlags.NoOverwrite)     i += m_verts.Lengthnext setcall VertexBuffer.Unlock()


Does this "theory"/"idea" work?

Thanks,
John Sedlak
Well, I'm not very familiar with C#, but in C++ you Lock() the buffer, which returns a pointer to the locked memory (this is probably the difference) which you can fill with your vertex data. Then you call Unlock() to return access rights to the GPU (make sure and call unlock!)

You can fit whatever vertex data you want in your buffer. Different FVF's, different size vertices, several meshes, it can all fit in a single buffer.

In C++, when you call SetStreamSource you can tell the runtime where in the buffer to begin referencing (OffsetInBytes). I profiled SetStreamSource with OffsetInBytes=0 and OffsetInBytes=X a while back, and both incurred a similar performance penalty (very small), though when you render many hundreds of triangles, its actually more efficient to stuff as much data as you can (reasonably) fit into a single buffer.

I forget the exact numbers, but if you search for SetStreamSource I made a thread about it a long time ago.
Chris PergrossiMy Realm | "Good Morning, Dave"
Ahhh, yes I see now that C#'s VB.Lock returns a System.Array which begs the question, what is this array exactly? I ask this because you can call Lock() with an offset of positions (let's say some integer n), so does it return an array of the buffer of positions n to length - 1? OR does it return an array of the whole buffer no matter what...?

:\ - i'm trying. heh...

thanks,
John Sedlak
Answered my own question... the array is apparently a fixed length and Lock returns all the data. So now I have to find a way to manage all this data...*sigh*

Programming is so fun... :D

This topic is closed to new replies.

Advertisement