Abanoub
Abanoub

Reputation: 3809

how to use glDrawElements with glBindVertexArray properly

what am trying to do is using glDrawElements to draw without redundancy of vertices as follow:

Model ModelManager::CreateModel(std::vector<glm::vec3>&vertices, std::vector<uint16_t>&vertexIndeces)
{
    //Vertecies
    GLuint vertexArray;

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

    GLuint vBufferId;
    glGenBuffers(1, &vBufferId);
    glBindBuffer(GL_ARRAY_BUFFER, vBufferId);
    glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint iBufferId;
    glGenBuffers(1, &iBufferId);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBufferId);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size(), vertexIndeces.data(), GL_STATIC_DRAW);

    glBindVertexArray(0);
    //
    return Model(vertexArray, vBufferId, iBufferId, vertexIndeces.size());
}

and then when I draw :

void Model::Draw()
{
    if (vertexArray)
    {
        isFinishedIniting = true;
        glBindVertexArray(vertexArray);
        glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_SHORT, 0);
        glBindVertexArray(0);
    }
}

shaders:

#version 120


void main()
{
        gl_Position= gl_ModelViewProjectionMatrix*gl_Vertex;

}

#version 120


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

the obj file am trying to load is easy I hand made it :

v 0.0 0.0 0.0
v 1.0 1.0 0.0
v -1.0 1.0 0.0
v -1.0 -1.0 0.0
v 1.0 -1.0 0.0

f 1/1/1 2/1/1 3/1/1
f 1/1/1 4/1/1 5/1/1

so it should show two red Triangles ,but it's not drawing anything to the screen!

Upvotes: 0

Views: 748

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54592

There are a couple of problems in this code:

  1. The sizes passed to glBufferData() look wrong:

    glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
    ...
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size(), vertexIndeces.data(), GL_STATIC_DRAW);
    

    Both vertices and vertexIndeces() are vectors. The .size() method on a vector gives the number of elements, while glBufferData() expects the size in bytes. To fix this, change the code to:

    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]),
                 vertices.data(), GL_STATIC_DRAW);
    ...
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndeces.size() * sizeof(vertexIndeces[0]),
                 vertexIndeces.data(), GL_STATIC_DRAW);
    
  2. The API calls use a mix of fixed function attributes and generic vertex attributes. Based on the version in the shader code, and the shader code itself (particularly the use of gl_Vertex), you're using OpenGL 2.1 level shaders with fixed function attributes. Therefore, you need to use glEnableClientState() and glVertexPointer() instead of glEnableVertexAttribArray() and glVertexAttribPointer():

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, 0);
    

    You can use generic vertex attributes, but then you need to declare a variable of type attribute in the vertex shader, instead of using gl_Vertex.

Upvotes: 2

Related Questions