0
\$\begingroup\$

Here is the code where I initialize the VAO, vertex attributes(also the main VBO) and EBO(im using my own wrapper class for these "databuffers" to hide some of the API features and make life easier so i dont think the problem will be in the generic class as it was working without problems)

void initVAOManager(const bool& ebo) {


    if (_vaoID == 0)
        glGenVertexArrays(1, &_vaoID);

    glBindVertexArray(_vaoID);

    /**
    Here is the main data buffer (positions,colors,UVs)
    If it doesn´t exist a new one is created
    **/
    if (!_mainBuffer)
        _mainBuffer = new DataBuffer<T>(GL_ARRAY_BUFFER);

    _mainBuffer->bindBuffer();

    if (!_eboBuffer && ebo) {

        _eboBuffer = new DataBuffer<eboData>(GL_ELEMENT_ARRAY_BUFFER);

        _eboBuffer->bindBuffer();
    }

    //This is the position
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));

    //Color attrib pointer
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));

    //UV
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, uv));

    _mainBuffer->unbindBuffer();

    if (ebo)
        _eboBuffer->unbindBuffer();

    glBindVertexArray(0);
}

Then the render function (dont mind the for loop, as i want to render multiple objects from the batch in one function):

void renderBatchNormal()
{
    uploadData();

    glBindVertexArray(_VAOManager->getVAO());

    std::vector<eboData>

    for (std::size_t i = 0; i < _DATA.size(); i++) {
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }

    glBindVertexArray(0);

    clearData();
}

The upload data function send a data from the vectors to their buffers, I can send it too but as Im using my generic wrapper and it worked before with normal drawings I assume there is no problem. And finally a class eboData(if anyone wondered) (basically just a blank class with an array of 6 indices)

class eboData {
public:
    GLuint indices[6];
};

However, this is causing crashes on the line where I try to execute the glDrawElements command, I read that it can be caused with no binded VAO while binding the ELEMENT BUFFER but as you can see from the code I´m doing it right(at least I think that). However, if I change the following line with:

std::vector<eboData> _eboVector;

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, _eboVector.data());

The code is working (problem is also that I don´t know how to render second item in the buffer as it is showing only the first one). Do you have any ideas what can cause this crash?

PS: glGetError() returns 0.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You're crashing because you unbind.

If you check your creation code, you'll see that _eboBuffer is first bound. At this stage _eboBuffer is stored in your VAO and all is well. Then at the end you unbind _eboBuffer, at which stage it's no longer stored in your VAO.

Unbinding, in general, is something that's actually not necessary and I would discourage it as a bad practice. Bind everything you need to use before you use it instead, and that way you can be certain that your state is what you intend.

\$\endgroup\$
2
  • \$\begingroup\$ You are the savior. I dont know where did this practice come from, maybe I´ve seen it in some of the tutorials. Thanks a lot! \$\endgroup\$
    – Pins
    Jun 21, 2017 at 8:21
  • \$\begingroup\$ @Pins - unfortunately unbinding is something that's frequently seen in more recent tutorials, yes. \$\endgroup\$ Jun 21, 2017 at 14:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .