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
\$\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\$
  • \$\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 '17 at 8:21
  • \$\begingroup\$ @Pins - unfortunately unbinding is something that's frequently seen in more recent tutorials, yes. \$\endgroup\$ – Maximus Minimus Jun 21 '17 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.