In an effort to learn things deeper I'm writing my own mathematics for the first time instead of using libraries. As far as I can tell my matrix multiplication is correct, and translation and scaling work fine. I am however, struggling to debug the rotations. I've tried pretty much everything I can think to check and it still won't function as expected. If I set the angle to zero then as expected the Model matrix will not be effected. Changing to 1.0f will explode, the only value which results in expected behaviours seems to be zero... I haven't written a view matrix yet and I've been trying to debug this with the projection(orthographic) matrix on and off. Below is code with some notes.
Matrices are linear arrays of 16 values. i32 is an int, f32 is float, internal is static.
inline m4x4 operator*(m4x4 a, m4x4 b){
//TODO redo this with simd
m4x4 Result = {};
for (i32 Row = 0; Row <= 3; ++Row)
{
for (i32 Col = 0; Col <= 3; ++Col)
{
for (i32 n = 0; n <= 3; ++n)
{
Result.c[(Row * 4) + Col] += a.c[(Row * 4) + n] * b.c[4 * n + Col];
}
}
}
return (Result); }
inline m4x4 GetRotationZ(f32 angle) {
m4x4 Result;
f32 c = Cos(angle);
f32 s = Sin(angle);
Result = { c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
return (Result); }
inline m4x4 RotateZ(m4x4 m, f32 angle) {
m4x4 Rotation = GetRotationZ(angle);
m4x4 Result = Rotation * m;
return (Result); }
internal void DrawSprite(sprite Sprite, v2 Position, v2 Size, f32 RotationAngle, v3 Colour) {
glUseProgram(Sprite.ShaderProgram);
glBindVertexArray(Sprite.VAO);
#if 0
Position = v2{400, 300};
Size = v2{100.0f, 100.0f};
RotationAngle = 0.0f;
#endif
#if 0
m4x4 Projection = Orthographic(0.0f, 800.0f, 0.0f, 600.0f, -1.0f, 1.0f);
u32 ProjectionUniformID = glGetUniformLocation(GlobalSprite.ShaderProgram, "Projection");
glUniformMatrix4fv(ProjectionUniformID, 1, GL_TRUE, &Projection.c[0]);
#endif
m4x4 Model = IdentityMatrix();
Position.x = Position.x * 0.01f;
Position.y = Position.y * 0.01f;
Model = Translate(Model, V3(Position, 0.0f));
Model = Translate(Model, v3{0.5f * Size.x, 0.5f * Size.y, 0.0f});
//Model = RotateZ(Model, RotationAngle);
Model = RotateZ(Model, 45.0f);
Model = Translate(Model, v3{-0.5f * Size.x, -0.5f * Size.y, 0.0f});
Size = v2{0.25, 0.25};
Model = Scale(Model, V3(Size, 1.0f));
u32 ModelUniformID = glGetUniformLocation(Sprite.ShaderProgram, "Model");
glUniformMatrix4fv(ModelUniformID, 1, GL_TRUE, &Model.c[0]);
glDrawArrays(GL_TRIANGLES, 0, 6); }
Next the shader source
char *VertexShaderSource = R"(
#version 330 core
layout (location = 0) in vec4 PositionAndTextureCoords;
uniform mat4 Model;
uniform mat4 Projection;
out vec2 TexCoords;
void main()
{
TexCoords = vec2(PositionAndTextureCoords.zw);
//gl_Position = vec4(PositionAndTextureCoords.xy, 0.0f, 1.0f);
//gl_Position = Model * vec4(PositionAndTextureCoords.xy, 0.0f, 1.0f);
//gl_Position = Projection * Model * vec4(PositionAndTextureCoords.xy, 0.0f, 1.0f);
gl_Position = Model * vec4(PositionAndTextureCoords.xy, 0.0f, 1.0f);
}
)";
char *FragmentShaderSource = R"(
#version 330 core
in vec2 TexCoords;
uniform sampler2D Texture;
out vec4 FragColour;
void main()
{
FragColour = texture(Texture, TexCoords);
}
)";
I've stepped through the debugger, I've checked every line of code again and again, I've worked through a few matrices by hand and still I don't know whats going wrong. It should be something so very trivial yet I can't seem to find the bug...
Below are pictures demonstrating the difference between 0.0f and 1.0f, as of this state of the code it not only skews and rotates incorrectly, but its scaling is well off as well.