Hello,
I’m currently working on a 2D game, for which I don’t use any library more than LWJGL.
I’m working with OpenGL 3.3.0, so I’ve got to make my own matrices to render things.
I use a Orthogonal Projection, but I’ve got some troubles when moving the camera, from left to right, and up to down (and vice-versa).
In fact, more than ‘displacing’ objects, it does that :
So here’s my Camera.java file :
package com.poulpicious.engine.graphics;
import com.poulpicious.engine.maths.Matrix4f;
import com.poulpicious.engine.maths.Vector2f;
import com.poulpicious.engine.maths.Vector3f;
public class Camera {
private float viewportWidth, viewportHeight;
private Shader shader;
private Vector3f position;
private Vector3f rotation;
private Matrix4f projection;
private Matrix4f rotationMatrix;
private Matrix4f translationMatrix;
private Matrix4f combined;
public Camera(float viewportWidth, float viewportHeight) {
projection = new Matrix4f().initOrthographic(-viewportWidth / 2, viewportWidth / 2, -viewportHeight / 2, viewportHeight / 2, 0, 1000.0f);
rotationMatrix = new Matrix4f().initIdentity();
translationMatrix = new Matrix4f().initIdentity();
position = new Vector3f(0, 0, 0);
rotation = new Vector3f(0, 0, 0);
updateViewport(viewportWidth, viewportHeight);
}
private Vector3f tmpVec = new Vector3f(0, 0, 0);
public void update() {
projection.initOrthographic(-viewportWidth / 2, viewportWidth / 2, -viewportHeight / 2, viewportHeight / 2, 0, 1000.0f);
rotationMatrix.initRotation(rotation.x, rotation.y, rotation.z);
translationMatrix.initTranslation(-position.x, -position.y, -position.z);
combined = projection.mul(rotationMatrix.mul(translationMatrix));
shader.updateUniform("combinedMatrix", combined);
}
public void updateViewport(float viewportWidth, float viewportHeight) {
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
}
public void startDrawing() {
shader.bind();
}
public void endDrawing() {
shader.unbind();
}
public void bindShader(Shader shader) {
this.shader = shader;
}
public Matrix4f getCombinedMatrix() {
return combined;
}
public void translate(float x, float y) {
this.position.add(x, y, 0);
}
public void moveTo(float x, float y) {
this.position.set(x, y, 0);
}
public void rotate(float z) {
this.rotation.add(0, 0, z);
}
public Vector3f getPosition() {
return position;
}
public void setPosition(Vector3f position) {
this.position = position;
}
public Vector3f getRotation() {
return rotation;
}
public void setRotation(Vector3f rotation) {
this.rotation = rotation;
}
}
And here my Matrix4f.java :
package com.poulpicious.engine.maths;
public class Matrix4f {
private float[][] m;
public Matrix4f() {
m = new float[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
m[i][j] = 0;
}
}
}
public Matrix4f initIdentity() {
m[0][0] = 1;
m[1][1] = 1;
m[2][2] = 1;
m[3][3] = 1;
return this;
}
public Matrix4f initTranslation(float x, float y, float z) {
initIdentity();
m[0][3] = x;
m[1][3] = y;
m[2][3] = z;
return this;
}
public Matrix4f initRotation(float x, float y, float z) {
Matrix4f rx = new Matrix4f();
Matrix4f ry = new Matrix4f();
Matrix4f rz = new Matrix4f();
x = (float) Math.toRadians(x);
y = (float) Math.toRadians(y);
z = (float) Math.toRadians(z);
rz.m[0][0] = (float) Math.cos(z);
rz.m[0][1] = (float) -Math.sin(z);
rz.m[1][0] = (float) Math.sin(z);
rz.m[1][1] = (float) Math.cos(z);
rz.m[2][2] = 1;
rz.m[3][3] = 1;
rx.m[0][0] = 1;
rx.m[1][1] = (float) Math.cos(x);
rx.m[1][2] = (float) -Math.sin(x);
rx.m[2][1] = (float) Math.sin(x);
rx.m[2][2] = (float) Math.cos(x);
rx.m[3][3] = 1;
ry.m[0][0] = (float) Math.cos(y);
ry.m[0][2] = (float) -Math.sin(y);
ry.m[1][1] = 1;
ry.m[2][0] = (float) Math.sin(y);
ry.m[2][2] = (float) Math.cos(y);
ry.m[3][3] = 1;
m = rz.mul(ry.mul(rx)).getM();
return this;
}
public Matrix4f initScale(float x, float y, float z) {
m[0][0] = x;
m[1][1] = y;
m[2][2] = z;
m[3][3] = 1;
return this;
}
public Matrix4f initOrthographic(float left, float right, float bottom, float top, float near, float far) {
this.initIdentity();
float width = right - left;
float height = top - bottom;
float depth = far - near;
m[0][0] = 2.0f / width;
m[0][3] = -(right + left) / width;
m[1][1] = 2.0f / height;
m[1][3] = -(top + bottom) / height;
m[2][2] = -2.0f / depth;
m[2][3] = -(far + near) / depth;
m[3][3] = 1;
return this;
}
public Matrix4f initRotation(Vector3f forward, Vector3f up) {
Vector3f f = forward.set(forward.x, 0, forward.z).normalized();
Vector3f r = up.normalized();
r = r.cross(f);
Vector3f u = f.cross(r);
return initRotation(f, u, r);
}
public Matrix4f initRotation(Vector3f forward, Vector3f up, Vector3f right) {
Vector3f f = forward;
Vector3f r = right;
Vector3f u = up;
m[0][0] = r.x;
m[0][1] = r.y;
m[0][2] = r.z;
m[1][0] = u.x;
m[1][1] = u.y;
m[1][2] = u.z;
m[2][0] = f.x;
m[2][1] = f.y;
m[2][2] = f.z;
m[3][3] = 1;
return this;
}
public Vector3f transform(Vector3f r) {
return new Vector3f(m[0][0] * r.x + m[0][1] * r.y + m[0][2] * r.z + m[0][3], m[1][0] * r.x + m[1][1] * r.y + m[1][2] * r.z + m[1][3], m[2][0] * r.x + m[2][1] * r.y + m[2][2] * r.z + m[2][3]);
}
public Matrix4f mul(Matrix4f r) {
Matrix4f res = new Matrix4f();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
res.set(i, j, m[i][0] * r.get(0, j) + m[i][1] * r.get(1, j) + m[i][2] * r.get(2, j) + m[i][3] * r.get(3, j));
}
}
return res;
}
public float[][] getM() {
float[][] res = new float[4][4];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
res[i][j] = m[i][j];
return res;
}
public float get(int x, int y) {
return m[x][y];
}
public void setM(float[][] m) {
this.m = m;
}
public void set(int x, int y, float v) {
m[x][y] = v;
}
public String toString() {
String result = "";
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
result += m[i][j] + ", ";
return result;
}
}
(I assume it’s TheBennyBox’s one !)
And the Vertex Shader :
#version 150 core
uniform mat4 combinedMatrix;
uniform vec2 cameraPosition;
in vec2 in_Position;
in vec2 in_TexCoord;
out vec2 texCoord;
void main(void) {
gl_Position = combinedMatrix * vec4(in_Position, 0.0, 1.0);
texCoord = in_TexCoord;
}
I don’t know how to figure this…
Thanks in advance for any response,
yann68