I’ve been trying to convert over to “modern” OpenGL, and one of the first steps I took was to try to figure out how to use matrices and specifically model the glm library. I honestly had to research and stitch code together a lot, so that’s probably my issue. But I don’t know enough about matrices to even try to guess what’s wrong!
So, I tried to create a function similar to the glm::perspective one. It is quite simply this:
public static Matrix4f perspective(float fovy, float aspect, float zNear, float zFar) {
final float halfFov = (float) Math.toRadians((fovy / 2.0f));
final float range = (float) Math.tan(halfFov) * zNear;
final float left = -range * aspect;
final float right = range * aspect;
final float bottom = -range;
final float top = range;
Matrix4f res = new Matrix4f();
res.m00 = (2 * zNear) / (right - left);
res.m11 = (2f * zNear) / (top - bottom);
res.m22 = -(zFar + zNear) / (zFar - zNear);
res.m23 = -1f;
res.m32 = -(2f * zFar * zNear) / (zFar - zNear);
return res;
}
And then I tried to create a glm::lookAt function:
public static Matrix4f lookAt(Vector3f eye, Vector3f center, Vector3f up) {
Vector3f f = new Vector3f(), u = new Vector3f(), s = new Vector3f();
Vector3f.sub(center, eye, f);
up.normalise(u);
Vector3f cross = Vector3f.cross(f, u, s);
cross.normalise(s);
Vector3f.cross(s, f, u);
Matrix4f res = new Matrix4f();
res.m00 = s.x;
res.m10 = s.y;
res.m20 = s.z;
res.m01 = u.x;
res.m11 = u.y;
res.m21 = u.z;
res.m02 = -f.x;
res.m12 = -f.y;
res.m22 = -f.z;
return res;
}
I then use it like this:
projection = MatrixUtils.perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.0f);
view = MatrixUtils.lookAt(new Vector3f(0, 0, 0), new Vector3f(0, 0, -1), new Vector3f(0, 1, 0));
model = new Matrix4f();
(Model being a “identity” matrix.)
I then pass all those matrices into my shaders, and I multiply them together:
layout(location = 0) in vec3 pos;
uniform mat4 projection, view, model;
void main()
{
gl_Position = (projection * view * model) * vec4(pos, 1);
}
My issue is that I try to use the Matrix4f.translate function to translate the geometry. But, instead of actually translating, the vertices simply “rotate” around a point, which actually seems to be the “Z-axis”. Here’s a picture to clarify what I mean:
This is the square being drawn “unmodified (no translations)”:
And then, I just add this line of code:
Matrix4f.translate(new Vector2f(1, 0), model, model);
Which results in this:
I expected the square to just move over to the left of the screen, but it looks as if it has rotated somehow and stretched itself. Here is the entire class:
public class World {
private Matrix4f projection, view, model;
private Shader shader;
private int vertexBuffer = 0, vbo = 0;
float[] vData = {
// Left bottom triangle
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
// Right top triangle
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
private FloatBuffer buffer;
public World() {
projection = MatrixUtils.perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.0f);
view = MatrixUtils.lookAt(new Vector3f(0, 0, 0), new Vector3f(0, 0, -1), new Vector3f(0, 1, 0));
model = new Matrix4f();
Matrix4f.translate(new Vector2f(1, 0), model, model);
shader = new Shader("/shaders/basic.vert", "/shaders/basic.frag");
shader.addUniform("projection");
shader.addUniform("view");
shader.addUniform("model");
buffer = Utils.createFloatBuffer(vData.length);
buffer.put(vData);
buffer.flip();
vertexBuffer = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vertexBuffer);
vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
public void update() {
}
public void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
shader.use();
shader.setUniformMat("projection", projection);
shader.setUniformMat("view", view);
shader.setUniformMat("model", model);
GL30.glBindVertexArray(vertexBuffer);
GL20.glEnableVertexAttribArray(0);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 2 * 3);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
(Please excuse the mess!)
Does anyone have idea what I could be doing wrong?