Regardless, of my inability to copy data legibly I can still explain the core of what needs done. OpenGL uses matrix math to perform transformations on your models. These transformations are what allows in to move around on the screen. So let's talk about matrix math.
I don't really want to explain how to perform math operations with matrices; there are lots of places you can go to learn that. All of transformations are done via matrix multiplication, as I've shown in the past (link to most basic shaders?) GLSL can handle this very easily for us. My concern in this post is how matrices and the multiplication thereof are useful in OpenGL's 3D rendering.
The only note I want to give on matrix mathematics, is that multiplication of matrices is not commutative. If you have two matrices A and B then A * B does note equal B * A. Supposedly matrix multiplication is associative; if you have three matrices A, B, and C then (A * B) * C does equal A * (B * C). I'm not sure if that is true for how OpenGL treats these transformations or not, so I would caution you to be very particular about the order you do the math.
You can do multiplication with any old matrix, but it's hard to make use of the results if you use random numbers. Instead let's take a look at some specific matrix formats which will do specific and useful things when multiplied with vertex coordinates.

1: mat4 m4Identity;
2: m4Identity = mat4(1.0);
Let's sat that we want to move our vertex in 3D space. We can do that by multiplying the coordinates with a translation matrix. Just set X, Y, and Z to the distance you want the vertex to move along that axis.
1: mat4 m4Translate;
2: m4Translate = mat4(1.0);
3: m4Translate[0][3] = x;
4: m4Translate[1][3] = y;
5: m4Translate[2][3] = z;
1: mat4 m4Scaling;
2: m4Scaling = mat4(1.0);
3: m4Scaling[0][0] = x;
4: m4Scaling[1][1] = y;
5: m4Scaling[2][2] = z;
Here is where we need to start being careful about the order we multiply things. What this does is multiple each coordinate by the scaling factor. If our model is currently at the origin (centered on coordinate 0, 0, 0) then this works fine and it will scale correctly. However, if we've translated the matrix then we'll also be multiplying that translation. The result will be a larger version of our model pushed even further from the center, and this probably isn't what you want. Bottom line, do your scaling before any translations.
If we'd like to spin our model around we'll have to multiply each vertex by one of the three rotation matrixes. Just like with scaling you can rotate around any of the three axes. You just need to set a to the amount of rotation in radians.
![]() |
![]() |
![]() |
Rotate around the X axis | Rotate around Y axis | Rotate around Z axis |
1: m4RotateX = mat4(1.0);
2: m4RotateX[1][1] = cos(XAngle);
3: m4RotateX[1][2] = -1 * sin(XAngle);
4: m4RotateX[2][1] = sin(XAngle);
5: m4RotateX[2][2] = cos(XAngle);
6:
7: m4RotateY = mat4(1.0);
8: m4RotateY[0][0] = cos(YAngle);
9: m4RotateY[0][2] = sin(YAngle);
10: m4RotateY[2][0] = -1 * sin(YAngle);
11: m4RotateY[2][2] = cos(YAngle);
12:
13: m4RotateZ = mat4(1.0);
14: m4RotateZ[0][0] = cos(ZAngle);
15: m4RotateZ[0][1] = -1 * sin(ZAngle);
16: m4RotateZ[1][0] = sin(ZAngle);
17: m4RotateZ[1][1] = cos(ZAngle);
Just like with the scaling you need to be careful of the order you do the rotating. If the model is centered around the origin, then it will spin in place. If you translate the model first then it won't spin, instead it will follow a path orbiting around the axis. Depending on which effect you want, you'll need to be careful to translate or rotate first.
To sum up all this, when you want to move your model around you just have the shader multiply each vertex by one of more of these matrices. You'll want to have your model start centered on the origin (coordinate 0, 0, 0), then multiply by the scaling matrix, then use rotation matrices to spin the model, and last a translation matrix to move the model. Then your model will be correctly positioned in 3D space. Finish up my multiplying the projection matrix to account for depth of vision and you're all done.
To do animation it's simply a lot more of this. You just render each scene with the translation matrices changed slightly so that it's position on screen is changed. So long as you do all this at something close to 30 frames per second it'll look like motion.
No comments:
Post a Comment