# OpenGL [LWJGL3] - Matrix4x4 not rotating correctly

I tried today to make my own matrix4f class because of that LWJGL 3 does not include a class for it. So I arrived at rotation and it does not seem to work. I tried using the old util from LWJGL 2 and then it worked fine. Here's a screenshot of how it looks like.

Here's a gif animation of how it looks. It's supposed to be a cube but as you can see it stretches when it rotates. Not only the x axis but the y and z axis to. Here's the code:

public Matrix4f rotate(Vector3f rotation) {
Matrix4f xRotation = new Matrix4f();
xRotation.setIdentity();

float x = rotation.x;
float y = rotation.y;
float z = rotation.z;

xRotation.m11 = (float) cos(x);
xRotation.m21 = (float) -sin(x);

xRotation.m12 = (float) sin(x);
xRotation.m22 = (float) cos(x);

Matrix4f yRotation = new Matrix4f();
yRotation.setIdentity();

yRotation.m00 = (float) cos(y);
yRotation.m20 = (float) sin(y);

yRotation.m02 = (float) -sin(y);
yRotation.m22 = (float) cos(y);

Matrix4f zRotation = new Matrix4f();
zRotation.setIdentity();

zRotation.m00 = (float) cos(z);
zRotation.m10 = (float) -sin(z);

zRotation.m01 = (float) -sin(z);
zRotation.m11 = (float) cos(z);

return multilpy(xRotation).multilpy(yRotation).multilpy(zRotation);
}


Can someone point the problem because I cannot find it.

Edit: The multiplication and the projection code:

public Matrix4f multilpy(Matrix4f matrix) {
// Row 0
m00 = m00 * matrix.m00 + m10 * matrix.m01 + m20 * matrix.m02 + m30 * matrix.m03;
m10 = m00 * matrix.m10 + m10 * matrix.m11 + m20 * matrix.m12 + m30 * matrix.m13;
m20 = m00 * matrix.m20 + m10 * matrix.m21 + m20 * matrix.m22 + m30 * matrix.m23;
m30 = m00 * matrix.m30 + m10 * matrix.m31 + m20 * matrix.m32 + m30 * matrix.m33;

// Row 1
m01 = m01 * matrix.m00 + m11 * matrix.m01 + m21 * matrix.m02 + m31 * matrix.m03;
m11 = m01 * matrix.m10 + m11 * matrix.m11 + m21 * matrix.m12 + m31 * matrix.m13;
m21 = m01 * matrix.m20 + m11 * matrix.m21 + m21 * matrix.m22 + m31 * matrix.m23;
m31 = m01 * matrix.m30 + m11 * matrix.m31 + m21 * matrix.m32 + m31 * matrix.m33;

// Row 2
m02 = m02 * matrix.m00 + m12 * matrix.m01 + m22 * matrix.m02 + m32 * matrix.m03;
m12 = m02 * matrix.m10 + m12 * matrix.m11 + m22 * matrix.m12 + m32 * matrix.m13;
m22 = m02 * matrix.m20 + m12 * matrix.m21 + m22 * matrix.m22 + m32 * matrix.m23;
m32 = m02 * matrix.m30 + m12 * matrix.m31 + m22 * matrix.m32 + m32 * matrix.m33;

// Row 3
m03 = m03 * matrix.m00 + m13 * matrix.m01 + m23 * matrix.m02 + m33 * matrix.m03;
m13 = m03 * matrix.m10 + m13 * matrix.m11 + m23 * matrix.m12 + m33 * matrix.m13;
m23 = m03 * matrix.m20 + m13 * matrix.m21 + m23 * matrix.m22 + m33 * matrix.m23;
m33 = m03 * matrix.m30 + m13 * matrix.m31 + m23 * matrix.m32 + m33 *    matrix.m33;

return this;
}

public static Matrix4f perspective(int width, int height, int fov, float zFar, float zNear) {
Matrix4f matrix = new Matrix4f();

float aspectRatio = (float) width / (float) height;
float fovY = (float) ((1f / tan(Math.toRadians(fov / 2f))) * aspectRatio);
float fovX = fovY / aspectRatio;
float frustum_length = zFar - zNear;

matrix.m00 = fovX;
matrix.m11 = fovY;
matrix.m22 = -((zFar + zNear) / frustum_length);
matrix.m23 = -1;
matrix.m32 = -((2 * zNear * zFar) / frustum_length);
matrix.m33 = 0;

return matrix;
}


#version 400 core

in vec3 position;
in vec2 textureCoord;

out vec2 textureCoords;

uniform mat4 tranformation;
uniform mat4 projection;

void main(void) {

gl_Position =  projection * tranformation * vec4(position,1.0);

textureCoords = textureCoord;
}


#version 400 core

in vec2 textureCoords;

out vec4 out_Color;

uniform sampler2D sampler;

void main(void) {
vec4 color = texture(sampler, textureCoords);

//if(color.a < 0.5) discard;

out_Color = texture(sampler, textureCoords);
}

• Why are there three multilpy() calls in the end? – sam hocevar Apr 25 '16 at 6:37
• @samhocevar so the rotation is applied to the matrix – Daan Meijer Apr 25 '16 at 9:00
• Your code looks fine (at least the logic is correct); there may be a problem with other parts of your code. Maybe the multiplication part? Or where you compute the projection? – sam hocevar Apr 25 '16 at 10:35
• @samhocevar added the code for the projection and the multiplication – Daan Meijer Apr 25 '16 at 10:49
• I hate this m00, m01, m02, m12, etc. approach to matrices. Arrays does exist – Bálint Apr 25 '16 at 10:55

The problem is your multiplication code. When you do:

m00 = m00 * matrix.m00 + m10 * matrix.m01 + m20 * matrix.m02 + m30 * matrix.m03;


You change m00, so you are not allowed to reuse it later in that function. Same for m01 and all the other ones. Use temporary values instead:

float temp_m00 = m00 * matrix.m00 + m10 * matrix.m01 + m20 * matrix.m02 + m30 * matrix.m03;


Also, as suggested in the comments, try to use arrays instead of the m00 m01 etc. notation; you will have much shorter code and it will be easier to debug.

• Do I have to use this at only m00 or multiple? – Daan Meijer Apr 25 '16 at 11:42
• @Daan Meljer on each – Bálint Apr 25 '16 at 12:13
• @DaanMeijer the fact that you ask this question means that writing a correct matrix class is going to be a challenging task for you. If you wish to carry on, I highly recommend that you use unit tests all along, for instance with JUnit. – sam hocevar Apr 25 '16 at 13:18
• @samhocevar Ill check it out, and yes indeed I just started with matrix math, do you have a good tutorial on matrix math? Btw thanks for helping me. – Daan Meijer Apr 25 '16 at 13:43
• @samhocevar I have a question. what is the matrix field supposed to be(matrix.m00)? Is it all the rotations matrices multiplied together or something else? – Daan Meijer Apr 25 '16 at 14:17

Your z rotation is messed up, it should be negative at (0; 1), and positive at (1; 0)

• I changed that part of the code and it seems a bit better but its still streching here's how it looks: giphy.com/gifs/1127CCJy2YcE12 – Daan Meijer Apr 25 '16 at 11:09