Question

I've been trying to use Vertex Buffer Objects to save vertex data on the GPU and reduce the overhead, but I cannot get it to work. The code is below.

From what I understand you generate the buffer with glGenBuffers, then you bind the buffer with glBindBuffer so it's ready to be used, then you write data to it with glBufferData and its done and can be unbinded and ready for use later with simply binding it again.

However the last part is what I'm having trouble with, when I bind it after I have created and loaded data to it and try to draw using it, it gives me lots of GL Error: Out of Memory.

I doubt that I am running out of memory for my simple mesh, so I must be doing something very wrong.

Thanks.

EDIT 1: I call glGetError after every frame, but since this is the only OpenGL I do in the entire program it shouldn't be a problem

//when loading the mesh we create the VBO
void createBuffer()
{
    GLuint buf;
    glGenBuffers(1, &buf);
    glBindBuffer(GL_ARRAY_BUFFER, buf);
    glBufferData(GL_ARRAY_BUFFER, vertNormalBuffer->size() * sizeof(GLfloat), (GLvoid*) bufferData, GL_STATIC_DRAW);

    //EDIT 1: forgot to show how I handle the buffer
    model->vertexNormalBuffer = &buf;
    //Unbinds it
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}


void Fighter::doRedraw(GLuint shaderProgram)
{
    glm::mat4 transformationMatrix = getTransform();
    GLuint loc = glGetUniformLocation(shaderProgram,"modelviewMatrix");
    glUniformMatrix4fv(loc, 1, GL_FALSE, (GLfloat*) &transformationMatrix);

    glBindBuffer(GL_ARRAY_BUFFER, *model->vertexNormalBuffer);

    //If I uncomment this line below all works wonderfully, but isnt the purpose of VBO of not uploading the same data again and again?
    //glBufferData(GL_ARRAY_BUFFER, model->vertAndNormalArraySize * sizeof(GLfloat), model->vertAndNormalArray, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(2);

    renderChild(model, model);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Fighter::renderChild(ModelObject* model, ModelObject* parent)
{
    //Recursively render the mesh children
    for(int i = 0; i < model->nChildren; i++)
    {
        renderChild( dynamic_cast<ModelObject*>(model->children[i]), parent);
    }
    //Vertex and normal data are interlieved
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat),(void*)(model-            >vertexDataPosition*sizeof(GLfloat)));
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)((model->vertexDataPosition + 4)*sizeof(GLfloat)));

    //Draws using two sets of indices
    glDrawElements(GL_QUADS,  model->nQuads * 4, GL_UNSIGNED_INT,(void*) model->quadsIndices);
    glDrawElements(GL_TRIANGLES, model->nTriangles * 3, GL_UNSIGNED_INT, (void*) model->trisIndices);

}
Was it helpful?

Solution

This is your problem:

model->vertexNormalBuffer = &buf;
/* ... */
glBindBuffer(GL_ARRAY_BUFFER, *model->vertexNormalBuffer);

You're storing the address of your buf variable, rather than its contents, and then it falls out of scope when createBuffer returns, and is most likely overwritten with other data, so when you're later rendering, you're using an uninitialized buffer. Just store the contents of buf in your vertexNormalBuffer field instead.

I'll admit I don't know why OpenGL thinks it proper to say that it's "out of memory" just because of that, but perhaps you're just invoking undefined behavior. It does explain, however, why it starts working when you re-fill the buffer with data after you rebind it, because you then implicitly initialize the buffer that you just bound.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top