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 300 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.
  • V Offline
    V Offline
    vikramg
    wrote on 19 Sept 2024, 00:18 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
    • V Offline
      V Offline
      vikramg
      wrote on 27 Sept 2024, 22:19 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
      • V vikramg has marked this topic as solved on 27 Sept 2024, 22:19

      • Login

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