glm: Triangle with perspective

Hi,

I can see my first “OpenGL 3.2 core profile”-triangle :slight_smile:
Now I tried to add perspective using the nice glm library.

But somehow the triangle disappears when using the
perspective stuff. Here is my code:

#version 150 core

uniform mat4 ModelViewProjectionMatrix;

in vec3 in_Position;

void main(void)
{
  gl_Position= ModelViewProjectionMatrix * vec4(in_Position, 1.0);
}
#version 150 core

out vec4 out_Color;

void main(void)
{
  out_Color = vec4(1.0, 0.0, 0.0, 1.0);  
}

// setup projection matrix

ProjectionMatrix= glm::mat4(1.0f);
ProjectionMatrix*= glm::perspective(45.0f, 1024.0f / 768.0f, 0.1f, 200.0f);


// setup modelview matrix (look down the negative z-axis)

ModelViewMatrix= glm::mat4(1.0f); 
ModelViewMatrix*= glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));


// create and upload modelviewprojection matrix

ModelViewProjectionMatrix= ProjectionMatrix * ModelViewMatrix;
glUniformMatrix4fv(glGetUniformLocation(m_handle, "ModelViewProjectionMatrix"), 1, false, glm::value_ptr(ModelViewProjectionMatrix));


// setup triangle using VBO and VAO

float* vert = new float[9];

vert[0] = 0.0; vert[1] = 1.0; vert[2]= -10.0;
vert[3] =-1.0; vert[4] =-1.0; vert[5]= -10.0;
vert[6] = 1.0; vert[7] =-1.0; vert[8]= -10.0;

unsigned int m_vaoID;
	
glGenVertexArrays(1, &m_vaoID);
glBindVertexArray(m_vaoID);
	
glGenBuffers(1, &m_vboID);
glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), vert, GL_STATIC_DRAW);	glVertexAttribPointer((GLuint)ATTRIBUTE_LOCATION_WORLDVERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0);	glEnableVertexAttribArray(ATTRIBUTE_LOCATION_WORLDVERTEX);


// render

glDrawArrays(GL_TRIANGLES, 0, 3);


// cleanup

glBindVertexArray(0);

delete[] vert;

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &m_vboID);

glDeleteVertexArrays(1, &m_vaoID);

I can see this triangle…

…when I apply the following changes to the code above:

glUniformMatrix4fv(glGetUniformLocation(m_handle, "ModelViewProjectionMatrix"), 1, false, glm::value_ptr(glm::mat4(1.0f)/*ModelViewProjectionMatrix*/));

vert[0] = 0.0; vert[1] = 1.0; vert[2]= -1.0;
vert[3] =-1.0; vert[4] =-1.0; vert[5]= -1.0;
vert[6] = 1.0; vert[7] =-1.0; vert[8]= -1.0;

So the change is that I upload an identity (no projection)
matrix for the modelviewprojection matrix and display the
triangle at z == -1.0f instead of -10.0f.

I have disabled back-face culling and depth test.

Where is my mistake? I can’t get the triangle to work
with perspective. I’m really stuck :frowning:

Help is really appreciated!

Instead of:
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));

I have the feeling that this would be better:
glm::lookAt(glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

No sure actually, it could be many thinks…

Mhmmm my triangle “sits” on the negative z-axis at -10.
So I guess the camera should look down the negative z-axis to
be able to see the triangle. That’s why I set the camera position
to (0,0,0) and the camera target to a point on the negative
z-axis (0,0,-1).

Anyway I tried your version but still no triangle =/. I really
wonder what could be wrong because it is not much code.
The shaders are minimalist… the object is minimalist… and
also visible without projection… all I do is multiplying
with the modelviewprojection matrix.

Groovounet do you have a working GLM example
similiar to my code above? I have no clue
whats wrong. It works without the projection
so I guess the projection matrix that glm
returns does not work.

I took a look at Projection tutorial to first confrim what you had made sense – yes it did. I then pulled together a quick complete code to try it out. This works fine for me … I used the notation &variable[0][0] instead of glm::value_ptr(variable) notation.


#define GL3_PROTOTYPES
#include <GL3/gl3.h>
#include <SDL.h>
#include <iostream>
#include <fstream>

//OpenGL Mathematics (GLM).  A C++ mathematics library for 3D graphics.
#include <glm/glm.hpp>
#include <glm/GLM_GTX_matrix_projection.h>
#include <glm/GLM_GTX_transform2.h> // for lookAt

void glError(const char *file, int line) {
  GLenum err(glGetError());

  while(err!=GL_NO_ERROR) {
    std::string error;

    switch(err) {
      case GL_INVALID_OPERATION:  error="INVALID_OPERATION";  break;
      case GL_INVALID_ENUM:    error="INVALID_ENUM";    break;
      case GL_INVALID_VALUE:    error="INVALID_VALUE";    break;
      case GL_OUT_OF_MEMORY:    error="OUT_OF_MEMORY";    break;
    }

    std::cerr<<"GL_"<<error<<" - "<<file<<':'<<line<<std::endl;
    err=glGetError();
  }
}

int main() {
  //SDL Initialization
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,2);
  SDL_Init(SDL_INIT_VIDEO);

  const int r_width(640),r_height(480);
  SDL_WindowID window(SDL_CreateWindow("Foo",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,r_width,r_height,SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN));
  SDL_GLContext glcontext(SDL_GL_CreateContext(window));

  std::cout<<"OpenGL "<<glGetString(GL_VERSION)<<" (GLSL "<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<')'<<std::endl;

  //Create shaders and shader program
  GLuint vshader(glCreateShader(GL_VERTEX_SHADER));
  GLuint fshader(glCreateShader(GL_FRAGMENT_SHADER));
  GLuint program(glCreateProgram());

  {
    std::ifstream source_file("image.vert");

    std::string data;
    std::getline(source_file,data,'\0');

    const GLchar *vshader_source(data.c_str());

    glShaderSource(vshader,1,&vshader_source,NULL);
  }

  {
    std::ifstream source_file("image.frag");

    std::string data;
    std::getline(source_file,data,'\0');

    const GLchar *fshader_source(data.c_str());

    glShaderSource(fshader,1,&fshader_source,NULL);
  }

  glCompileShader(vshader);
  glCompileShader(fshader);

  glAttachShader(program,vshader);
  glAttachShader(program,fshader);
  glLinkProgram(program);

  //Get handles to shader uniforms
  GLint l_ModelViewProjectionMatrix(glGetUniformLocation(program,"ModelViewProjectionMatrix")); //uniform mat4 ModelViewProjectionMatrix;

  //Create geometry vertex array
  GLuint buf_in_Position,vao;
  const GLfloat in_Position[3*3]= {
    0.0f, 1.0f,-10.0f, 
   -1.0f,-1.0f,-10.0f,
    1.0f,-1.0f,-10.0f
  };

  glGenVertexArrays(1,&vao);
  glBindVertexArray(vao);

  //in vec3 in_Position;
  glGenBuffers(1,&buf_in_Position);
  glBindBuffer(GL_ARRAY_BUFFER,buf_in_Position);
  glBufferData(GL_ARRAY_BUFFER,sizeof(in_Position),in_Position,GL_STATIC_DRAW);
  const GLint l_in_Position(glGetAttribLocation(program,"in_Position"));
  glVertexAttribPointer(l_in_Position,3,GL_FLOAT,GL_TRUE,0,NULL);
  glEnableVertexAttribArray(l_in_Position);

  //Render
  glm::mat4 projmat;
  glm::mat4 modelmat;
  glm::mat4 ModelViewProjectionMatrix;

  projmat=glm::mat4(1.0);  //loadIdentity
  projmat*=glm::perspective(45.0f, 1024.0f / 768.0f, 0.1f, 200.0f);

  modelmat=glm::mat4(1.0);  //loadIdentity
  modelmat*=glm::lookAt( glm::vec3(0.0f,0.0f, 0.0f), 
                         glm::vec3(0.0f,0.0f,-1.0f), 
                         glm::vec3(0.0f,1.0f, 0.0f));

  ModelViewProjectionMatrix=projmat*modelmat;

  glUseProgram(program);

  glUniformMatrix4fv(l_ModelViewProjectionMatrix,1,GL_FALSE,&ModelViewProjectionMatrix[0][0]);

  glBindVertexArray(vao);
  glDrawArrays(GL_TRIANGLES,0,3);

  glError(__FILE__,__LINE__);
  SDL_GL_SwapWindow(window);
  SDL_Delay(6000);

  //Quit
  glDeleteShader(vshader);
  glDeleteShader(fshader);
  glDeleteProgram(program);
  SDL_GL_DeleteContext(glcontext);
  SDL_DestroyWindow(window);
  SDL_Quit();
}

I just found the problem. While converting stuff from OpenGL
1.X to 3.2 I had to comment out some old code in a utility
class to avoid that glGetError throws errors.

Unfortunately in this code also some arrays were allocated.
Later there was a write operation on these arrays (which I
forgot to comment out too). This operation wrote into
undefined memory locations partially overwriting my glm
matrices. I don’t know why this did not instantly crash
the program. Anyway thanks god I finally found the problem.

Also thanks for your effort marshats because after I read
your post that the code works fine for you I figured this
memory corruption out by moving the matrix calculations
from my Init method directly in front of the
glDrawElements command.

Lo and behold! I suddenly saw the triangle! So I compared
the matrix generated in front of the glDrawElements command
with the matrix generated in my Init method and noticed
a difference in one mvp column caused by this invalid write. :mad:

Shame on my that I did not notice this earlier!

Great to read!

I was afraid that something trivial doesn’t work in GLM but fortunately it’s not the case here! :slight_smile: Sorry I didn’t put must effort on this thread, I am in holidays.

Damn it, what am I doing here? Nice day guys!