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:
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:
No comments:
Post a Comment