Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-666

QOpenGLFunctions.glDrawElements doesn't work with buffers

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 5.9
    • Fix Version/s: None
    • Component/s: PySide
    • Labels:
    • Environment:
      Linux x86_64

      Python 3.6
    • Commits:
      7ff4d98f9314c75cdb4cb22c65e02637b6357b88

      Description

      When calling glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) with 'indices' being an offset in a bound buffer, the binding code fails.

      In current state, the binding only accepts a pointer to an array of indices, for instance an array.array('I', ...). This is fine for direct rendering.

      However, when an index buffer is bound to the opengl context with QOpenGLBuffer.bind() with the buffer type being QOpenGLBuffer.IndexBuffer, the OpenGL semantic is that 'indices' become a byte offset into the bound buffer.

      Unfortunately, it is not possible to pass such an offset to the binding:

      • glDrawElements(GL.GL_POINTS, 10, GL.GL_UNSIGNED_INT, 0): this fails (or any other numeric input) because the binding expect a pointer
      • glDrawElements(GL.GL_POINTS, 10, GL.GL_UNSIGNED_INT, None): this fails too
      • glDrawElements(GL.GL_POINTS, 10, GL.GL_UNSIGNED_INT, ctypes.c_void_p(...)): this fails also because it's not possible to pass a null pointer or a pointer to an invalid memory address (such as 0 or 1000).

      I did a quick hack as follow (adding a new function variant to accept numbers instead of array pointers), and it works in both cases now:

       

        <object-type name="QOpenGLFunctions" since="5.0">
      
            <add-function signature="glDrawElements(int,unsigned int,int,unsigned int)">
                 <inject-code class="target" position="beginning">
                     %BEGIN_ALLOW_THREADS
                     %CPPSELF.%FUNCTION_NAME(%1, %2, %3, (const GLvoid*)((size_t)%4));
                     %END_ALLOW_THREADS
                 </inject-code>
             </add-function>
      
        </object-type>
      

       

      The catch is that it's unsafe to pass a number if no opengl index buffer is bound to the context. Maybe that should be checked?

      This kind of logic is also necessary for (non exhaustive):

      • glDrawElementsBaseVertex
      • glDrawElementsInstanced
      • glDrawElementsInstancedBaseInstance
      • glDrawElementsInstancedBaseVertex
      • glDrawElementsInstancedBaseVertexBaseInstance
      • glDrawRangeElements
      • glDrawRangeElementsBaseVertex

       

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            crmaurei Cristian Maureira-Fredes
            Reporter:
            nitrotm Antony Ducommun
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes