|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| Using Vertex Buffers With DirectX |
|
![]() wazoo69 Member since: 9/8/2000 From: Calgary, Canada |
||||
|
|
||||
| What a helpfull article on using VertexBuffers! |
||||
|
||||
![]() Luminous Member since: 11/4/2001 From: Marietta, GA, United States |
||||
|
|
||||
| Vertex Buffers are also in DirectX 7 :D |
||||
|
||||
![]() Spacecat Member since: 7/26/2002 From: Quebec, Canada |
||||
|
|
||||
| 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 |
||||
|
||||
![]() bpopp Member since: 5/3/2002 From: Memphis, USA |
||||
|
|
||||
| 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) |
||||
|
||||
![]() wazoo69 Member since: 9/8/2000 From: Calgary, Canada |
||||
|
|
||||
| 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, |
||||
|
||||
![]() Syrillix Member since: 5/7/2002 From: Brisbane, Brisbane, Australia |
||||
|
|
||||
| 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? |
||||
|
||||
![]() wazoo69 Member since: 9/8/2000 From: Calgary, Canada |
||||
|
|
||||
| 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, |
||||
|
||||
![]() Syrillix Member since: 5/7/2002 From: Brisbane, Brisbane, Australia |
||||
|
|
||||
| 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 |
||||
|
||||
![]() wazoo69 Member since: 9/8/2000 From: Calgary, Canada |
||||
|
|
||||
| Syrillix: very sensible and a practical solution! There's always that option as well. |
||||
|
||||
![]() Pipo DeClown Member since: 2/16/2002 From: Amsterdam, Netherlands |
||||
|
|
||||
| [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? |
||||
|
||||
![]() Pipo DeClown Member since: 2/16/2002 From: Amsterdam, Netherlands |
||||
|
|
||||
| *PMUB* |
||||
|
||||
![]() wazoo69 Member since: 9/8/2000 From: Calgary, Canada |
||||
|
|
||||
| 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? |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| 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. |
||||
|
||||
![]() madiyaan Member since: 11/24/2003 |
||||
|
|
||||
| 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, |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|