Home » Community » Forums » » Using Vertex Buffers With DirectX
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic


 Last Thread Next Thread 
 Using Vertex Buffers With DirectX
Post Reply 
What a helpfull article on using VertexBuffers!

 User Rating: 1038   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Vertex Buffers are also in DirectX 7 :D

 User Rating: 1018   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

I'd like to recommend an extra link: http://developer.nvidia.com/view.asp?IO=Efficient_Use_Vertex_Buffers
This is the official NVidia viewpoint on the uses of Vertex Buffers. And I'm happy to note there are no contradictions between this article and the GeForce makers. (I was a bit worried when I read that Dynamix Buffers were 'recommended', turns out they can thouroughtput 70% of a Static Buffer performance if used correctly - at least on NVidia chipsets)

If you want the more 'general' NVidia articles, here they are.(makes a good bookmark along with their Dev Sitemap)
http://developer.nvidia.com/view.asp?PAGE=directx

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Good article but unfortunately it didn't answer the question that has been running around in my head for weeks. How do you handle multiple unrelated objects (each with their own shader settings/transformations) with a single vertexbuffer?

In my case, I have a terrain, a few models, a skybox, and some 2D objects (bitmap fonts, HUD, etc.). Currently each of my objects has it's own vertexbuffer but I know this is extremely inefficient.

I'm thinking each object could dump it's vertexes into a common vertexmanager (possibly a singleton), and then store the offset. So an objects vertex creation might look like:

MYVERTEX* pVertices;
VertexManager::Instance()->lock ( &pVertices, &m_offset );
pVertices->x = 100;
pVertices->y = -100;
..
VertexManager::Instance()->unlock();

And then the object's rendering loop might look like:

SetTexture ( 0, m_texture );
DrawPrimitive ( D3DPT_TRIANGLELIST, MYVERTEXFVF, m_offset, VertexManager::Instance()->getVB(), m_vertexCount );

Would something like this work? How would the vertexmanager handle situations where the vertex buffer is full?

bpopp (bpopp.net)

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

I think it depends upon your 3d engine requirements bpopp.

Direct3D9 seems to be a bit more flexible in terms of designing a generic "vertex buffer manager" object that will control the type of operations you're looking at.

Although I use a vertex buffer manager for D3D8.0, it's of a fairly "light" design. All of my objects within the game use the same FVF, which makes the vertex buffer usage that much more speedier.

Your manager would need to keep track of the initial size of the vertex buffer and how many primitives have been sent to the GPU so far. As you add primitives to the object, you'll have to do a quick check to see if you've hit that maximum. If so, then just unlock the vertex buffer and call DrawPrimitive. Once that's finished, relock the vertex buffer and then continue to add triangles/primitives to the object.

If you want to see a sample of how I do this, check out my GPL'd DX8.0 game "AsteroidArena" available on my website.

http://www.wazooenterprises.com

hth,

 User Rating: 1038   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

great article... my only question is how would you go about switching textures during the drawing... or would you have one dynamic VB for each particle system or systems that share the same textures?

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Syrillix: Great question. And one that doesn't have a "too" definite answer.

It really depends on your game.

Both NVidia and ATI documentation clearly point to the fact that the less vertex buffer switching that goes on in your game, the better off you'll be.

However, at the same time, if you're only using one dynamic vertex buffer for the scene, then it'll mean a LOT of locking/unlocking operations as you pass it around between object managers.

There's probably a formula somewhere which computes the ideal size/amount of vertex buffers based on scenegraph information (such as vertices, size of vertices, number of textures, etc), but I have as yet to see it.

To try and provide an answer though, I would first try it the easy way: select your first particle system texture, batch up your primitives in the GPU related to that texture, then switch to the next texture, add its primitives, etc..

If your frame rate drops dramatically whenever more particle systems are in play, then add another vertex buffer to see if it helps out.

hth,

 User Rating: 1038   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

thanks for the reply, the solution i came up with was to author all the particle textures into 1. i use at most 4 textures so that makes it kinda easy.
when particles are being created i examine the type of particle system and adjust texture coordinates accordingly.... not exactly the best solution but it also meant zero texture switching during particle rendering, which is always nice

Get busy livin' or get busy dyin'... - Shawshank Redemption

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Syrillix: very sensible and a practical solution! There's always that option as well.

 User Rating: 1038   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

[Creation of Dynamic Vertex Buffers]
Direct3D 9.0 example:

//now that the GPU has handled the above vertex data,
//relock our vertex buffer area with DISCARD to flush it
if(FAILED(hr = m_lpVB->Lock(0, m_iVBSize * sizeof(VERTEX_PARTICLE),
(VOID **) &pVertices, D3DLOCK_DISCARD))){
return hr;
}



Isn't Lock() expensive?

 User Rating: 1469   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

*PMUB*

 User Rating: 1469   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Yes Lock() is an expensive operation, which is why the documentation really recommends keeping it down to a minimum during each render frame..

ie. instead of locking/unlocking 10 times a frame or whatever, try to sort out your objects so that you only need to lock/unlock the vb once or so a frame...

that help?

 User Rating: 1038   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

This article help me a lot in understanding the semantics of Vertex Buffers.

However, i still have one question for you:

How do I combine "The Microsoft Way" of drawing dynamic VBs with DrawIndexPrimitiveCall. I already have de Index Buffer but if i keep changing the VB the data in the IB becomes corrupt.

 User Rating: 1015    Report this Post to a Moderator | Link

I know this article is pretty old, but can anyone tell me how method #2 is different from method #3? The way I see it, both keep CPU and GPU parallel. Does it have something to do with the way DX manages memory?

Thank you,

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: