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