Results 1 to 3 of 3

Thread: What's happening to my triangles?

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2013
    Posts
    25

    What's happening to my triangles?

    EDIT:
    I've gotten my cube to draw, but I'm still confused. See edit at bottom of post.

    Hello all,

    Sorry for the vague title, but that really is my question. As a preface, I am using glm for some things, and I've got a Shader class with accessor methods for the handle to the position attribute. I am also using SDL2 to create my context, and the version I am requesting is OpenGL 3.0.

    I am just trying to draw a cube, and I have created a VAO using the following function:

    Code :
    //Global geometry struct
    struct Geom{
       GLuint VAO, nIdx;
       vec4 color;
       mat4 MV;
    };
     
    Geom g_Geometry {0, 0, vec4(1), mat4(1) };
     
    //Global Shader
    JShader g_Shader;
     
    bool createGeometry(){
       GLuint buffers[2];
     
       //Indices and Vertices taken from an IQM file exported from Blender
       vector<GLfloat> vertices{
          1,1,-1,
          -1,-1,-1,
          1,-1,-1,
          -1,1,-1,
          1,1,1,
          -1,-1,1,
          -1,1,1,
          1,-1,1,
          1,1,-1,
          1,-1,1,
          1,1,1,
          1,-1,-1,
          1,-1,-1,
          -1,-1,1,
          1,-1,1,
          -1,-1,-1,
          -1,-1,-1,
          -1,1,1,
          -1,-1,1,
          -1,1,-1,
          1,1,1,
          -1,1,-1,
          1,1,-1,
          -1,1,1
       };
     
       vector<GLuint> indices{
          0,1,2,
          0,3,1,
          4,5,6,
          4,7,5,
          8,9,10,
          8,11,9,
          12,13,14,
          12,15,13,
          16,17,18,
          16,19,17,
          20,21,22,
          20,23,21
       };
     
       glGenVertexArrays( 1, &g_Geometry.VAO );
       glBindVertexArray( g_Geometry.VAO );
     
       glGenBuffers(2, buffers);
     
       //positions
       glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
       glBufferData(GL_ARRAY_BUFFER, 
                          sizeof(GLfloat)*vertices.size(),
                          vertices.data(), 
                          GL_STATIC_DRAW);
       glEnableVertexAttribArray(g_Shader.getPosHandle());
       glVertexAttribPointer(g_Shader.getPosHandle(), 3, GL_FLOAT, 0, 0, 0);
     
       //indices
       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
       glBufferData(GL_ELEMENT_ARRAY_BUFFER, 
                          sizeof(GLuint)*indices.size(), 
                          indices.data(), 
                          GL_STATIC_DRAW);
     
       //unbind
       glBindBuffer(GL_ARRAY_BUFFER, 0);
       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
       glBindVertexArray(0);
     
       //Set the number of indices and color
       g_Geometry.nIdx = indices.size();
       g_Geometry.color= vec4(1,0,1,1);
     
       return g_Geometry.VAO != 0;
    }

    All of that data was taken from an IQM file I exported from Blender (just the default cube), and I think it is correct (it looks like two triangles per face, anyway.)

    Here is my render call. I have a Camera struct as well, but I don't think it's relevant.

    Code :
    struct Camera{
       mat4 proj;
    };
     
    Camera g_Camera { mat4(1) };
     
    //Just a rotation to keep things moving
    float theta(0.1f);
     
    //Render function
    bool render(){
       g_Shader.bind();
       glBindVertexArray(g_Geometry.VAO);
       {
          //Send MV matrix to GPU
          g_Geometry.MV = glm::translate( vec3(0,0,-5.f) ) * glm::rotate( theta, vec3(0,1,0) );
          g_Shader.updateMV(glm::value_ptr(g_Geometry.MV));
     
          //Send projection matrix to GPU
          g_Camera.proj = glm::perspective(45.f,SCREEN_DIM.x/SCREEN_DIM.y, 1.f, 20.f);
          g_Shader.updateProj(glm::value_ptr(g_Camera.proj));
     
          //Set color uniform on GPU
          g_Shader.updateColor(glm::value_ptr(g_Geometry.color));
     
          //Draw call, neither really seems to work
          glDrawArrays(GL_TRIANGLES, 0, g_Geometry.nIdx);
    //    glDrawElements(GL_TRIANGLES, g_Geometry.nIdx, GL_UNSIGNED_INT, NULL);
       }
       glBindVertexArray(0);
       g_Shader.unbind();
       theta += 0.01f;
     
       return true;
    }

    When I use glDrawArrays, I get a shape whose triangles do seem to hit every corner, although the ordering is very incorrect. When I use glDrawElements I don't see anything at all.

    I'm not sure what the deal with enabling and disabling Vertex Attribute Arrays (like position), but I though that with a VAO I only needed to do it during the initialization.

    For posterity, here is my shader

    Code :
    //VERTEX SHADER
    #version 130
     
    uniform mat4 projMat;
    uniform mat4 MVMat;
     
    attribute vec3 vPosition;
     
    void main(){
       gl_Position = projMat * MVMat * vec4(vPosition,1);
    }

    Code :
    //FRAGMENT SHADER
    #version 130
     
    uniform vec4 fColor;
     
    void main(){
       gl_FragColor = fColor;
    }

    Sorry for all that text, but if anyone reads it all, any advice? As I said glDrawArrays does but a magenta cube-esque shape on the screen, but it's obvious that the draw order is incorrect. I tried GL_TRIANGLE_STRIP, and while it actually did look better it was still somewhat incorrect.

    EDIT:
    I was able to get it drawing by removing the following calls from createGeometry():

    Code :
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    I guess this makes sense, but I thought that binding the VAO would rebind these by default? Is that not the case?

    And in general, what are some best practices for when to unbind data (especially in a case like this, where I don't really want to deal with individual VBOs)?

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,105
    Quote Originally Posted by mynameisjohn View Post
    I thought that binding the VAO would rebind these by default? Is that not the case?
    The glBindBuffer() call was made while the VAO was bound, so unbinding the element array buffer changes the setting stored within the VAO.

    Also, note that the VAO doesn't store the current binding for GL_ARRAY_BUFFER; for each attribute, it stores the buffer which was bound at the time of the corresponding glVertexAttribPointer() call.

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2013
    Posts
    25
    Thanks, that actually clears up a lot for me.

Similar Threads

  1. Trying to get compute shader happening
    By PeterGali in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 06-23-2015, 10:55 PM
  2. Replies: 1
    Last Post: 08-27-2009, 05:31 PM
  3. What is happening?
    By Zak McKrakem in forum OpenGL: Advanced Coding
    Replies: 61
    Last Post: 03-31-2005, 12:31 PM
  4. What's happening with opengl
    By Toni in forum OpenGL: General
    Replies: 12
    Last Post: 06-17-2003, 06:36 PM
  5. why this is happening?
    By monka in forum OpenGL: Basic Coding
    Replies: 5
    Last Post: 08-30-2002, 04:24 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean