Daily Archives: December 26, 2012

When we merged in OpenGL|ES support for compiz, we didn’t have the resources to continue maintenance of some of the plugins which were were more complicated in their OpenGL usage. As such, those plugins were disabled for building until a later time.

I’ve taken some of my spare time to make the cubeaddon plugin work with the new OpenGL API.

I figure the sphere-deformation was the one people have asked me for the most, so I decided to go with that one. It was a good learning experience too – I’ve always wanted to know how the mathematics of the spherical deformation actually works. You can see how with the wireframe render below:

Or with a reduced mesh size:

The window deformation is complicated to explain, but the caps are quite simple. We use a TRIANGLE_FAN primitive to render the very tips of the sphere, like this:

Once you have that, you just render quads (or a TRIANGLE_STRIP with primitive restart for newer OpenGL versions) for the curvature until the windows are reached:

In this reduced-resolution version, two quads are rendered per cube face, so we only submit eight vertices each time we render, but the texture co-ordinate planes and object transformation matrices are rotated each time. This gives us our full image.

Other interesting parts

Some other fun parts were to remove fixed-function pipeline usage and replace it with client side or shader equivalents. For example, cubeaddon used this code:

Texture co-ordinate generation with GL_OBJECT_LINEAR just takes the dot product of the object vertex and texture plane.

Another challenge was the usage of glDrawElements

glDrawElements (GL_QUADS, CAP_NIDX, GL_UNSIGNED_SHORT,
mCapFillIdx);

glDrawElements uses a technique called index buffer objects, which is a clever optimization to prevent sending the GPU a lot of geometry. Instead of uploading lots of vertices which might overlap (you saw this in my diagrams earlier, it was often the case that v3 and v1 overlapped each other), you send OpenGL an array of unique vertices, then send it an array of indicies which reference which vertex in the vertex buffer should be drawn next. So for example you might have: