I am trying to read the color buffer content of the default framebuffer in PyQt5 using pixel buffer object given by the Qt OpenGL framework.
It looks like the reading is unsuccessful because the end image always contains all zeros. There's very little examples with pixel buffers and PyQt5, so I was mostly relying on this c++ tutorial explaining pixel buffers, specifically section Example: Asynchronous Read-back
.
My code goes something like this:
class GLCanvas(QtWidgets.QOpenGLWidget):
# ...
def screenDump(self):
"""
Takes a screenshot and returns a pixmap.
:returns: A pixmap with the rendered content.
:rtype: QPixmap
"""
self.makeCurrent()
w = self.size().width()
h = self.size().height()
ppo = QtGui.QOpenGLBuffer(QtGui.QOpenGLBuffer.PixelPackBuffer)
ppo.setUsagePattern(QOpenGLBuffer.StaticRead)
ppo.create()
success = ppo.bind()
if success:
ppo.allocate(w * h * 4)
# Render the stuff
# ...
# Read the color buffer.
glReadBuffer(GL_FRONT)
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0)
# TRY1: Create an image with pixel buffer data - Doesn't work, image contains all zeros.
pixel_buffer_mapped = ppo.map(QOpenGLBuffer.ReadOnly)
image = QtGui.QImage(sip.voidptr(pixel_buffer_mapped), w, h, QtGui.QImage.Format_ARGB32)
ppo.unmap()
# TRY2: Create an image with pixel buffer data - Doesn't work, image contains all zeros.
# image = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32)
# bits = image.constBits()
# ppo.read(0, bits, w * h * 4)
ppo.release()
pixmap = QtGui.QPixmap.fromImage(image)
return pixmap
Any help would be greatly appreciated.
I didn't have any success after a couple of days, so I decided to implement color buffer fetching with pixel buffer object in C++, and then use SWIG to pass the data to Python.
I'm posting relevant code, maybe it will help somebody.
CPP side
Python side