Skip to content

GLU Hacks

Recently I have been playing with GLU library and I was annoyed with GLU’s (in)ability to take only arrays of double values as input. If you have arrays of floats (or maybe ints) as I did, you have to make workaround to pass those to GLU – or abandon the idea and use doubles all the way.

Just for fun I decided to take a look at GLU code, which I know since before, was available from SGI and see if I can change this. SGI’s code turns to be a messy combination of Perl scripts and C/C++ code so next stop was Mesa, which is software implementation of OpenGL.

Mesa developers seems to already have processed SGI’s code, and made it quite straightforward to use, even with free VS Express, so that is code I have used. I have just further reorganized their VS project files, and made it more independent from the rest of mesa code. Zipped code is available for download here.

So what did I do to GLU?

Hack #1

… was to add more flexible interface in regard of input. It turned to be more work that I thought would be, but it wasn’t impossible to do. I have added following functions to GLU interface:

void gluTessVertex2i (GLUtesselator* tess, GLint *location, GLvoid* data);
void gluTessVertex2f (GLUtesselator* tess, GLfloat *location, GLvoid* data);
void gluTessVertex2d (GLUtesselator* tess, GLdouble *location, GLvoid* data);

void gluTessVertex3i (GLUtesselator* tess, GLint *location, GLvoid* data);
void gluTessVertex3f (GLUtesselator* tess, GLfloat *location, GLvoid* data);
void gluTessVertex3d (GLUtesselator* tess, GLdouble *location, GLvoid* data);

I have just followed standard parlance of OpenGL, and as you guess those correspond to gluTessVertex, but takes arrays of 2 integers, 2 floats and so on as input (gluTessVertex takes as input only array of 3 doubles). In case of 2-value arrays (2d geometry), the third coordinate is implicitly set to 0 by the library.

One thing to note, which might slip at first sight, is that one has to match data passed to gluTessVertex* in combine and vertex callbacks. Vertex data that you get back from combine callback is still in double precision, since internals of the library have not changed. It still produces new vertices in double precision, which have to be converted to floats (or ints) for vertex callback. See examples (tess2 and tess3) in zipped code to get it clear.

Hack #2

While I was looking to make code above working, I noticed that code can be made more effective when working in 2d. To start with, there is very nice explanation of the algorithm used, included in the code by original author (I think):

Phases of the algorithm
1. Find the polygon normal N.
2. Project the vertex data onto a plane. ( … )
3. Using a line-sweep algorithm, partition the plane into x-monotone regions. ( … )
4. Triangulate the x-monotone regions.
5. Group the triangles into strips and fans.

From the phases of the algorithm it is clear we can omit steps 1 and 2 when working in 2d space. If we never specify the third coordinate, we are implicitly saying that polygons are in same plane (say z = 0). Original algorithm does not count for this.

There is already built-in way to omit calculation of normal – just use gluTessNormal funtion. To make it possible to omit step 2, I have added a new property called GLU_TESS_DONT_PROJECT, which can be set as other GLU properties, with gluTessProperty function. By setting it to GL_TRUE, one guarantees that all vertices of a polygon are in the same plane and enables the algorithm to skip projection.

All changes are done in glu.h, tess.h and tess.c.

Note that those hacks are done for my own use. I have tryed to make project files and original code as self-enclosed as possible; hopefully there are no dependencies outside code of the project. Also the code is not extensively tested, so there will be bugs. If you find them, plaese drop a note. Also it would be nice to hear opinions if you find this useful or have suggestion for further improvement.

Just to make this page a bit more colorful below are screenshots from tests (source is included in download):

Download zipped source.

Post a Comment

Your email is never published nor shared. Required fields are marked *