Search code examples
c++openglglm-math

How to configure VAO and VBO for custom made Structure


I am trying to construct a bar.

First I declare a structure

struct VertexFormat
    {
        glm::vec3 positions;
        glm::vec3 normal;
        glm::vec2 texCoord;
        VertexFormat(glm::vec3 pos, glm::vec3 norm, glm::vec2 coord) : positions(pos), normal(norm), texCoord(coord)
        {   }
    };

and then I configure the VAO and the VBO

glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(VertexFormat), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size(), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, data.size() * sizeof(VertexFormat), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, data.size() * sizeof(VertexFormat), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, data.size() * sizeof(VertexFormat), (void*)(6 * sizeof(float)));
glBindVertexArray(0);

Nothing gets drawn when I issue the drawing commands

glBindVertexArray(m_VAO);
glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);

My question is: am I defining the offsets for the data in the buffers correctly?


Solution

  • There are several problems with this code:

    First, the amount of data uploaded to the EBO is wrong. The size of the data has to be given in byte. Assuming that indices contains unsigned integers, the code should be:

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
    

    Then, stride describes the offset between two consecutive vertices in the buffer, not the total size of your data. In your case, every vertex starts sizeof(VertexFormat) after the previous one.

    The correct code should be:

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)(6 * sizeof(float)));