Search code examples
c++openglglm-mathglew

opengl drawing a 3d cube with with EBO


I am trying to draw a cube with OPENGL by using EBO, VAO, and VBO.

the first function init the VAO of the cube

initVAO()
{
    GLfloat cube_vertices[] = {
        // front
        -1.0, -1.0,  1.0,
         1.0, -1.0,  1.0,
         1.0,  1.0,  1.0,
        -1.0,  1.0,  1.0,
        // back
        -1.0, -1.0, -1.0,
         1.0, -1.0, -1.0,
         1.0,  1.0, -1.0,
        -1.0,  1.0, -1.0
    };
    GLushort cube_elements[] = {
        // front
        0, 1, 2,
        2, 3, 0,
        // right
        1, 5, 6,
        6, 2, 1,
        // back
        7, 6, 5,
        5, 4, 7,
        // left
        4, 0, 3,
        3, 7, 4,
        // bottom
        4, 5, 1,
        1, 0, 4,
        // top
        3, 2, 6,
        6, 7, 3
    };

    vertices.insert(vertices.begin(), std::begin(cube_vertices), std::end(cube_vertices));
    indices.insert(indices.begin(), std::begin(cube_elements), std::end(cube_elements));

    /* create vao */
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    /* create ebo */
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);

    /* create vbo */
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    /* unbind buffers */
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glBindVertexArray(0);
    
}

and the second function use it to draw

draw()
{

    shader->activateShader();

    /* calculate projection matrix */
    //TODO:: find a new place for the projection matrix calculation
    int width = (GLfloat)ResourceManager::getInstance()->getWindowSize().x;
    int height = (GLfloat)ResourceManager::getInstance()->getWindowSize().y;
    glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)width / height, 0.1f, 100.0f);

    /* update shader uniforms*/
    glUniformMatrix4fv(shader->projectionUniform, 1, GL_FALSE, glm::value_ptr(proj));
    glUniformMatrix4fv(shader->viewUniform, 1, GL_FALSE, glm::value_ptr(Engine::getInstance()->camera->createViewMatrix()));
    glUniformMatrix4fv(shader->modelUniform, 1, GL_FALSE, glm::value_ptr(transform->createModleMatrix()));

    glUniform4f(shader->colorUniform, color.x, color.y, color.z, 1);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    glUseProgram(0);

}

right now the program is not drawing anything and I cant figure out what is wrong with it

I know that the other parts of the code works because I tested it without a EBO and it worked but I don't know what to do.


Solution

  • See Index buffers. The index buffer binding is stated within the Vertex Array Object. When a buffer is bound to the target ELEMENT_ARRAY_BUFFER, then this buffer is associated to the vertex array object which is currently bound. When calling glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); the binding of the element buffer to the currently bound VAO is broken. Remove this line of code:

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


    The type specification in the glDrawElements must match the type of the indices. Since the type of the indexes is GLushort, the specified type must be GL_UNSIGNED_SHORT:

    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);