syntax-highlighter

Saturday, November 19, 2011

4x4 transformation matching OpenGL

An updated version of this code is available on Github, removing the need for an external linear algebra library to compute matrix inverses, although the remainder of this post is still valid. Please see: http://jamesgregson.blogspot.ca/2013/09/updated-4x4-transformation-matching.html to get the updated code.

Several times now I've wanted to develop/debug graphics applications which involve 3D transformations and visualize the results with OpenGL. I usually end up just using the OpenGL matrix functions like glRotatef(...), glFrustum(...) for everything in order to have consistent transformations between the debugging view and the underlying app.

This works OK, however it means that a valid OpenGL context is available, since many of these functions don't work properly without one. To avoid this, I have duplicated most of the OpenGL functions in a custom 4x4 transformation class, which produces nearly identical results (usually to within 10-6 -> 10-4) but which does not require a context. It also exposes some extra operations, such as transposition and inversion along with the GLU functions gluProject, gluUnProject and gluPerspective. These make it quite easy to duplicate the OpenGL vertex transformation pipelines in custom, non-OpenGL code.

For example:

// example code to pan a view

// declare some variables, grab an OpenGL matrix
double mat[16];
transformation T;
glGetDoublev( GL_MODELVIEW_MATRIX, mat );

// load mat into T
T.from_opengl( mat );

// pan the view 
T = transformation::glTranslate( dx, dy, 0.0 ) * T;

// convert back to OpenGL format and update 
T.to_opengl( mat );
glLoadMatrixd( mat );


Currently the library includes the following OpenGL/GLU functions:

transformation::glIdentity(...)
transformation::glScale(...)
transformation::glTranslate(...)
transformation::glRotate(...)
transformation::glOrtho(...)
transformation::glFrustum(...)
transformation::gluPerspective(...)
transformation::gluProject(...)
transformation::gluUnProject(...)

All of these have been tested against the OpenGL/GLU equivalents, and have matching interfaces except they return a transformation rather than operate on the active matrix stack. There are also a number of additional functions to transpose/invert transformations, access individual elements and get the right/up/forward/position vectors from a transformation.

The code is available to download Github:

https://github.com/jamesgregson/transformation

I hope people find it useful. I will be updating the code with any bug-fixes or improvements over time, please send them my way if you have a suggestion or a problem.

No comments: