Sign in to follow this  
Ryam BaCo

z-buffer example for newbie...for...me...

Recommended Posts

hi all! i'm new here and really looking forward to post with you in the future. aye, so much for introduction. ;) now...my problem...i started learning directx in c++ and i'm going through an small example about my new friend z-buffer yet. so my new good old friend direct3d draws two quadrangles (made out of triangles...i know), one rotating along the y-axis, one rotating along the z-axis. so here are the important parts of the example: here are the vertices, 6 for the first quadrangle, 4 for the second one... sVertex Verts[10] = { { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { -100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { 100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { 100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { -100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) }, { -100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) }, { 100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) }, { 100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) }, }; and here's the rendering-rotation-stuff: // Create and set the world transformation matrix // for first four primitives. Rotate along Y-axis. D3DXMatrixRotationY(&matWorld, (float)timeGetTime() / 1000.0f); g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); // Draw first four polygons g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 4); // Draw next four polygons, but rotate on Z-axis D3DXMatrixRotationZ(&matWorld, -(float)timeGetTime() / 1000.0f); g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 6, 2); oh...and here's my question: why can't i build the first quadrangle (the one rotating along the y-axis) out of 2 triangles (...and 4 vertices)? why do i have to use 4 triangles (...and 6 vertices)? i don't understand why i have to use these 2 additional vertices for the first quadrangle. sVertex Verts[10] = { okay...these 4 vertices are "used" for the 4 edges of the quadrangle... { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { -100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { 100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { 100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, ...but why these ones?... { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, { -100.0f, 100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) }, i think i missed something. so please help! :)

Share this post


Link to post
Share on other sites
I'm not sure what this has to do with a z-buffer?

This is related to index buffers and drawing indexed primitives. The rendering system draws each triangle as an indivual "task". That means it needs three vertices per triangle, or six vertices per quad. The purpose of an index buffer is to reduce the vertices in this exact type of situation. It's basically just a lookup table. The rendering system uses the index buffer to reference the vertices, so they need to be stored in a specific order. The vertices themselves won't need to be in a certain order anymore, because the index buffer points the rendering system into the vertex for each index. Like this:

Vertex 0 = Vertices[ IndexBuffer[0] ];
Vertex 1 = Vertices[ IndexBuffer[1] ];

Take a look at the DrawIndexedPrimitive method. It's less important with such a small number of vertices (6). But it can become a huge memory saver later on.

Share this post


Link to post
Share on other sites
Quote:
i'm new here and really looking forward to post with you in the future

Welcome to the forums[attention] - hope you enjoy your stay [grin]

Coder, our moderator in these parts, would probably appreciate it if you familiarised yourself with the various FAQ's (if you haven't checked them already).

Anyway, your question...

They look to me like they could be degenerate triangles...

Basically, with triangle strips (indicated by D3DPT_TRIANGLESTRIP in your draw call) each triangle is connected to the previous one:


0---1
/
/
/
2---3
/
/
/
4---5
/
/
/
6---7


So if you wanted two quads that **weren't** actually connected you'd have to put something in the middle - e.g. degenerate triangles. These are triangles that you either don't draw (which looks like what your code does) or triangles that when drawn don't actually appear as anything...

Alternatively, you could use D3DPT_TRIANGLELIST and just specify 6 vertices (3 vertices for each of 2 triangles) per quad, for a total of 12 vertices in the buffer...

I haven't actually checked against the coordinates you're using, so the above could be wrong - but a hunch tells me that it's the case [wink]

hth
Jack

P.S. - This isn't really anything to do with the Z-Buffer as per your title! [smile]

Share this post


Link to post
Share on other sites
Erp. Guess I wasn't paying enough attention. I didn't notice you were rendering as triangle strips. I guess an index buffer won't do you much good :)

Share this post


Link to post
Share on other sites
thx for your fast replies! :)

hmmmkay...i made a screenshot of this fine example:
http://mitglied.lycos.de/affengottsekte/buffididbuffbuff.png

our red friend is spinning around the x-axis, our blue friend along the z-axis
and it's related to my other new friend z-buffer (what a bunch of friends i get because of directx!!! woohoo!!!) because our blue friend hides parts of our red friend, which don't need to be rendered or something.

and if i try to build our red friend just with 4 vertices the program doesn't work properly, because our red friend is flickering...what i don't get is why are here 2 "extra"-vertices with exactly the same coordinates as the first two vertices used.

Share this post


Link to post
Share on other sites
You've definitely got some degenerate triangles in there [smile]

If you step through your 10-vertex array, you get the following pattern of triangles:

The first triangle is defined 0->1->2 with the final edge created between 2->0:

0 2
| /
|/
1


The second triangle is defined 1->2->3 with the final edge created between 3->1:

2
/|
/ |
1 3


The third and fourth triangle seem to be back-facing as they exist coplanar to the first two, but in an opposite order. This means that when the triangles rotate such that they *dont* face your camera they still appear on the screen. They appear as the following:

4 2 4
\ | |\
\| | \
3 5 3


Now the next two are blatantly degenerate as they have no area:

46 6
|| ||
|| ||
5 57

(a bit tricky to express as ascii art!)

The last two triangles, creating the blue quad are as so:

6 8 8
| / /|
|/ / |
7 7 9


hth
Jack

Share this post


Link to post
Share on other sites
[edit]
waaahhhaaaa! answer to myself: so...when the red quad is spinning i need to define the backside of it somehow so that mr direct3d knows that also the red backside should be...rendered or something and therefore i need these 6 vertices for 4 triangles = 2 quads or something, back and front and so...wohooo...i think i got it!

thx jack, i love you! :D

[Edited by - Ryam BaCo on July 10, 2005 12:07:03 PM]

Share this post


Link to post
Share on other sites
Edit: Too slow! I'll leave my answer anyway, just in case it's useful [smile]

Quote:
Original post by Ryam BaCo
i interpret your post, that i need some vertices for the back side of my red quad, but...well...why?

It's due to backface culling. Direct3D, as an optimization, will remove any triangles that aren't facing the camera (controlled by the D3DRS_CULLMODE render state). Whether a triangle is back-facing or not is based on the order of the vertices, hence why for your 4 triangles the 2 pairs are defined in opposite orders...

So, given the rotation, beyond a certain point the triangles will appear to just disappear until they rotate far enough around to be visible again.

Change this line:
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 4);

To be:
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

run it again and you should spot that the red quad just disappears after a certain amount of rotation, but comes back again as it rotates around [smile]

However, if you also add the following line into your code (before the draw call would be okay):
g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

Run the program again and you'll see, magically, that the quad no longer disappears after a given rotation.

The blue quad does not have this problem because of the way it rotates - the backface of the triangles do not ever face the camera.

hth
Jack

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this