Skip to main content
GameDev.net gamedev.net
🔒 Locked

Vertex Buffers

Started by ms291052 Jan 19, 2004 at 1:30 PM 7 replies 550+ views
Original Post
ms291052
ms291052
*Ahem* Before I say anything I apologize if I make anyone cringe in my bad coding-style... Ok... I finally decided that my 2D classes (CBitmap, CSprite, CBillboard, CParticleSystem, etc) were getting a bit out of hand since every instance of each class had its own VB ! Rediculous I know, so I decided to try to fix said problem. I understand how to lock, copy memory, unlock the VB and all that good stuff, and also I can store the index to where a specific instance of a class''s vertices are in the VB. The problem is that I don''t know how big to make the vertex buffer. I mean, if I''m in-game I may only have, say, 20 vertices in that buffer, because I''m only rendering 5 bitmaps for health, etc. However, say I chuck a grenade, and all of a sudden I''m using a billboard for the fire and a particle system for the smoke, the vertex count goes up a lot! How can I deal with resizing the vertices and, if necessary, recalculate the indices for each instance? As of now I have a global LPDIRECT3DVERTEXBUFFER9 g_p2DVB; and it''s declared as an extern in each class file. Then, I initialize and I just create a massive VB that will obviously handle most anything I could want, and then fill and blahdy blah that. I see that is horribly inefficient, and there''s got to be a better way. So... Can you resize a VB??
Erzengeldeslichtes
Erzengeldeslichtes
The only way to resize (that I've found) is to release it and create a new one.

If you must use vertex buffers for your 2d sprites: Why not just create a global 4 vertex VB with points at (-0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, -0.5, 0), (-0.5, -0.5, 0), and then have each 2d sprite use the scale part of the world matrix to make it, say, 128x128 units by scaling (128, 128, 0)?

[edited by - Erzengeldeslichtes on January 19, 2004 3:11:24 PM]
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
ms291052
ms291052
How would you go about releasing and creating a new VB? Would you not have to lock, loop through, save data, unlock, release, create new, lock, loop through, set data, unlock? That''s a rediculous amount of work for something that *should* be so simple.
Erzengeldeslichtes
Erzengeldeslichtes
Well think about it. When you create a vertex buffer you basically say "Set aside enough space for this many vertices." The next time you add anything else to the memory (a variable on the stack, a variable on the heap) it will be added RIGHT AFTER the set aside space. So when you resize the buffer you have to completely set aside a new section of memory after all the other memory set aside and copy the data into it, then release the original. (pseudocode: VERTEXBUFFER* g_VB, VERTEXBUFFER* temp, temp->create, copy(temp, g_vb), g_vb->release(), g_vb = temp)

[edited by - Erzengeldeslichtes on January 19, 2004 4:02:05 PM]
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
Fidelio66
Fidelio66
You can do all your 2D in directgraphics with just one VB with 4 or 6 points, which stays constant and never needs to be updated.

Make a quad (between -0.5 and 0.5 in x and y and u and v, with z set to 1) and store this in a vertexbuffer.

Set the view matrix to the identity.
Set the projection matrix to a matrix generated with D3DXMatrixOrthoLH(matOrtho, mydev.width, mydev.height, 1, 10);
This allows you to use z between 1 and 10 for depth (overlapping).

Then for each quad you want to render you use D3DXMatrixScaling and D3DXMatrixTranslation to scale it to the right size in pixels for x and y, and z with eg. 1.05, and translate it to the rigth position on the screen. (0,0) is the center. The z is of course related to the depth/drawing order. Multiply those matrices and set that as the world matrix.

If you want to fade quads with alpha you can set a material with diffuse r,g,b to 1.0 and vary the alpha. This way you never have to update the (small) vertex buffer.

Then set texture, material. If you use this for on-screen menu''s beside 3D action you also set the streamsource and vertexshader (FVF) and texturestagestates. And then a simple drawprimitive call.

ms291052
ms291052
Thanks everyone for your help. I think I should try out Fidelio/Erzengeldeslichtes''s method of only a few vertices. I''m glad someone out there is more of a creative thinker than I am.
Raloth
Raloth
Simple answer: don''t resize it! When you run out of room unlock the vertex buffer, render, relock, and start filling it up again.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
mishikel
mishikel
Fidelio: Wouldn''t your method be more inefficient than using an dynamic vertex buffer and adding pretransformed vertices each frame? I would think that a couple hundred DP calls (one for each quad, as you describe) would be more inefficient than using the locking scheme described in the SDK docs for dynamics VBs.

Matt
Fidelio66
Fidelio66
It depends on the purpose and amount of quads I guess.

I made something like this based on some articles for a menu class. So it''s typically a dozen, a background, one for each line of text, button, checkbox etc. This keeps it simple, one VB at initialization, and all things are objects with the neccesary parameters, position, size, texture, alpha.

If you want a game with 1000 objects floating around, it might work. I never tested that on this scale.

However it might just be possible. It requires no renderstates since they can be the same, just settexture/settransform/drawprimitive.

If you have a hundred sprites with one texture then maybe the VB method works because it''s one draw for a few hundred.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.