Proper way to use Vertex Buffers

Started by
8 comments, last by xg0blin 20 years, 10 months ago
I am new to Direct3d. I learned OpenGL first. The way Direct3d does the vertices is really odd to me, and I can''t figure out the correct way to do it. Here''s the deal, I''m making a tetris clone to learn with (the same thing I did to learn OpenGL). I have my main.cpp file where I initialize everything, my blocks.h and blocks.cpp file where I am going to draw each of the seven different block types, based on the center and the type. I move the center around the board, and I want to fill my vertices array with the vertices everytime the blocks move or flip or whatever. The blocks that are already on the board, I want to put on the screen every frame with a for loop that checks if a block is present in an array. I never know how many vertices are gonna be on the board is my problem. Do I make the device external, and use many different vertex buffers, or do I use one set of vertex buffers, and lock, copy new vertices, unlock every frame in the render function. Every example I''ve seen has a vertex buffer they only need to worry about once. Mine changes every frame. What is the proper way to do this?
Advertisement
depending on how you display your blocks, you could do it one of several ways. In any case, even though the number of blocks at a given time changes, you can still compute the maximum number of vertices you''ll need and make a vertex buffer of that size.

It also depends on how you''re storing your data. If you''re using a tilemap, you can just have one vertex bufffer to represent a block and render multiple times to represent each tile. Using this method, you don''t have to switch vertex buffers, which should be avoided. The drawback to this is that you''re only rendering 12-24 triangles (depending on how your block looks) per call to DrawPrimitive, and you should try to render closer to 200+ per frame.

If you have a separate structure for the ''active block'' and the rest of the blocks, you can have a one vertex buffer represent the active block and another buffer to represent the rest of the blocks. You would update the active block every frame, but you would only update the rest of the blockfield when the active block falls to the bottom. This is a lot more efficient because your''re only making two calls to DrawPrimitive, and each contains a large number of vertices.

If you''re intereseted, I have a d3d8 tetris clone that''s fairly well-commented. You could use it as an example. E-mail me if you want to look at it, and I''ll see if I can find it.

Hope this helps, and good luck


Check out my raytracer at http://simp-raytracer.sourceforge.net. Download it at http://www.sourceforge.net/projects/simp-raytracer.
Make 1 vertex buffer with the size of the maximum possible blocks you can have on your board (4 * width * height). Then you can have a simple AddBlock() function in your wrapper class (if you have one) that will memcpy it to your pointer and update the number of vertices/triangles being used. When you are done adding just unlock the buffer and call the DrawPrimitive function (you should probably use DrawIndexedPrimitive instead), then set the number of vertices/triangles used to 0. Make sure you use the D3DUSAGE_DYNAMIC flag since locking every frame with a "static" buffer will like to eat your frame rate.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
So I should always aim to have just one vertex buffer? WTF? That sounds really crappy. Why wouldn''t I want to make several?
Switching vertex buffers has to flush everything out of the video card, so you want to keep that to a minimum. You can have more if you need it, but 1 for every block is rediculous.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
for a tetris clone you don''t need to do crazy vetrex buffer fills, just have one VB with a cube, and draw the cube multiple times to make the shapes. There isn''t going to be too many DrawPrimitive calls because this is tetris. For more complex and detaled scenes it makes sence to use batching.
what about a breakout clone? I have an array of blocks that are drawn to the screen using a for loop through an array. Their position never changes. The only thing about the block that ever changes will be that it gets the bDisplay flag set to false when it gets hit. This should all be in a static vertex buffer, no?

Then theres the paddle and the ball, both of which move. The paddle follows the direction of the mouse, and the ball has a direction vector. I have to translate each without bothering any anything else in the scene. When I was using OpenGL, I just had to do something like this:

glPushMatrix();
glTranslate(x, y, z);
// draw the objects I wished
glPopMatrix();

With direct3d, all my vertices would be stored in the same vertex buffer in this case (you guys said it would be a waste otherwise), so how do I go about doing the seperate translations for the ball and the paddle? Also, should I get rid of the vertices every frame and reput it in the vertex buffer, even though only the ball and the paddle changes? This is so much harder than opengl. I just want to figure out how to do this kind of thing the best way. Any help is appreciated .

Maybe I'm just not understanding their proper usage. Someone above suggested just having one cube to draw all my cubes. That would require immense amounts of translation to draw all of the blocks on my screen. I don't get it....

*scratches head*


[edited by - xg0blin on June 20, 2003 11:58:35 AM]
you cant possibly keep EVERYTHING in one vertex buffer. Have a separate one for the Paddle, The Ball, and The Blocks. For simple games like these, you can keep one block in a VB nd draw it multiple times, it;''s not that slow. Plus you''ll have other godies like the Hardware Transforms and different textures for each block.

I am also confused on this subject! Thanks for asking


---------------------My specs (because I always forget to post them)Intel P4 2.4 GHz640 MB system memoryRadeon 9700 PROWindows XPDirectX 9DirectX 8.1 SDK
quote:Original post by FuzzyBunny
For simple games like these, you can keep one block in a VB nd draw it multiple times, it;''s not that slow.


This is where i guess you''re losing me. Have one block in the vertex buffer, and translate it around and draw it several times to draw the whole scene? I could have like 13X26 (my tetrisboard array) places where it could be used, so I''d transform this single block around everywhere to draw the scene? I don''t get it. I must not understand what you are talking about.

This topic is closed to new replies.

Advertisement