opengl vertex buffer objects

Started by
6 comments, last by RobTheBloke 10 years, 9 months ago
Hello, I want to convert vertices and colors variables to Vertex Buffer Objects (VBO). I managed to write the below code, though when program runs after a while it jumps out. Moreover, how can I make sure the VBO is created and vertices & colors are transfered to GPU? I also need to update the colors values. How can I do that when it is transfered to GPU? (but vertices is constant).




void PlanPositionIndicator::render(
QGLShaderProgram* shaderProgram)
{
    qDebug() << vertices.size() << " " << sizeof(QVector3D);

    if(!initialized)
    {
        GLuint vertexId = shaderProgram->attributeLocation("vertex");
        GLuint colorId  = shaderProgram->attributeLocation("color");

        glGenBuffers(2, VBO_ID);

        glGenVertexArrays(1, &VAO_ID);
        glBindVertexArray(VAO_ID);

        glBindBuffer(GL_ARRAY_BUFFER, VBO_ID[0]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(QVector3D)*vertices.size(), vertices.constData(), GL_STATIC_DRAW);
        glVertexAttribPointer(vertexId, 3, GL_FLOAT, GL_FALSE, 0, 0);// param - 1 ->0
        glEnableVertexAttribArray(vertexId);

        glBindBuffer(GL_ARRAY_BUFFER, VBO_ID[1]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vertices.size(), colors, GL_DYNAMIC_DRAW);
        glVertexAttribPointer(colorId, 1, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(colorId);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

    glBindVertexArray(VAO_ID);

    int vertexLocation = shaderProgram->attributeLocation("vertex");
    int colorLocation = shaderProgram->attributeLocation("color");

    shaderProgram->enableAttributeArray(vertexLocation);
    shaderProgram->enableAttributeArray(colorLocation);

//    shaderProgram->setAttributeBuffer(vertexLocation, GL_FLOAT , 0, 3, 0);
//    shaderProgram->setAttributeBuffer(colorLocation , GL_FLOAT , 0, 1, 0);

    glEnable    (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDrawArrays(GL_TRIANGLES, 0, 6*numVerts);

//    glDrawElements(GL_TRIANGLES, vertices.size(), GL_FLOAT, vertices.constData());
}
Advertisement

right now you are generating a vbo every time you draw them. on top of that from the code you gave it doesnt look like you release them.so sooner or later you should run out of VRAM.

call glBufferData or similiar whenever you want to update the data

Bingo, it works. Now I need to reduce memory. currently, it is 46%, if I clean vertices with

vertices.clear();

it will jump down to 26%. However, When I free colors with

free (colors);

the memory will not reduce and still remains at 26%, why?

Besides, I have a problem modifying the color array.


       GLuint vboId = ppi->getVBOID();

       glBindBuffer(GL_ARRAY_BUFFER, vboId);

       glBufferData( GL_ARRAY_BUFFER, ( 100 * 6 * sizeof( float ) ), buffer0, GL_DYNAMIC_DRAW );

it jumps outta program when it comes to glBindBuffer. The getVBOID() function simply return VBO_ID[1], dedicated for colors.

how could I resolve this?

Now I need to reduce memory. currently, it is 46%, if I clean vertices with

vertices.clear();

it will jump down to 26%. However, When I free colors with

free (colors);

the memory will not reduce and still remains at 26%, why?

clear() does not free memory, but free will (as will reserve(0)). I therefore am led to believe that where ever you're reading that 46% from, you're not reading an accurate value. Are you manually tracking memory usage? Are you using VLD/Valgrind?


it jumps outta program when it comes to glBindBuffer. The getVBOID() function simply return VBO_ID[1], dedicated for colors.

how could I resolve this?


For what reason? Is the glBindBuffer function pointer invalid? (which would indicate that the context has not yet been created? and your update code is being run before the windows has been created?).

Now I need to reduce memory. currently, it is 46%, if I clean vertices with

vertices.clear();

it will jump down to 26%. However, When I free colors with

free (colors);

the memory will not reduce and still remains at 26%, why?

clear() does not free memory, but free will (as will reserve(0)). I therefore am led to believe that where ever you're reading that 46% from, you're not reading an accurate value. Are you manually tracking memory usage? Are you using VLD/Valgrind?


it jumps outta program when it comes to glBindBuffer. The getVBOID() function simply return VBO_ID[1], dedicated for colors.

how could I resolve this?


For what reason? Is the glBindBuffer function pointer invalid? (which would indicate that the context has not yet been created? and your update code is being run before the windows has been created?).

I am using htop utility in Linux to monitor Memory and CPU usage.

Vertices.clear reduced memory. However, as I said free(colors) gives segmentation fault. Are we still reading from colors? I don't think so. But, wait a minute, I defined vertices to be static as its value would not change in the program. But, for colors I defined it as GL_DRAW_DYNAMIC and not STATIC. Maybe one copy of the colors variable should exist in the main memory!

about glBindBuffer(), I simply call it from another class, the thing I did is posted above. I did not delete vbo and vao ids in the render function.

Here I want to modify the value of colors, so I simply get a pointer to vbo_id[1] and write a buffer to it. but it fails.

Vertices.clear reduced memory.

Then your approach to memory profiling does not work.

However, as I said free(colors) gives segmentation fault.

Actually, you said it would make no difference to the memory usage, and now you're saying something completely different. I'm going to guess that you haven't actually allocated the memory and are trying to delete a static array for some reason?

But, for colors I defined it as GL_DRAW_DYNAMIC and not STATIC. Maybe one copy of the colors variable should exist in the main memory!

Cool story bro, but what does this have to do with your memory leak?

Here I want to modify the value of colors, so I simply get a pointer to vbo_id[1] and write a buffer to it. but it fails.

WAT? You're trying to **write** to an integer value? WAT? What's wrong with using it as an integer name for your VBO? Then you can bind the buffer, and just update via glBufferSubData. RTFM.

Vertices.clear reduced memory.

Then your approach to memory profiling does not work.

However, as I said free(colors) gives segmentation fault.

Actually, you said it would make no difference to the memory usage, and now you're saying something completely different. I'm going to guess that you haven't actually allocated the memory and are trying to delete a static array for some reason?

But, for colors I defined it as GL_DRAW_DYNAMIC and not STATIC. Maybe one copy of the colors variable should exist in the main memory!

Cool story bro, but what does this have to do with your memory leak?

Here I want to modify the value of colors, so I simply get a pointer to vbo_id[1] and write a buffer to it. but it fails.

WAT? You're trying to **write** to an integer value? WAT? What's wrong with using it as an integer name for your VBO? Then you can bind the buffer, and just update via glBufferSubData. RTFM.

Let's review again, at the beginning it is 46%. When I do free(colors) it jumps to 41%. Next, when I do vertices.clear(), it jumps to 26%.

Now, why is it still taking 26%? If I only construct my vertices and remove them all the memory is 6%, However, If I keep colors and vertices, send them to VBO with the code below and then release them all, it still stays at 26%, why? is it something else that is consuming the memory?


    if(!initialized)
    {
        GLuint vertexId = shaderProgram->attributeLocation("vertex");
        GLuint colorId  = shaderProgram->attributeLocation("color");

        glGenBuffers(2, VBO_ID);

        glGenVertexArrays(1, &VAO_ID);
        glBindVertexArray(VAO_ID);

        glBindBuffer(GL_ARRAY_BUFFER, VBO_ID[0]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(QVector3D)*verticesSize, vertices.constData(), GL_STATIC_DRAW);
        glVertexAttribPointer(vertexId, 3, GL_FLOAT, GL_FALSE, 0, 0);// param - 1 ->0
        glEnableVertexAttribArray(vertexId);

        glBindBuffer(GL_ARRAY_BUFFER, VBO_ID[1]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*verticesSize, colors, GL_STATIC_DRAW);
        glVertexAttribPointer(colorId, 1, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(colorId);

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        vertices.clear();

        free(colors);

        initialized = true;
    }

this function is called inside render() and executed only once, as the initialized variable becomes true then.

Let's review again, at the beginning it is 46%. When I do free(colors) it jumps to 41%. Next, when I do vertices.clear(), it jumps to 26%.

Now, why is it still taking 26%?

Your method of tracking memory usage within your application sucks so badly, that it is not giving you useful information. There are better tools to do this.

Who knows why it's taking 26%. It could be a driver. It could be a memory leak in your code. It could be for any number of reasons.

If I only construct my vertices and remove them all the memory is 6%, However, If I keep colors and vertices, send them to VBO with the code below and then release them all, it still stays at 26%, why? is it something else that is consuming the memory?

It's possibly consumed within a driver. But once again. Your method of tracking memory usage is not useful. There are better tools (intrusive preferably) that can help track allocations within your app. Use one of those instead of getting stuck in a loop focusing on something of little to no importance. If it runs cleanly through valgrind, you really haven't got a problem. If your driver is consuming memory, then it's also fair to assume that the behaviour is specific to your driver / video card make. There's a good chance other drivers behave differently. The problem though, is that attempting to validate what is happening in a 3rd party compiled binary will not help to improve your code whatsoever. Validate YOUR code, and move on when it works.

This topic is closed to new replies.

Advertisement