Camera

I'm going to add a camera system to the project. Because I would to make some 3D things in the next posts. I won't explain the math behind it, because I'm not the chosen one. We will only learn the methods we need to use.
Camera System
I tried to draw an image showing how we get a projection view.

Let's start with Camera class. I will create a file called Camera.cs in objects folder. Because a camera is an object for me:
public class Camera
{
    Matrix4 view;
    Matrix4 projection;
    ShaderManager shaderManager;
    public Vector3 Position { get; set; }

    public Camera(ShaderManager shaderManager, float angle, int width, int height, float zNear=0.1f, float zFar=100f)
    {
        this.shaderManager = shaderManager;

        // Creates a perspective projection matrix.
        projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(angle), (float) width / (float) height, zNear, zFar);


        Position = new Vector3(0f,0f,3f);
        // camera position -> (0,0,3)
        // camera look at -> (0,0,0) origin
        // up -> axis-y
        view = Matrix4.LookAt(Position, new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));

        // we can set projection matrice from shader at once.
        foreach (var shader in this.shaderManager.Shaders)
        {
            Console.WriteLine(shader);
            GL.UseProgram(shader.Value.ShaderProgram);
            int uniformLocation_projection = GL.GetUniformLocation(shader.Value.ShaderProgram, "projection");
            GL.UniformMatrix4(uniformLocation_projection, true, ref projection);
        }
    }

    public void Update()
    {
        view = Matrix4.LookAt(Position, new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
        
        foreach (var shader in this.shaderManager.Shaders)
        {
            GL.UseProgram(shader.Value.ShaderProgram);
            int uniformLocation_view = GL.GetUniformLocation(shader.Value.ShaderProgram, "view");
            GL.UniformMatrix4(uniformLocation_view, true, ref view);
        }
    }
}
I added the update method because when the camera has to move, the view matrix will be updated. Let's update the vertex shader:
#version 330 core

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoord;

uniform mat4 uTransform;
uniform mat4 projection;
uniform mat4 view;

out vec2 passTexCoord;

void main()
{
    gl_Position =  vec4(aPos, 1.0) * uTransform * view * projection;
    passTexCoord = aTexCoord;
}
Normally, the multiplication of matrices should not be in this order in opengl applications, however it should be multiplied in the opposite way in OpenTK as far as I understand. I updated the draw method of GameObject class as follows:
        public void Draw()
        {
            GL.UseProgram(Shader!.ShaderProgram);

            ...
            
            int uniformLocation_Transformation = GL.GetUniformLocation(Shader.ShaderProgram, "uTransform");
            GL.UniformMatrix4(uniformLocation_Transformation, true, ref Transformation);

            ...
        }
Now, I can use the camera in the scene. I created an object called camera in the Scene.cs:
        private void InitScene()
        {
            ...

            camera = new Camera(shaderManager, 45f, 1024, 768, 0.1f, 100f);
        }
        
        public void Update()
        {
            objectManager.Update();
            camera.Update();
        }
Let's test the camera how it looks:
Camera Test OpenGL

The camera position is changed like below:
            camera = new Camera(shaderManager, 45f, 1024, 768, 0.1f, 100f);
            camera.Position = new Vector3(0,0,15f);
        }
The output:
camera zoom out OpenGL


No comments:

Post a Comment