First of all we would like our icosahedron to rotate around itself. To do so, we save the current transformation matrix using glPushMatrix and then apply a rotation before drawing the actual object. The following code saves the matrix, rotates the origin by a variable angle on all three axes and then draws an icosahedron using the glut function glutIcosahedron.
glPushMatrix();
glRotatef(angle,1.0,1.0,1.0);
glutSolidIcosahedron();
glPopMatrix();
Now, we would like to add two toruses which will rotate around the icosahedron on all three axes but in opposite directions. To make the toruses follow the icosahedron, this code should go inside the "current matrix" just after the glutSolidIcosahedron call.
To draw two rotating toruses we can either save the matrix, rotate, draw the first torus, reload the saved matrix and rotate the second one in the opposite direction or just rotate the first one and then rotate the second one twice in the opposite direction. Transformations are cumulative; when we rotate the second torus twice in the opposite direction, the first time we cancel the previous rotation (10 degrees + (– 10 degrees) equal zero), and the second we rotate an equal amount of degrees in the opposite direction.
This is much faster than saving and reloading the matrices, as every time OpenGL saves and load a matrix several multiplication and additions happen behind the scenes, slowing down the application.
Thus, the complete system of two toruses and an icosahedron can be written as:
glPushMatrix();
glRotatef(angle,1.0,1.0,1.0);
glutSolidIcosahedron();
glRotatef(angle, 1.0, 1.0, 1.0);
glutSolidTorus(0.2, 1.0, 10, 10);
glRotatef(-2*angle, 1.0, 1.0, 1.0);
glutSolidTorus(0.2,1.0,10,10);
glPopMatrix();
In order to save space in this tutorial and make our program more modular we can replace the previous code block with a function, named for example createIcoToruses(). please note that the actual implementation of this function contains some extra code to color the icosahedrons and toruses.