Once I managed to get an entirely unimaginative red 2D triangle or three onto the screen in a few different ways, I knew that I had to expand into the 3rd dimension. To that end, I dropped back to a single 3D triangle, left it red, and prepared myself for what should be on the screen. A couple seconds of compiling and firing up the program revealed that while the triangle was in fact on my screen, it looked no different from my 2D version.
This is simply because by default OpenGL happily ignores the Z-Axis entirely. In the old fixed pipeline days, you could probably fix that by simply setting some configuration value or other to one that makes 3D stuff happen. In the fancy new shader pipeline you need to tell the card how to do that. That means passing a few matrices down with all of your fun geometry. In English, that means you need to tell the card how to use the Z-axis.
In one of the books I’m reading it was mentioned that OpenGL “is not a math library.” This is especially true with LWJGL. In C/C++ you can use the library mentioned by the book called vmath. In Java you are on your own. This fact has sent me down the multi-week long detour of crafting a math package of my own and making sure the tests for it prove it behaves the way math should.
The current list of things in my math library are as follows:
- For graphics:
- Vector2 – Vector of 2 floating points.
- Vector3 – Vector of 3 floating points.
- Vector4 – Vector of 4 floating points.
- For pixel level precision:
- IntVector2 – Vector of 2 integers.
- IntVector3 – Vector of 3 integers.
- IntVector4 – Vector of 4 integers.
- For transforms:
- Matrix33 – A 3×3 matrix of floating points.
- Matrix44 – A 4×4 matrix of floating points.
- Quaternion – Numbers in the form (a + bi + cj + dk) using floating point values.
- For fractals:
- ComplexNumber – Numbers in the form (a + bi) using floating point values.
This list is perhaps a bit larger than I needed with the goal of simply producing a a proper perspective projection matrix. I was however on a roll and my test cases provided actual evidence of progress which is nice to have sometimes when you feel a bit stalled in a project. I also created a little test program to see how well these things perform. Specifically how quickly I can multiply a Matrix44 by another Matrix44, and how fast multiplying a Matrix44 by a Vector4 was. I was satisfied with the numbers I was seeing so hopefully it will be enough.
As of right now, my test coverage tool tells me that around 89% of my math package is covered with tests. I am shooting for a perfect 100% for this package because if I can’t trust my math library, how can I know when I’ve built things that use it and have problems whether it’s the math that’s wrong or the thing I built on top of it?