Archived

This topic is now archived and is closed to further replies.

Telamon

Newbie C# D3D Question

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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

Share this post


Link to post
Share on other sites