Newbie C# D3D Question

Started by
4 comments, last by Telamon 20 years, 7 months ago
Ok. I recognize this is probably a stupid question and that by asking it I am demonstrating a complete lack of understanding of how the Managed DX9 Framework works. This is not my fault. The documentation is absolute garbage and the samples are all too similar to gain much insight. I am writing a clone of Tetris Attack. This is a graphically simple game and I basically want to draw 200-ish different colored cubes onto the screen. I know how to draw one cube (or any shape, really) from the MDX9 samples by loading the vertices into a vertex buffer and blasting it to the screen with DrawPrimitives(). How do I draw more than one cube? I know, I know... When rendering a scene with multiple distinct objects in Managed DX9, is it best to make a vertex buffer for each and every object? That seems inefficient compared to OpenGL, which lets you send vertices directly to the hardware. I understand that vertex buffers optimizes traffic on the graphics pipe, but it seems like a messy solution. What is the real way to do this? Right now I''m filling a single vertex buffer up with all my cubes'' data (200-ish cubes) and drawing it as a TriangleList, which I know is bad because it duplicates a lot of vertex data. For the love of all the is holy, why can''t Microsoft release proper MDX9 docs!!! It''s been almost an entire year since DX9 was released.

Shedletsky's Bits: A Blog | ROBLOX | Twitter
Time held me green and dying
Though I sang in my chains like the sea...

Advertisement
I''m not sure what they''ve changed in DX9, so bear with me, this is from my DX8 experience.

You don''t need a seperate vertex set for each block. Since your blocks are all the same shape, just do this:

loop {
set the texture (blue, red, etc)
set the position
render
}
Generally you''ll want to have a separate vertex buffer for each distinct vertex type (not necessarialy each object!), as it is ideal to reduce the number of vertex buffer switches during runtime. Since it sounds like all of your vertex data shares the same format, it is best from a speed standpoint to store all of that data into the same vertex buffer, like you''re doing now.

You may also want to consider pairing an index buffer along with your vertex data to make use of many cards'' on-chip post-transform vertex cache. When combined with an index buffer, triangle lists actually don''t perform too poorly.

And, to answer your question, you can still use Device.DrawPrimitives, with the start offset set to whatever vertex offset into your VB you choose (usually zero), and the last parameter as the total number of primitives you wish to render. Since all your cubes are packed into the same VertexBuffer, this would simply be the number of vertices in the VB divided by three (for a TriangleList).

I agree that the MDX docs are absolutely terrible, and unfortunately most of the tutorials out there on MDX are just more detailed explanations of the tutorial examples which ship with the SDK. So...

<shameless plug>
In the coming weeks, http://www.xsdev.net/tutorials.php will be hosting some new tutorials on MDX9 w/C#, covering material from absolute newbie stuff, to advanced stuff utilizing shaders and effects, to other small things which many people seem to skip over or ignore completely.
</shameless plug>

Anyway, I hope my reply was of some assistance, and good luck with the MDX docs

Russell Klenk
Oh, I forgot to mention that you''ll still need to make a separate DrawPrimitives call for each distinct object (which is inefficient, as you might guess). You''ll simply need to update the starting offset into your vertex buffer (specified in vertices, IIRC) and your primitive count (specified in primitives). If each block set has the same number of triangles (or cubes, or whatever) you won''t need to recompute the primitive count every time, so your render loop will look something like this:

[C#-ish]
int vertsPerObj = 12 * 3 * 4; // 12tri/cube@3vert/tri@4cube/block
int primsPerObj = 12 * 4; // assuming 4 cubes/block
int totalVerts = <size of your vertex buffer, in vertices>

<SetStreamSource here>
for ( int ofs = 0; ofs < totalVerts; ofs += vertsPerObj ) {
<set block render state here>
<set block world transform here>
activeDevice.DrawPrimitives( PrimitiveType.TriangleList, ofs, primsPerObj );
}

Ideally, you''d have sorted objects inside you vertex buffer by render state, in which case the for loop would change slightly:

int offset = 0;

for ( int group = 0; group < numGroups; ++group ) {
<set render states for group ''group''>
for ( int object = 0; object < numObjsInGroup; ++object ) {
<set world transform for object ''object''>
activeDevice.DrawPrimitives( ..., offset, primsPerObj );
offset += vertsPerObj;
}
}

Russell Klenk
Tetris Attack is one of my favourite games of all time!
Sorry, no productive info
The previous answers covered it pretty good.

Niko Suni

Thanks guys, that was pretty helpful.

Hey! I''d love to know when you start putting up new C# DX9 tutorials, make sure you make a post about it :-)

Shedletsky's Bits: A Blog | ROBLOX | Twitter
Time held me green and dying
Though I sang in my chains like the sea...

This topic is closed to new replies.

Advertisement