0
\$\begingroup\$

I am very new to open gl and am struggling to understand relation between vaos vbos and ibos like how is currently bound vao related to currently bound ibo?

now i am trying to render 4 triangles with vertex data and index data for ibo as

float vertices[] = {
        -0.5f, -0.5f,  2.0f,     1.0f, 0.0f, 0.0f ,1.0,
         0.5f, -0.5f,  2.0f,     0.0f, 1.0f, 0.0f ,1.0,
         0.0f,  0.5f,  2.0f,     0.0f, 0.0f, 1.0f ,1.0,

         0.0f,  0.0f,  1.0f,     1.0f, 1.0f, 0.0f ,1.0,
         0.0f,  0.0f,  3.0f,     0.0f, 1.0f, 1.0f ,1.0,
         0.0f, -1.0f,  2.0f,     1.0f, 0.0f, 1.0f ,1.0,
    };

    float vertices1[] = {
        -0.5f, -0.5f,  0.0f,     1.0f, 0.0f, 0.0f ,1.0,
         0.5f, -0.5f,  0.0f,     0.0f, 1.0f, 0.0f ,1.0,
         0.0f,  0.5f,  0.0f,     0.0f, 0.0f, 1.0f ,1.0,

         0.0f,  0.0f, -1.0f,     1.0f, 1.0f, 0.0f ,1.0,
         0.0f,  0.0f,  1.0f,     0.0f, 1.0f, 1.0f ,1.0,
         0.0f, -1.0f,  0.0f,     1.0f, 0.0f, 1.0f ,1.0
    };

    unsigned indices[] = {
        0,1,2,3,4,5
    };

    unsigned indices1[] = {
         0,1,
         1,2,
         2,0,
         3,4,
         4,5,
         5,3
    };

and i am creating vaos and ibos as:

unsigned int VBO[2], VAO[2], IBO[2];
    glGenVertexArrays(2, VAO);
    glGenBuffers(2, VBO);
    glGenBuffers(2, IBO);
    glBindVertexArray(VAO[0]);

    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);



    glBindVertexArray(VAO[1]);

    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

And I am drawing it as:

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
        glBindVertexArray(VAO[0]);

        glDrawElements(GL_TRIANGLES, sizeof(indices1) / sizeof(unsigned), GL_UNSIGNED_INT, 0);

        glBindVertexArray(0));
        //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[1]);
        glBindVertexArray(VAO[1]);

        glDrawElements(GL_LINES, sizeof(indices1)/sizeof(unsigned), GL_UNSIGNED_INT, 0);

        glBindVertexArray(0));
        //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

If i dont unbind vao in the draw call then it will not be drawn as expected i.e. partially drawn lines or missing triangles. Are'nt vaos supposed to override any previous bindings and bind a new one specified? Even if i dont unbind vao after setting glVertexAttribPointer I get a blank screen! Then I got Totally confused on when to bind before doing what. What does vao hold other than vertex attribute?like can i unbind ibo before vao?

\$\endgroup\$
1
  • \$\begingroup\$ If you are not restricted to an older OpenGL version i highly recommend you to use the new OpenGL 4.5 Direct State Access. At least for me the whole VBO/VAO thing felt a lot more intuitive and easier to understand using those functions instead. \$\endgroup\$
    – Eric
    May 30 '20 at 15:44
0
\$\begingroup\$

I don't do it that way any more. In cases when the shader-pipeline doesn't change and the interface (vertex attributes) from the application stays the same one can create a vao and just switch the buffers before the draw calls. Example with plain c-code, to sketch the way, OpenGL 4.5, a vertex array with a static and a dynamic buffer and one vertex attribute, for brevity:

// Configure vertex array and buffers
glCreateVertexArrays( 1, &(i->vertex_array) );
// Only one vec4f attrib: .xy = coords, .zw = texture coords from font atlas
glVertexArrayAttribFormat( i->vertex_array, 0, 4, GL_FLOAT, GL_FALSE, 0 );
glEnableVertexArrayAttrib( i->vertex_array, 0 );
glCreateBuffers( 1, &(i->static_vertex_buffer) );
glCreateBuffers( 1, &(i->dynamic_vertex_buffer) );

Copy in static data to the static buffer (1 time only):

glNamedBufferData( in->static_vertex_buffer, (GLsizeiptr)buffer_size, buf, GL_STATIC_DRAW );

Prepare dynamic buffer storage. Size cannot be changed later, contents can:

glNamedBufferStorage( in->dynamic_vertex_buffer, size, NULL, GL_MAP_WRITE_BIT );

Every frame, update dynamic buffer:

// obtain a pointer
vec4f* buf = glMapNamedBuffer( in->dynamic_vertex_buffer, GL_WRITE_ONLY );
// ... use the pointer to write to the buffer, e.g. via memcpy() ...
if( GL_TRUE != glUnmapNamedBuffer( in->dynamic_vertex_buffer ) )
    // do something about it

And in the draw you just bind the array. You can switch the buffers as needed:

// draw static and dynamic buffer
glBindVertexArray( i->vertex_array );
glVertexArrayVertexBuffer( i->vertex_array, 0, i->static_vertex_buffer, 0, sizeof( vec4f ) );
glDrawArrays( GL_TRIANGLES, 0, i->num_static_vertices );
glVertexArrayVertexBuffer( i->vertex_array, 0, i->dynamic_vertex_buffer, 0, sizeof( vec4f ) );
glDrawArrays( GL_TRIANGLES, 0, i->num_dynamic_vertices );

If you draw elements you glCreateBuffer it once and connect it to the vao via glVertexArrayElementBuffer. If its contents change map/write/unmap as above. During drawing, just use the shader and the vao and switch buffers as needed, or keep them when they don't change.

Don't forget error checking the return value of glUnmapBuffer.

Hope that clarifies.

\$\endgroup\$

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.