Simplify & gain speed

Here are some code from my display-routine:

glRotatef(xtick, 1.0f, 0.0f, 0.0f);
glRotatef(ytick, 0.0f, 1.0f, 0.0f);
glRotatef(ztick, 0.0f, 0.0f, 1.0f);

I have read in a book that I can use one 4x4 matrix to do rotation, scaling and transformation. Do this apply here?
Will I gain any speed?

I use glCallList() because I have thousands of triangles to calc in the object.

Regards Roland

Yes, you can use one matrix here. However, you must calculate them on your own. With standard “functions” like rotation about each of the three axes and then translation, you can do your own matrixmultiplication on paper (or in a mathprogram that can handle symbolic expressions), and use letters instead of numbers to create a… hmm what to call it… basematrix (?), where each element consists of a certain formula. Then all you have to do in your program is to calculate all 16 elements and place them in a float[16] array. Then use glLoadMatrix() to load you transformationmatrix.

This might be slightly faster then using gl-functions to create the same matrix. But I really don’t recomend doing this. It makes the code less readable, and the speedimprovement is VERY small. You are trying to gain a few (4) matrixmultiplications to create the transformationmatrix. And after that, you are doing THOUSANDS of multiplications. Remember that each vertex is muliplied with the modelviewmatrix and the projectionmatrix. If yor model contains 10.000 triangles (=30.000 vertices), you are trying to reduce the amount of multiplications from 60.004 to 60.000. And if you pass normals and texturecoordinates too… well… the amont will more be like 200.004 to 200.000.

Just out of curiosity, would it be worthwhile to precompute everything before you send it to the renderer. Not just building the modelview and projection matrices then passing them GL and letting it do all the work on all of the vertices.

Imagine this: with the pipeline you suggest, you create the modelview matrix (M), the projection matrix § and 30,000 vertices (v[1] to v[30000]). So the rendering goes roughly like: for(i=1;i<=30000;i++) Mv[i]; for(i=1;i<=30000;i++) Pv[i]; 60,000 multiplications, all done in GL.

What if you created a single transformation for the entire model (T), that described both the modelview and projection transformations. Then your rendering would be: for(i=1;i<=30000;i++) T*v[i]; 30,000 multiplications. Now if you wrote your own superfast matrix multiplication routine in asm or whatever, the calculations are all done in less than half the time.

Is there a reason to not do this? Or am I missing something (never had to deal with an API to make 3D graphics before, I probably just need a paradigm shift.)

the only reason to not do this is if you have a card that support hardware T&L. Otherwise it is worth it. But now with Ati and NVidia having a T&L solution and both releasing low end cards(coming soon for Ati) GeforceMX for Nvidia, there is no real reason to bother doing your own because T&L will become a standard(I believe!) very soon.

Indiana: I bet a good OGL driver will never do something like that:for(i=1;i<=30000;i++) Mv[i]; for(i=1;i<=30000;i++) Pv[i], but it will first multiply the two matrices together and then multiply each vertex with that matrix.

There is one MAJOR reason why you don’t create one matrix, the one called T above.

The mathematical result will be the same, there will be more or less half the amount of multiplications. BUT, lightning (and some more stuff I can’t remember now) is performed BEFORE projection, but AFTER modelview. How do you plan to solve this problem?

And another problem too. If you want to pop or reset you modelviewmatrix, you have to recalculate the T-matrix, and not just overwrite it.

Sorry, forgot to add…

There is no reason to create your own multiplicationroutine, and then pass pre-transformed_and_projected vertices, because OpenGL will multiply them anyway, unless you got a smart driver which know it’s not suppose to multiply if you got the identitymatrix loaded, or if you use some extension (think there is one) to pass vertices which is not multiplicated by either modelview nor projection. And you can’t gurantee that ALL implementation will have either this extension or the feature not to multiply.

Ooops, forgot that.

Hmmm, for lighting you can use the normals only. It’s not correct, but perhaps good enough. You can use ONE matrix to transform the vertices and TWO to do the lighting stuff. On an matrix push and pop you have to recalculate T ONE time which is most times cheaper than to multiply every vertex with two matrices. I’ll have to think about that more…

So basically if I had done that, GL would have mulitplied then all by the identity anyways, and I would have gained nothing, and run the risk of missing out on acceleration. Lovely.

Oh dear, converting this software renderer to OGL isn’t as simple as I thought it would be.

Then again what is these days.

As for using the one T matrix for transformations and the P and M for lighting: wouldn’t you be doing all of the lighting calculations in your program then, for each normal, instead of letting OGL take advantage of acceleration?

Hummm. Although I’m not sure of this, it’s not the drivers doing this so called optimization of premultiplying the Modelview and Projection matrixes together when aplicable. I’ve always just thought that that was part of the OpenGL pipeline since it makes sence. I can’t imagine the makers of a popular 3D api like openGL overlooking something like that. Assuming the makers of openGL were not morons this is already done and done faster than anyone except assembly masters could redo.

If anyone doubts me and is willing to spend a little time on the matter, I’m sure this is covered in the OpenGL specs.