If you want to rotate an object around its center, you first have to translate it to the origin, then rotate and translate it back. Since transformation matrices affect your vectors from right to left, you have to code these steps in opposite order.
Here is some pseudocode since I don't know OpenGL routines by heart:
PushMatrix();
LoadIdentity(); // Start with a fresh matrix
Translate(); // Move your object to its final destination
Rotate(); // Apply rotations
Draw(); // Draw your object using coordinates relative to the object center
PopMatrix();
These matrices get applied:
v_t = (I * T * R) * v = (I * (T * (R * v)))
So the order is: Rotation, Translation.
EDIT: An explanation for the equation above.
The transformations rotation, scale and translation affect the model-view-matrix. Every 3D point (vector) of your model is multiplied by this matrix to get its final point in 3D space, then it gets multiplied by the projection matrix to receive a 2D point (on your 2D screen).
Ignoring the projection stuff, your point transformed by the model-view-matrix is:
v_t = MV * v
Meaning the original point v
, multiplied by the model-view-matrix MV
.
In the code above, we have constructed MV
by an identity matrix I
, a translation T
and a rotation R
:
MV = I * T * R
Putting everything together, you see that your point v
is first affected by the rotation R
, then the translation T
, so that your point is rotated before it is translated, just as we wanted it to be:
v_t = MV * v = (I * T * R) * v = T * (R * v)
Calling Rotate() prior to Translate() would result in:
v_t = (I * R * T) * v = R * (T * v)
which would be bad: Translated to some point in 3D, then rotated around the origin, leading to some strange distortion in your model.