0
votes

I'm trying to change my camera projection from perspective to orthographic. At the moment my code is working fine with the perspective projection

m_prespective = glm::perspective(70.0f, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.01f, 1000.0f);
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -mesh.radius);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_prespective * glm::lookAt(m_position, m_forward, m_up);

But as soon as i change it to orthographic projection I can't see my mesh anymore.

m_ortho = glm::ortho(0.0f, (float)DISPLAY_WIDTH, (float)DISPLAY_HEIGHT,5.0f, 0.01f, 1000.0f);
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -mesh.radius);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_ortho * glm::lookAt(m_position, m_forward, m_up);

I don't understand what I'm doing wrong.

1
Have you accidentally swap the arguments to ortho? The signature should be ortho(left, right, bottom, top, near, far). What's that 5.0?peppe
Actually yes, setting top to 0.0f allow me to see at least an extremely small bunch of pixels in the top left corner of my window. However using perspective projection my mesh is displayed in the center of the screen and has a "normal" size. Still, i don't understand why it is displayed so far away and not centered. Do you have any clue?Izzy88
Considering that my DISPLAY_WIDTH and DISPLAY_HEIGHT are respectively 800 and 600, changing these values from m_ortho = glm::ortho(0.0f, 800.0f, 600.0f ,5.0f, 0.01f, 1000.0f); to m_ortho = glm::ortho(8.0f, 0.0f,0.0f,6.0f, 0.1f, 100.0f); makes the size go back to normal (more or less). But I don't understand if there's a rule or a specific relation for changing the size values from perspective projection to orthographic projection. (Just to avoid changing them manually every time)Izzy88
@Izzy88: Here's a suggestion. Don't just mindlessly try to shuffle around variables based on code you've seen somewhere. If you do that you're cargo cult programming: You do things that somehow resemble how other people write code, but you're never getting the planes to land, err, make your code do what you want it to do, because you don't actually understand what you're doing there. Understand what the parameters for a perspective and a orthographic projection mean in geometrical terms and why and how you have to chose them to get the desired results. Take a pen and paper and start drawing.datenwolf

1 Answers

2
votes

In perspective projection the term (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT is evaluating the picture aspect ratio. This number is going to be close to 1. The left and right clip plane distances at the near plane for perspective projection is aspect * near_distance. More interesting though is the expanse of left-right at the viewing distance, which in your case is abs(m_position.z)= abs(mesh.radius).

Carrying this over to orthographic projection the left, right, top and bottom clip plane distances should be of the same order of magnitude, so given that aspect is close to 1 the values for left, right, bottom and top should be close to the value of abs(mesh.radius). The resolution of the display in pixels is totally irrelevant except for the aspect ratio.

Furthermore when using a perspective projection the value for near should be chosen as large as possible so that all desired geometry is visible. Doing otherwise will waste precious depth buffer resolution.

float const view_distance = mesh.radius + 1;

float const aspect = (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT;
switch( typeof_projection ){
case perspective:
    m_projection = glm::perspective(70.0f, aspect, 1.f, 1000.0f);
    break;

case ortho:
    m_projection = glm::ortho(
        -aspect * view_distance,
         aspect * view_distance,
        view_distance,
        view_distance,
        -1000, 1000 );
    break;
}

m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -view_distance);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);

return m_projection * glm::lookAt(m_position, m_forward, m_up);