Could anyone help me set up an intuitive perspective camera matrix using OpenGL and the GLM library?
By "intuitive" I mean that I want the camera to be looking at the middle of the screen down the -Z axis, but I want it to be positioned in front of the camera to the exact degree that would cause a vector placement at (0,0,0)
and a vector placement of (screen_width, screen_height, 0)
to show up in the bottom-left and top-right corners respectively.
Feel free to ask me to clarify, if need be. This is what I have currently:
glm::mat4 Projection = glm::perspective(45.0f, (GLfloat) window_width / (GLfloat) window_height, 0.1f, #X#);
glm::mat4 View = glm::lookAt(
glm::vec3(window_width/2, window_height/2, #X#), // camera position
glm::vec3(window_width/2, window_height/2, 0), // look at origin
glm::vec3(0, 1, 0) // Head is up
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * View * Model;
The #X#
s are the arguments that I'm not sure how to calculate.
I don't know how to calculate the correct Z position for the camera, and I also don't know how far out to put my far clipping plane. (Should it be a fixed(large) value, or should it be based on my width/height?)
Also, is 45 degrees what I should be using? I've seen some people use values like 60 or 70.
I'm sure whatever the calculation function is would work based off of the angle/window_width/window_height and I'm also sure its easy if you know trig.
EDIT
In response to user1118321
I tried to implement the solution provided, but it didn't quite give me what I'm looking for.
Here is the code I have now
float fov=45.0f;
glm::mat4 Projection = glm::perspective(fov, (GLfloat) window_width / (GLfloat) window_height, 0.1f, 10000.0f);
float angle1=fov/2.0;
float angle2=180 - (90 + angle1);
float Z = 0.5 * window_height * sin(glm::radians(angle2))/sin(glm::radians(angle1));
glm::mat4 View = glm::lookAt(
glm::vec3(window_width/2, window_height/2, Z), // camera position
glm::vec3(window_width/2, window_height/2, 0), // look at origin
glm::vec3(0, 1, 0) // Head is up
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * View * Model;
When I try to render a square, who's bottom left corner is at (0,0,0)
and who's top right corner is at (window_width, window_height,0)
, it doesn't span the entire screen.
This is what I get instead: