Binding issue with glDrawElements

Phil Thompson phil at riverbankcomputing.com
Sat Oct 19 16:14:45 BST 2024


I think it depends on how you interpret the meanings of the 'indices' 
argument to glDrawElements() and the 'pointer' argument to 
glVertexAttribPointer(). My reading is that they are different - the 
former is simply an array of indices and the latter is a similar array 
*or* an offset into a previously bound array. My understanding of OpenGL 
is very limited so please correct me if I am wrong.

By the way there is a bug (fixed in the next snapshot) that causes a 
crash if the array (in either case) is passed as a bytes object.

Phil

On 13/10/2024 12:54, Ognyan Moore wrote:
> Hello,
> 
> There seems to be an issue with the binding on glDrawElements, 
> specifically
> the indices attribute.  Issue can be demonstrated w/ the following 
> code:
> 
> import struct
> 
> from PyQt6 import QtGui, QtOpenGL
> OFFSET = lambda x : x
> 
> # from PySide6 import QtGui, QtOpenGL
> # from shiboken6 import VoidPtr
> # OFFSET = lambda x : VoidPtr(x)
> 
> class MyWidget(QtOpenGL.QOpenGLWindow):
>     def initializeGL(self):
>         vtx = struct.pack('9f', 0, -1, -1, 1, -1, -1, 1, 1, 1)  # 1 
> bogus
> float in front
>         ind = struct.pack('6H', 0, 1, 2, 2, 3, 1)
> 
>         self.m_vbo =
> QtOpenGL.QOpenGLBuffer(QtOpenGL.QOpenGLBuffer.Type.VertexBuffer)
>         self.m_vbo.create()
>         self.m_vbo.bind()
>         self.m_vbo.allocate(vtx, len(vtx))
> 
>         self.m_ibo =
> QtOpenGL.QOpenGLBuffer(QtOpenGL.QOpenGLBuffer.Type.IndexBuffer)
>         self.m_ibo.create()
>         self.m_ibo.bind()
>         self.m_ibo.allocate(ind, len(ind))
> 
>         GL = self.get_functions()
>         GL.glEnableVertexAttribArray(0)
>         # specifying an integer offset to skip past the bogus float 
> works
> for glVertexAttribPointer
>         GL.glVertexAttribPointer(0, 2, 0x1406, False, 0, OFFSET(4))
> 
>     def get_functions(self):
>         vp = QtOpenGL.QOpenGLVersionProfile()
>         vp.setVersion(2, 0)
>         return QtOpenGL.QOpenGLVersionFunctionsFactory.get(vp,
> self.context())
> 
>     def paintGL(self):
>         GL = self.get_functions()
>         GL.glClear(0x4000)
> 
>         # draw 2 triangles separately to demonstrate the issue
> 
>         try:
>             # unlike the binding for glVertexAttribPointer, we are not 
> able
> to
>             # supply an integer offset.
>             GL.glColor3f(1, 0, 0)
>             GL.glDrawElements(4, 3, 0x1403, OFFSET(None))
> 
>             GL.glColor3f(0, 1, 0)
>             GL.glDrawElements(4, 3, 0x1403, OFFSET(6))
>         except TypeError as e:
>             # should have been defined as PYQT_OPENGL_BOUND_ARRAY?
>             print(e)
> 
> app = QtGui.QGuiApplication([])
> win = MyWidget()
> win.show()
> app.exec()
> 
> 
> the except TypeError as e: print(e) outputs the following:
> 
> glDrawElements(self, mode: int, count: int, type: int, indices:
> PYQT_OPENGL_ARRAY):
> glDrawElements(self, mode: int, count: int, type: int, indices:
> PYQT_OPENGL_ARRAY):
> 
> the OpenGL docs
> <https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDrawElements.xhtml>
> indicate it should be a pointer to the location where the indices are
> stored. With the pyside bindings, using VoidPtr(x) seems to be 
> sufficient.
> When using PyQt bindings, in other places we've often gotten what's 
> needed
> for similar arguments using lambda expressions, which we expected to be
> able to do the same here as well.
> 
> Thanks,
> Ogi


More information about the PyQt mailing list