So I created a vertex shader that takes in an angle and calculates the rotation. There is a problem though that the model rotates around the world center and not its own axis/origin.
Side note: This is 2D rotation.
How do I make the model rotate through its own axis?
Here is my current vertex shader:
#version 150 core
in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;
out vec4 pass_Color;
out vec2 pass_TextureCoord;
void main(void) {
gl_Position = in_Position;
pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
}
Rotating CPU side:
Vector3f center = new Vector3f(phyxBody.getPosition().x,phyxBody.getPosition().y,0);
Matrix4f pos = new Matrix4f();
pos.m00 = (phyxBody.getPosition().x)-(getWidth()/30f/2f);
pos.m01 = (phyxBody.getPosition().y)+(getHeight()/30f/2f);
pos.m10 = (phyxBody.getPosition().x)-(getWidth()/30f/2f);
pos.m11 = (phyxBody.getPosition().y)-(getHeight()/30f/2f);
pos.m20 = (phyxBody.getPosition().x)+(getWidth()/30f/2f);
pos.m21 = (phyxBody.getPosition().y)-(getHeight()/30f/2f);
pos.m30 = (phyxBody.getPosition().x)+(getWidth()/30f/2f);
pos.m31 = (phyxBody.getPosition().y)+(getHeight()/30f/2f);
pos.rotate(phyxBody.getAngle(),center);
Result is a weird rotated stretch of the object.. Do you know why? Don't worry about the /30f part.
EDIT:
Vector3f center = new Vector3f(0,0,0);
Matrix4f pos = new Matrix4f();
pos.m00 = -(getWidth()/30f/2f);
pos.m01 = +(getHeight()/30f/2f);
pos.m10 = -(getWidth()/30f/2f);
pos.m11 = -(getHeight()/30f/2f);
pos.m20 = +(getWidth()/30f/2f);
pos.m21 = -(getHeight()/30f/2f);
pos.m30 = +(getWidth()/30f/2f);
pos.m31 = +(getHeight()/30f/2f);
pos.rotate(phyxBody.getAngle(),center);
pos.m00 += phyxBody.getPosition().x;
pos.m01 += phyxBody.getPosition().y;
pos.m10 += phyxBody.getPosition().x;
pos.m11 += phyxBody.getPosition().y;
pos.m20 += phyxBody.getPosition().x;
pos.m21 += phyxBody.getPosition().y;
pos.m30 += phyxBody.getPosition().x;
pos.m31 += phyxBody.getPosition().y;
This is currently the transformation code, yet the rotation still doesn't work correctly.
My try at the rotate method: (What am I doing wrong?)
if (phyxBody.getAngle() != 0.0) {
pos.m00 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
pos.m01 *= Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m10 *= -Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m11 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
pos.m20 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
pos.m21 *= Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m30 *= -Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m31 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
}
The order is scaling * rotation * translation - see this question. I'm guessing you've already translated your coordinates outside of your shader. You'll have to rotate first, then translate. It's good to know the linear algebra behind what you're doing so you know why things work or don't work.
The typical way to do this is to pass a pre-computed ModelView matrix that has already taken care of scaling/rotation/translation. If you've already translated your vertices, you can't fix the problem in your shader without needlessly undoing it and then redoing it after. Send in your vertices untranslated and accompany them with data, like your angle, to translate them. Or you can translate and rotate both beforehand. It depends on what you want to do.
Bottom line: You must rotate before you translate.
Here is the typical way you do vertex transformations:
OpenGL side:
Calculate ModelView matrix: Scale * Rotation * Translation
Pass to shader as a uniform matrix
GLSL side:
Multiply vertices by ModelView matrix in vertex shader
Send to gl_Position
Response to Edit:
I'm inclined to think your implementation needs to be completely redone. You have points that belong to a model. These points are all oriented around the origin. For example, if you had a car, the points would form a mesh of triangles.
If you simply do not translate these points and then rotate them, the car will rotate around its center. If you translate afterwards, the car will translate in its rotated fashion to the place you've specified. The key here is that the origin of your model lines up with the origin of rotation so you end up rotating the model "around itself."
If you instead translate to the new position and then rotate, your model will rotate as if it were orbiting the origin. This is probably not what you want.
If you're modifying the actual vertex positions directly instead of using transformation matrices, you're doing it wrong. Even if you just have a square, leave the coordinates at (-1,-1) (-1,1) (1,1) (1,-1) (notice how the center is at (0,0)) and translate them to where you want to be.
You don't have to re-implement math functionality and probably shouldn't (unless your goal is explicitly to do so). GLM is a popular math library that does everything you want and it's tailored specifically for OpenGL.
Final Edit
Here is a beautiful work of art I drew for you demonstrating what you need to do.
Notice how in the bottom right the model has been swept out around the world origin about 45 degrees. If we went another 45, it would have its bottom edge parallel to the X-axis and intersecting the positive Y-axis with the blue vertex in the bottom left and purple vertex in the bottom right.
You should probably review how to work with vertices, matrices, and shaders. Vertices should be specified once, matrices should be updated every time you chance the scale, rotation, or position of the object, and shaders should multiply the each vertex in the model by a uniform (constant).