How to draw a rectangle with DX9?

Started by
9 comments, last by kevlur 19 years, 10 months ago
Hi kevlur. Are you trying to make rectangles (quads) in Direct3D to create a 2D game (like Mario Bros or PacMan), or are you wanting to render 2D rectangles in a 3D game (like a scoreboard or ''sprite'' objects in Quake3)?

If you''re just trying to create a rectangle in Direct3D, I''m going to show you how to modify the DirectX tutorial ''Tut02_Vertices'' to get it to draw a ''rectangle'' instead of a ''triangle''. Once you get that figured out, the rest is cake.

First, copy the contents of ''Tut02_Vertices'' into an ''experiment'' folder. You''re going to be doing a little bit of modifying of this code, so you don''t want to try these edits on the original code.

Now open ''Vertices.vcproj'' from within your ''experiment'' folder and look at the code. Go ahead and build it and run it to make sure it works (you''ll see a small window with a colorful triangle on a blue background). If that works, then go to the next step.

Look down to the function ''HRESULT InitVB()''. You''ll see a vertex list (CUSTOMVERTEX vertices[]) that makes up the vertex coordinates and colors for their triangle. Since a triangle only consists of three vertices, you''ll only see a three-line list. A rectangle (also known as a ''quad'') is made of four vertices, so we need to add another vertex and then rearrange the coordinates a little to turn it into a quad.

BEFORE:
CUSTOMVERTEX vertices[] ={	{ 150.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color	{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },	{  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },}; 


AFTER:
CUSTOMVERTEX vertices[] ={	{ 50.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color	{ 250.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, },	{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },	{  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },}; 


I rearranged the (x, y) coordinates to make a quad. The arrangement of the vertices is important; you can see that I started with the upper left corner of the quad and went around clockwise to the last vertex. (50, 50), (250, 50), (250, 250), (50, 250). If you get the vertex order wrong, you''ll either see one triangle or you won''t see anything at all when your program''s run.

Now look a little further within this same function and you''ll see the code that actually buffers this vertex info (CreateVertexBuffer). Currently, it''s looking for a CUSTOMVERTEX array that is only three lines big (three vertices make a triangle). We need to change that so it can handle an array that''s four lines big (four vertices make a quad).

BEFORE:
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) ){	return E_FAIL;} 


AFTER:
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) ){	return E_FAIL;} 


Only one difference there; changed a three to a four. But if this size isn''t correct, then the vertex buffer won''t be created and the function will bail with an E_FAIL result.

One last change needs to be done. Look a little further into the code for the function ''VOID Render()''. Within that function, you''ll see the actual ''DrawPrimitive()'' function. That''s where the triangle is actually rendered on the screen. I made some changes to it, so here they are:

BEFORE:
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 ); 


AFTER:
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); 


You''ll notice two changes; the constant and the number in the function''s argument list.
The example used the constant ''D3DPT_TRIANGLELIST'' whereas I used ''D3DPT_TRIANGLEFAN''. A triangle list is simply a bunch of triangles that make up a primitive. In other words, your quad is made of two separate triangles. That''s not very efficient, since each triangle uses three vertices, and using two separate triangles to make your one quad will mean that six vertices will be used. A triangle fan is a bunch of triangles that share common vertices to make up a primitive. Now your quad is still made of two triangles, but those two triangles share four vertices to make a quad . That''s just great, because now your one quad only uses four vertices.
Finally, the example used ''1'' at the end of the argument list whereas I used ''2''. This is important, as this number indicates how many triangles are going to make up your primitive! The example only drew one triangle, so naturally the primitive is only going to consist of ''1'' triangle. Your quad is going to consist of two triangles, so we need to tell ''DrawPrimitive()'' that this primitive is going to be made up of ''2'' triangles. If you don''t change this to a ''2'', then you''ll only see a triangle when your run the program.

That''s about it. Only three line changes (vertex count, vertex buffer size, and primitive triangle count) and everything else stays the same. But I''m still very much a newbie, so hopefully this info will help you!
"The crows seemed to be calling his name, thought Caw"

This topic is closed to new replies.

Advertisement