Bringing some of the missing plugins to Modern OpenGL builds

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:

I made a branch in launchpad with a working OpenGL|ES port of firepaint.

I have a question about coding style: are std::vectors always preferable to arrays? Generally, are there any guidelines about which C++ features should be used and when? (I looked at http://wiki.compiz.org/Development/CodingStyle)

I didn’t see a merge proposal for your branch. Do you think you might be able to do that? I will be able to see it even if you set it to “Work in Progress”

Great to see you’ve ported it – the coding style document really only indicates the usage of whitespace and other such things, but doesn’t say anything about language features.

The generally accepted view on vectors is to use them where it makes sense to – eg, if you can have an array with a fixed size, which will always be full, then it makes sense to use arrays. If the array has a dynamic size, or the size might change, then a vector makes sense.

Generally speaking there is very little difference between the two in terms of performance.