Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL: Problem with triangle strips for 3d mesh and normals

I'm new to opengl programing. I'm currently making animation of cave shaft formation. I have a set of coordinats for profiles of the shaft along the z-axis. My plan is to make a 3d mesh from this data and to do that I've decieded to use TRIANGLE_STRIPS. The way I did this was that I've created multiple strips like this:

 11----12 5------6
 |   /  | |   /  |
 |  /   | |  /   |
 9-----10 3------4
 |   /  | |   /  |
 |  /   | |  /   |
 7------8 1------2

My questions are:

  1. Is this the right way to do it? Because now I have problems with normals. I would like to use GL_SMOOTH shading and for that as I understand I need to calculate normals of vertices? But in my cas vertex 10 and 3 are the same so there would be two normals??? Is that a problem? And is there any other way to create multiple strips?

  2. And is there any other way to create multiple strips? Or the solution with strips is maybe not the best one?

  3. Another problem is, that this strips are not of equal length. Some are shorter then others. Thank you for your help :)

like image 678
Diba Avatar asked May 31 '11 13:05

Diba


2 Answers

First, do not use triangle strips. It's and old concept for old hardware. Use simple indexed triangle lists. It is easier (at first) and faster. To your questions:

1) Every vertex has a normal. It is just as unique and important as the position. If two vertices had a different position they would be different vertices. The same applies to normals: There are vertices with the same position but with different normals. But they are different vertices. Think about how vertices off a sphere are different to vertices of a cube.

2) Use lists (glDrawElements). Do not use strips. There are optimal ways to order those lists for caching, nvidia and ati have plenty of example code in their developer sections.

3) Do not worry about that yet. A good mesh will have approximately equal area triangles. The indices are sorted to hit a vertex cache (usually at least 16 entries) most of the time. Strips are a way to optimize for a 2 entry vertex cache.

like image 156
starmole Avatar answered Sep 30 '22 09:09

starmole


First, in your picture, the diagonals are actually flipped, if the numbers represent the order of vertices (but that's a minor presentation error).

  1. This is the easiest and most times sufficient approach for stripping a more or less uniform grid of vertices. You are right, in that 10 and 3 need the same normal, so you need to give them the same normal for them to be lit correctly. In this case indexing is your friend. Just use a single vertex for 3 and 10 (with a corresponding normal) and use an indexed triangle strip, where index 3 and 10 reference the same vertex. This is the standard way in resolving vertex ambiguities. If you don't know what I mean, delve a little deeper into OpenGL and 3D programming in general, especially vertex and index arrays.

  2. For regular grids, strips are often a good idea, because they can be constructed quite easily. For more complex meshes it isn't really needed anymore nowadays, as it is often more important to reduce the number of draw calls.

  3. They should have at least a reasonable length compared to the overall number of triangles, otherwise the overhead of drawing a single strip just outweights the time spared by the slightly faster vertex processing, but actual numbers are highly implementation dependent. You should use vertex arrays/buffers anyway, stay away from begin/end if you care for performance.

You can actually merge multiple strips into one by introducing degenerate triangles that aren't rendered (to reduce the number of draw calls). Your example can be rendered as the following single strip:

1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12

But again, keep answer 3. in mind. The strips should have a reasonable size so that the degenerate triangles don't outweight the real triangles too much.

like image 44
Christian Rau Avatar answered Sep 30 '22 10:09

Christian Rau