How to avoid redundant transformations

Suppose I want to draw a square plane built of many triangles (heavily tesselated).
As of my current knowledge of OpenGL the best way to do that is to use triangle strips (one triangle strip per 1 row of triangles in plane).
However, this means that each nonedge vertex of plane will be specified 2 times.
No matter if I’m using vertex arrays or glVertex calls OpenGL transforms and lights these vertices twice.
This makes the performance suffer badly.
If I used triangle lists instead of triangle strip each vertex would be specified 6 times (on average) making performance totally unacceptable.

Does anybody know how to make OpenGL calculate and light vertices only ONCE?

I don’t think that you can rescue performance in any way. Even when you use triangle strips, that doesn’t mean that the number of vertixes are less than when you use independent triangles. because the OpenGL interpreter will interprete this code:

glBegin(GL_TRIANGLE_STRIP);

glVertex3dv(&V1);
glVertex3dv(&V2);
glVertex3dv(&V3);
glVertex3dv(&V4);

glEnd();

into this equivalent code:

glBegin(GL_TRIANGLEs);

glVertex3dv(&V1);
glVertex3dv(&V2);
glVertex3dv(&V3);

glVertex3dv(&V3);
glVertex3dv(&V2);
glVertex3dv(&V4);

glEnd();

[This message has been edited by softland_gh (edited 12-22-2000).]

Originally posted by softland_gh:
[b]I don’t think that you can rescue performance in any way. Even when you use triangle strips, that doesn’t mean that the number of vertixes are less than when you use independent triangles. because the OpenGL interpreter will interprete this code:

glBegin(GL_TRIANGLE_STRIP);

glVertex3dv(&V1);
glVertex3dv(&V2);
glVertex3dv(&V3);
glVertex3dv(&V4);

glEnd();

into this equivalent code:

glBegin(GL_TRIANGLEs);

glVertex3dv(&V1);
glVertex3dv(&V2);
glVertex3dv(&V3);

glVertex3dv(&V3);
glVertex3dv(&V2);
glVertex3dv(&V4);

glEnd();

[This message has been edited by softland_gh (edited 12-22-2000).][/b]

Sorry, but this is completely wrong.
If the OpenGL hardware (or software, in general the driver) is capable of processing triangle strips it will not split strips, but make excellent reuse of the already transformed and lit verices. You can easily test that with the given example of a huge mesh.

It’s even possible to make reuse of alrady issued vertices if they are given as indices into arrays.
For some more performanc options check out http://www.nvidia.com/Marketing/Developer/DevRel.nsf/FAQ_Frame?OpenPage

You should be able to reuse the vertices by using Vertex Arrays and using the glDrawElements call, which takes an index list. Using this technique you should only need to specify your vertex once in the vertex array but access it as many times as required via the index array. This should prevent any unwanted transforms.

Thank you Relic for correcting me. Anyway, the performance boost one may get form triangle strips depends on hardware and the driver. So, it’s not always guaranteed that performance will improve if one used triangle strips. Right? Vertex arrays sound to be a great solution, though.

Triangle strips are virtually guaranteed to be a speedup.

  • Matt

Originally posted by daveg:
You should be able to reuse the vertices by using Vertex Arrays and using the glDrawElements call, which takes an index list. Using this technique you should only need to specify your vertex once in the vertex array but access it as many times as required via the index array. This should prevent any unwanted transforms.

Sorry, but every time I specify vertex index using glDrawElements call this vertex is transformed and lit once again. If OpenGL was to calculate vertex in vertex array only once, it would have to:

a) remember transformed and lit vertex parameters in some structures (OpenGL 1.1 spec says nothing about that)

b) keep track of all rendering context modifications and discard already transformed / lit vertices if it changes (If I change matrices or light parameters previously transformed/lit vertices are invalid).

As for my best knowledge OpenGL does not do that. At least with Voodoo 3 and GeForce using latest drivers - drawing plane using triangles is almost exactly 3 times slower than using triangle strips (when window size is very small and rasterization does not take too much time). This means that every vertex is calculated SIX times (triangles) instead of TWO times (triangle strips). But I want it to be calculated ONCE.
In DirectX (starting with version 7.0) there is a function called ProcessVertices() that calculates all given vertices once and then you can draw as much primitives as you want without any more transforms. Is there any OpenGL extension that allows for the same?

I’m not sure, but maybe compiled display lists may make performance even better.