2

When I use a perspective projection in OpenGL, my X axis gets inverted as seen in the image below. The code below might not be valid because I changed it a lot in order to make it less obscure. It might not work, so just keep that in mind. Here is the code and vertices:

 typedef struct{
   float x;
   float y;
   float z;
 } vertex_t;

  glm::vec3 position = glm::vec3(0, 0, 0);
  glm::vec3 look_at = glm::vec3(0, 0, 1);

  glm::mat4 projectionMatrix = glm::perspective(45.0f, (float)800 / (float)600, 0.1f, 100.f); 
  glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 5.0f));
  glm::mat4 viewMatrix = glm::lookAt(
    position, 
    look_at,
    glm::vec3(0, 1, 0) 
  );

  vertex_t data[3] = {
    {-0.5,  0.5, -0.5f},
    { 0.5,  0.5, -0.5f},
    {-0.5, -0.5, -0.5f},
  };

  unsigned int indices[3] = {
    0, 1, 2
  };

 glm::mat4 mvp = projectionMatrix * viewMatrix * modelMatrix; //This is passed in as the uniform u_MVP later

This is the vertex shader:

#version 330 core

layout(location = 0) in vec4 position;

uniform mat4 u_MVP;

void main(){
  gl_Position = u_MVP * position;
}

And this is the output. As you can see, it doesn't match the vertices provided. enter image description here

If you need the entire code, or if you want me to provide the original version, please let me know. Thanks!

UPDATE: I've tried a negative Z axis, and it hasn't worked. Heres the code:

  position = glm::vec3(0, 0, 0);
  look_at = glm::vec3(0, 0, -1);

  
  glm::mat4 projectionMatrix = glm::perspective(45.0f, (float)800 / (float)600, 0.1f, 100.f); 
  glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));
  viewMatrix = glm::lookAt(
    position,
    look_at, 
    glm::vec3(0, 1, 0)  // Tilt/rotation (unclear) set y to -1 for upside down view
  );
Serket
  • 3,785
  • 3
  • 14
  • 45
  • 2
    I think your problem might be related to your camera rather than your projection matrix. What's happening is that you're looking at it from behind, hence it seems as if x is inverted. Remember that OpenGL uses a right-handed coord-system, meaning that the z-axis points out of the screen towards you. Imagine your triangle on the screen. You translate it by 5 (~5 steps out of the screen), and your camera (in the screen) looks in that direction. Hence the output. What you want is the model moved by -5 and the camera looking in the negative direction. – Beko Nov 28 '20 at 12:02
  • 1
    @Beko thanks! could you post this as an answer? – Serket Nov 28 '20 at 12:04
  • Np, Rabbid has already answered it, so no need. – Beko Nov 28 '20 at 12:05
  • 1
    @Beko You are right. We spotted out the same issue (almost at the same time). Don't post comments, but post answers. Actually your comment is an answer. – Rabbid76 Nov 28 '20 at 12:09
  • 1
    @Rabbid76 Yes pretty much simultaneously. I'll keep that in mind (: – Beko Nov 28 '20 at 12:14
  • @Beko I'm getting a black screen, the triangle isn't appearing. But the higher the number on the Z-Axis is, the further away the triangle is getting, suggesting that its a left-handed system. What's wrong? – Serket Nov 28 '20 at 13:00
  • I don't know, looks fine to me. In your shader you have your `position` as `vec4`, may be worth checking out. Make it a `vec3` in the shader and change the calc to `u_MVP * vec4(position, 1.0)` and see if that changes anything. Edit: and what you say has nothing to do with LHS/RHS. The difference is just the direction in which the z-axis points. – Beko Nov 28 '20 at 13:43

1 Answers1

3

The x-axis doesn't get inverted because of the projection matrix, but it get's inverted because of the view matrix.

glm::vec3 position = glm::vec3(0, 0, 0);
glm::vec3 look_at = glm::vec3(0, 0, 1);
glm::mat4 viewMatrix = glm::lookAt(position, look_at, glm::vec3(0, 1, 0));

The view space is a Right-handed system, where the X-axis points to the right and the Y-axis points up. The Z-axis points out of the view (Note in a right hand system the Z-Axis is the cross product of the X-Axis and the Y-Axis).

Hence you look at the triangle from the back.

Change the model matrix and the view matrix. Shift the triangle along the negative Z axis. Define a line of sight pointing in the negative z-direction:

glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));

glm::vec3 position = glm::vec3(0, 0, 0);
glm::vec3 look_at = glm::vec3(0, 0, -1);
glm::mat4 viewMatrix = glm::lookAt(position, look_at, glm::vec3(0, 1, 0));

The distances to the near and far plane have to be positive values and th unit of the angle for glm::perspective is radiant:

0 < near < far

glm::mat4 projectionMatrix = glm::perspective(45.0f, (float)800 / (float)600, -0.1f, -100.f);

glm::mat4 projectionMatrix = glm::perspective(
    glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.f); 
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • I'm getting a black screen, the triangle isn't appearing. But the higher the number on the Z-Axis is, the further away the triangle is getting, suggesting that its a left-handed system. What's wrong? – Serket Nov 28 '20 at 12:58
  • changed both of them, when the z position is negative, I cannot see anything. – Serket Nov 28 '20 at 13:06
  • i've added the code, could you take a look? – Serket Nov 28 '20 at 13:10
  • I tried it with positive values, same thing – Serket Nov 28 '20 at 13:13
  • It doesnt work for me. Ive narrowed down the problem to this line: ```look_at = glm::vec3(0, 0, -1);```. When this looks at z=1, everything is fine (including when the modelMatrix is at -5 z) but when its at negative 1, I cannot see anything – Serket Nov 28 '20 at 13:17
  • Still doens't work. Its almost like I cant look at the negative z axis – Serket Nov 28 '20 at 13:20
  • I've figured out something else: If the position of the camera (on the Z axis) is larger than the look_at position (for the Z axis) the screen turns black – Serket Nov 28 '20 at 13:22
  • Could you add your working code to the answer? Ill figure out the rest by myself – Serket Nov 28 '20 at 13:23
  • @Serket I've copied the "UPDATE" code from your question. Then I changed `45.0f,` to `glm::radians(45.0f)` and it works fine for me. – Rabbid76 Nov 28 '20 at 13:26
  • It doenst work, could you add your working code and Ill do the rest – Serket Nov 28 '20 at 13:27
  • @Serket Which working code? I've put your matrix setup to an arbitrary example on my local drive. Anyway https://pastebin.com/MNp0TQZS. Required files can be found at https://github.com/Rabbid76/graphics-snippets/tree/master/example/cpp/_util/include/gl – Rabbid76 Nov 28 '20 at 13:33
  • Thanks I’ll let you know when I figure out the problem – Serket Nov 28 '20 at 13:36