Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt with OpenGL: bind/release of Index Array Object
Forum Updated to NodeBB v4.3 + New Features

Qt with OpenGL: bind/release of Index Array Object

Scheduled Pinned Locked Moved Solved General and Desktop
2 Posts 1 Posters 345 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • vikramgV Offline
    vikramgV Offline
    vikramg
    wrote on last edited by
    #1

    I have been following this answer for custom OpenGL rendering to a QML Item via QQuickFrameBufferObject. Briefly, the setup described is:

    vao.create();
    vao.bind();
    
    // Prepare shaders
    shaderpgm.addShader(...);
    shaderpgm.link();
    
    // Prepare vertex array, VBO
    vbo.create();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.bind();    
    vbo.allocate(vertices.data(), vertices.size()*sizeof(GLfloat));
    vbo.release();
    
    // Set shader attribs
    shaderpgm.bind();
    
    vbo.bind();
    shaderProgram.enableAttributeArray("vertex");
    shaderProgram.setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
    vbo.release();
    
    shaderpgm.release();
    vao.release();
    

    In the render function we have:

    vao.bind();
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());
    vao.release();
    

    This makes sense, and works fine. However, this scheme does not seem to work for an Index Buffer Object. I thought that all that would be needed is to bind/allocate/release the IBO while the VAO is bound and that would take care of it (and of course, the glDrawArrays changes to glDrawElements). Like so:

    vao.create();
    vao.bind();
    ...
    ibo.create();
    ibo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    ibo.bind();    
    ibo.allocate(indices.data(), indices.size()*sizeof(GLuint));
    ibo.release();
    ...
    vao.release();
    

    However this does not work. After some trial and error, I found that either of the two following solutions work:

    1. Do not release the ibo in the above setup:

    ibo.create(); ibo.setUsagePattern(QOpenGLBuffer::StaticDraw); ibo.bind(); ibo.allocate(indices.data(), indices.size()*sizeof(GLuint));
    ibo.release();

    1. Or, do release it as before, but bind it again in the render call:
    vao.bind();
    ibo.bind();
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    ibo.release();
    vao.release();
    

    Why is this different for the IBO compared to the VBOs? I had thought that as long as the VAO is bound when you create various buffers, all of those get associated with that VAO, and in the render call you only need to bind/release the VAO.

    1 Reply Last reply
    0
    • vikramgV Offline
      vikramgV Offline
      vikramg
      wrote on last edited by
      #2

      Turns out this is a quirk of OpenGL, and IBOs and VBOs are indeed different internally. From here:

      For VBO: it is the call to glVertexAttribPointer (done in QOpenGLProgram::setAttributeArray) that establishes the VBO bind within the VAO. glVertexAttribPointer(i, ...) is the same as vao.attributes[i].vbo = vbo; where i is the attribute index.

      Otoh the IBO bind glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) is directly stored inside the VAO. i.e.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); is the same as vao.ibo = ibo;

      VBOs can be unbound but IBOs must not.

      1 Reply Last reply
      1
      • vikramgV vikramg has marked this topic as solved on

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved