I am developing a game engine. Currently I am working on the camera system. When I translate it Time::getMainLoopDeltaTime() units to the right, everything in the scene moves to the right along with it when everything should look like it is moving left. I cannot figure out what I am doing wrong. These are the technologies that I am using:
Note: I am using the game object's transform as the camera's transformation matrix that also serves as the view matrix. The x position outputs positively increasing values and the game objects in the scene are stationary (their x y z position values are not changing).
Camera game object intialization
GameObject* gameObject = GameObject::create("Main Camera", 100);
gameObject->addComponent(ComponentType::CAMERA_2D);
Transform* transform = gameObject->getTransform();
transform->scale(glm::vec3(0.1f, 0.1f, 0.1f)); // Zoom out camera 10x and gameObject's transform
Projection matrix initialization:
glm::mat4 projectionMatrix = glm::ortho(-500.0f, 500.0f, -500.0f, 500.0f, -1.0f, 1.0f);
I have a logic component that runs every main loop update/cycle and translates the camera/game object:
Transform* cameraTransform = Camera2D::getMainCamera()->getGameObject()->getTransform();
cameraTransform->translate(glm::vec3(Time::getMainLoopDeltaTimeF() * 10, 0, 0));
cout << cameraTransform->getPosition().x << endl;
Then the rendering engine does the following:
projectionViewMatrix = projectionMatrix * Camera2D::getMainCamera()->getViewMatrix();
spirVProgram->setProjectionViewMatrix(projectionViewMatrix);
Note: I am multiplying these matrices in this order because I am using GLM.
Here is my vertex shader for additional information:
#version 450 core
layout(location = 0) in vec2 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 textureCoordinates;
layout(location = 3) in float textureSlot;
layout(location = 4) in float ssboIndex;
layout(std430, binding = 2) buffer myBuffer {
mat4 transform[];
};
layout(location = 0) uniform mat4 uProjectionView;
out vec4 vColor;
out vec2 vTextureCoordinates;
out float vTextureSlot;
void main() {
vColor = color;
vTextureCoordinates = textureCoordinates;
vTextureSlot = textureSlot;
gl_Position = uProjectionView * transform[int(ssboIndex)] * vec4(position, 1.0, 1.0);
}
I hope someone can spot what I am doing wrong. If not, can someone explain to me how this is supposed to be done? Is this even supposed to be the expected behavior?
This is how everything looks like:
It is like the game object is moving to the right but the camera moving to the left...
IMPORTANT EDIT
From my research, it appears this is the expected behavior, but I am not sure. If this is the correct behavior, should I just negate the position? And, should I do the same with rotation?
EDIT: is this an acceptable solution?
glm::mat4 Camera2D::getViewMatrix() {
Transform* transform = gameObject->getTransform();
glm::mat4 cameraMatrix = transform->getTransformationMatrix();
cameraMatrix[3][0] *= -1;
cameraMatrix[3][1] *= -1;
cameraMatrix[3][2] *= -1;
return cameraMatrix;
}
The game object's transform would keep it original transform but every time I get it I negate it. This gave the expected result/behavior.
Apparently, what I thought was wrong was actually right, but and incomplete implementation of the camera system. Translating the camera/gameObject matrix to the right will also move everything to the right. To solve this, we can negate the position of a copy of the transformation matrix every time we need to use it to render things. This will allow to keep the original data while getting the expected behavior when rendering.