• Advertisement

Archived

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

Specifying the order of a triangle strip?

This topic is 5098 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I'm working on a .map parser. I've learned quite a bit from Stefan's article here: http://folk.uio.no/stefanha/ However, I've run into a little snag and I'm looking for a way to rectify it. From what I can gather, DirectX draws its triangle strips like this (when you're drawing a quad): 2 3 0 1 If you follow my sexah ASCII art. However, when I try to simply create my verticies for my quad in the same order I'm getting them from the CMF, I end up with 'broken quads'. You know the kind I mean, they look like: ____ | / |__ That kind of stuff. I've found that if I juggle the verticies around, I can get the verticies to draw just fine. Basically, I get the verticies in the order A B C D and I change that order to D A C B, the polygons all end-up fine. However, this juggling is pretty silly and will only complicate things as I add support for triangles and polygons more complex then 3 or 4 points. So I figured I'd fix the problem now, before I continue. So, going back to my original assumption, we can see the quad is drawn like this: C B D A So is there a way to change my polygon ordering, so that I start at A, move up to B, left to C, then finish my other triangle to form the quad with D? Near as I can tell, thats still CCW it just starts at a different vertex. This would make the order for all of my other polygons work, I would hope. Do I maybe want soemthing other then a triangle strip? So any ideas? [edited by - GroZZleR on February 7, 2004 12:13:43 AM]

Share this post


Link to post
Share on other sites
Advertisement
You''re going to apply this to a terrain map right? I wouldn''t recommend triangle strips for such. You should use Triangle Lists. Also, I didn''t quite understand your explanation, but I''m not sure you comprehend triangle strips completely. Forgive me if I''m wrong. I''ll give a brief synopsis just in case.

Triangle strips take the first two points in the vertex buffer or index buffer, call those two points of the starting triangle. Then the third point encountered makes the first full triangle. Then the fourth point defines a triangle between the second and third points. Then the fifth point defines a triangle between the third and fourth points, and so forth. So, you can''t draw the quad as A,B,C,D as in:

C B
D A

It has to be A,B,D,C or A,D,B,C or B,C,A,D or etc... Does that make sense? Is this what you were asking or am I confused?

Also, the vertex declaration "Direction" (i.e. clockwise or counter) is defined by the first three vertices in a Triangle Strip. Make sure you have culling set appropriately.

Chris

Share this post


Link to post
Share on other sites
I don't think we're on the same wavelength and probably just confused eachother more =P

The map is going to be used in many different ways, but definitely not a height map if thats what you mean by terrain. More Half-Life / Quake style levels.

Alright.

I parse the map file, and I get 4 points like this:
-1, 0.5, 1 (A)
-0.5, 0.5, 1 (B)
-0.5, 0.5, -1 (C)
-1, 0.5, -1 (D)

But when I slap the verticies into my Quad, I get the 'broken polygon' as discussed earlier.

By re-arranging the verticies, to this:
-1, 0.5, -1 (D)
-1, 0.5, 1 (A)
-0.5, 0.5, -1 (C)
-0.5, 0.5, 1 (B)

My Quad is drawn just fine. Bottom Left, Bottom Right, Top Left, Top Right.

What I'd like to do, is render the polygon in the same direction I'm given it though. So not re-arrange them, but take the original points and render from there. That way, all my verticies for future objects (triangles and others) are rendered in the correct order as well.

I'm using a triangle strip because that seemed to make the most sense to me. I'll have to check out triangle lists I guess.

I wouldn't mind a solution for either primitive =)

[edited by - GroZZleR on February 8, 2004 1:13:15 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Use an index buffer with a triangle list.

Assuming the quad is like the one below

1------2
| |
| |
| |
3------4

Youd have to set the vertex and index buffers like so:
Vertex Buffer: 1, 2, 3, 4
Index Buffer: 1, 2, 3, 3, 2, 4

and then call DrawIndexedPrimitive(0,2,D3DPT_TRIANGLELIST)

The logic behind this is to maintain readability while allowing vertex reuse. Basically, the index buffer specifies which vertices are to be drawn and in what order. Once you start using it youll scoff at triangle strips and fans.

Thats the logic but you might want to check on the syntax and the way DX orders its polys.

-- psamty

Share this post


Link to post
Share on other sites
I apologize for my poor ASCII art skills

i meant:

1------2
|xxxxxx|
|xxxxxx|
|xxxxxx|
3------4

Share this post


Link to post
Share on other sites
Oops... a little blooper on the syntax too....

DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 4, 0, 2)

Look into the SDK docs for an explanation of each of the arguments.

Creating an index buffer is much like creating a vertex buffer, look at the function CreateIndexBuffer()

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
It looks like the actual problem is that the verts are ordered such that they should be drawn using a tri-strip, but you''re telling D3D to draw a quad, and you will have to re-order to get that to work. Instead, try drawing the four verts as a strip in the order that they''re specified, and see what happens.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
It looks like the actual problem is that the verts are ordered such that they should be drawn using a tri-strip, but you're telling D3D to draw a quad, and you will have to re-order to get that to work. Instead, try drawing the four verts as a strip in the order that they're specified, and see what happens.


I am currently using a strip and without reordering the polygon comes out malformed. Unless I've misunderstood what you mean.

---

Thanks psamty10, I'll try using an Index Buffer for it. Won't this be adding a little bit of overhead though? Or is it just an insignificant amount?


[edited by - GroZZleR on February 8, 2004 1:20:48 PM]

Share this post


Link to post
Share on other sites
Somethings amiss. Nothing fails, but I''m only getting 1 triangle in the quad, not two.

I''m not sure if its my code or not, I''m sure it is, so here''s a little code:


bool CQuad :: CreateIndexBuffer(void)
{
VOID *pBufferIndices = 0x00;

if(FAILED(m_pD3DDevice->CreateIndexBuffer(6 * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIndexBuffer, NULL)))
{
MessageBox(NULL, "CreateIndexBuffer", "CREATE INDEX BUFFER BROKE", MB_OK);
return false;
}

// WORD pIndices[] = { 1, 2, 3, 3, 2, 4 };

WORD pIndices[] = { 0, 1, 2, 2, 1, 3 };

if(FAILED(m_pIndexBuffer->Lock(0, 6 * sizeof(WORD), &pBufferIndices, 0)))
{
MessageBox(NULL, "Lock", "CREATE INDEX BUFFER BROKE", MB_OK);
return false;
}

// Copy stored indices to index buffer

memcpy(pBufferIndices, pIndices, 6 * sizeof(WORD));

if(FAILED(m_pIndexBuffer->Unlock()))
{
MessageBox(NULL, "Unlock", "CREATE INDEX BUFFER BROKE", MB_OK);
return false;
}

return true;
}


Heres how I draw it:

void CQuad :: Render(void)
{
/*
// No Texture, Probably Don''t Need This...
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
*/


//Select the material to use

m_pD3DDevice->SetMaterial(&m_matMaterial);

// Set Us Up.

m_pD3DDevice->SetFVF(QUAD_D3DFVF_CUSTOMVERTEX);
m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(QUAD_CUSTOMVERTEX));
m_pD3DDevice->SetIndices(m_pIndexBuffer);

// Draw!

//m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

if(FAILED(m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2)))
MessageBox(NULL, "FAILED TO DRAW PRIMITIVE", "AHHH", MB_OK);

return;
}


Nothing fails, and the VB and stuff is fine. Unless I have to alter the VB in someway to compensate for the IB, but the example from Andy Pike didn''t show anything like that so maybe I''m wrong. The VB was working fine with the DrawPrimitive call when I re-arranged the verticies, so I don''t think thats the problem.

When I get verticies like these:
-1, 0.5, 1 (A)
-0.5, 0.5, 1 (B)
-0.5, 0.5, -1 (C)
-1, 0.5, -1 (D)

And I order them, it does come out to
A B
C D

As psamty10''s example shows, so everything is in synch. I just can''t figure out whats wrong =(

Share this post


Link to post
Share on other sites
Hey woah,

I'm searching the forms for an answer to my question and I came across this thread, it's like the same problem I'm having... However, it's not answered. I tried the stuff above too and I've got the same problem as Grozzler.

Anyone still looking into this problem?!?!?!

- Newb Programmer: Geek++

EDIT: spelling

[edited by - GeekPlusPlus on February 8, 2004 11:45:59 PM]

Share this post


Link to post
Share on other sites
quote:

When I get verticies like these:
-1, 0.5, 1 (A)
-0.5, 0.5, 1 (B)
-0.5, 0.5, -1 (C)
-1, 0.5, -1 (D)

And I order them, it does come out to
A B
C D



The vertex ordering is flawed.

Note that if we read in the vertices (x,y,z), the ones youve produced up there will be:

A--------B
|*******|
|*******|
D--------C

And thats where the problem lies..... the two triangles overlap..... moreover DX draws vertices anticlockwise, which means the first triangle wont draw at all.

For the order youve shown above try the two below

IB = { A,D,B,B,D,C }
The above one works if its anticlockwise ordering
The one below if its clockwise ordering
IB = { A,B,D, D,B,C }

Try em both....

Prasan


[edited by - psamty10 on February 8, 2004 12:18:36 AM]

[edited by - psamty10 on February 8, 2004 12:19:05 AM]

Share this post


Link to post
Share on other sites
A wimpier way to do it is:

pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

This sets off backface culling so that vertex ordering doesnt matter

Share this post


Link to post
Share on other sites
First and foremost, thank you very much for your help psamty10, you've been invaluable. But now I've quite a little quirk, I'm curious about.

Heres output, right from my quad class as I set up the vertices. My vertices are ordered like this:


-1 0.5 1
-0.5 0.5 1
-0.5 0.5 -1
-1 0.5 -1


As (you've corrected), that comes out to:
A B
D C

But when I use the CCW method you've described below:
IB = { A,D,B,B,D,C }

Which is clearly counter-clockwise (unless I don't know the clock as well as I think I do), but with the cullmode set to CCW, it culls out the frontfaces and draws the back faces? I can tell this because my boxes are now being rendered inverted (I'm sure you know what I mean).

If I set the cullmode to CW, then it renders just fine.

And oddly enough, if I setup the other method you've described here:
IB = { A,B,D, D,B,C }

And turn the cull mode to CCW, then it renders just fine, even though those verticies are being drawn in a CW manner.

Does this lead me to change my thinking on how backface culling works? That it culls in the opposite? The backfaces of the frontfaces would be drawn in the opposite order of the way they're drawn, correct?

So if you draw in CW, the backfaces are CCW, and they're the ones that are culled out?

I was always under the impression that it culled the backface of the frontfaces that are drawn in the culled method.

If you can follow =P

Anyone have some input here?

[edited by - GroZZleR on February 9, 2004 1:49:38 AM]

Share this post


Link to post
Share on other sites
Keep in mind that different APIs order their vertices differently.

The real way to think about it is that the normal is projected outwards from the face drawn (either CW or CCW DEPENDING on the API being used).

Back face culling removes faces with normals facing AWAY from the camera.

It doesnt cull the back face OF the front faces.
A face is either a BACK face OR a FRONT face - not both.

[edited by - psamty10 on February 9, 2004 1:54:45 AM]

Share this post


Link to post
Share on other sites
I don''t currently calculate the normal, I figured that was just for lighting. My FVF only specifies 3 points and a colour.

Once I calculate the normals and add that to FVF, will I find I might have to re-order the drawing order?

Share this post


Link to post
Share on other sites
DX calculates the normal, even if you dont.
The Normal is usually not calculated at all actually, its interpolated using the 3 verts

Share this post


Link to post
Share on other sites
If your wanting to do more complicated geometry as well then you want to just remder traingles (lists) with an index buffer like said above. That''ll make life much easier. I had a good link to a site on index buffers but I haven''t got it with me - typical. I''ll try and find it out.

Share this post


Link to post
Share on other sites
I found this really useful - it only applies to the draw indexed primative comand but it's a reall good tutorial.

http://bellsouthpwp.net/d/f/dfrey69/dip.htm

I credit the person who wrote it (someone on these forums) cus it really helped me out.

I also recomend you try using the draw indexed primative comadn to try drawing each triangle individually and try other things like checking the IB and the VB to make sure the right data's there. It may take a bit of fiddeling but it'll be worth doing.

Good Luck!

[edited by - de_matt on February 9, 2004 7:51:40 AM]

Share this post


Link to post
Share on other sites

  • Advertisement