Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: glm: Triangle with perspective

  1. #1
    Junior Member Regular Contributor
    Join Date
    May 2008
    Posts
    116

    glm: Triangle with perspective

    Hi,

    I can see my first "OpenGL 3.2 core profile"-triangle
    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:

    Code :
    #version 150 core
     
    uniform mat4 ModelViewProjectionMatrix;
     
    in vec3 in_Position;
     
    void main(void)
    {
      gl_Position= ModelViewProjectionMatrix * vec4(in_Position, 1.0);
    }

    Code :
    #version 150 core
     
    out vec4 out_Color;
     
    void main(void)
    {
      out_Color = vec4(1.0, 0.0, 0.0, 1.0);  
    }

    Code :
    // 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:

    Code :
    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

    Help is really appreciated!

  2. #2
    Super Moderator Frequent Contributor Groovounet's Avatar
    Join Date
    Jul 2004
    Posts
    937

    Re: glm: Triangle with perspective

    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....

  3. #3
    Junior Member Regular Contributor
    Join Date
    May 2008
    Posts
    116

    Re: glm: Triangle with perspective

    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.

  4. #4
    Junior Member Regular Contributor
    Join Date
    May 2008
    Posts
    116

    Re: glm: Triangle with perspective

    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.

  5. #5
    Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: glm: Triangle with perspective

    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.

    Code :
    #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,&amp;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,&amp;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,&amp;vao);
      glBindVertexArray(vao);
     
      //in vec3 in_Position;
      glGenBuffers(1,&amp;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,&amp;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();
    }

  6. #6
    Junior Member Regular Contributor
    Join Date
    May 2008
    Posts
    116

    Re: glm: Triangle with perspective

    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.

    Shame on my that I did not notice this earlier!

  7. #7
    Super Moderator Frequent Contributor Groovounet's Avatar
    Join Date
    Jul 2004
    Posts
    937

    Re: glm: Triangle with perspective

    Great to read!

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

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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •