我想使用PyQT5和OpenGL来创建一个应该在Raspberry Pi Zero上运行Raspbian的交互式应用程序。
第一步是在屏幕上显示图像纹理,但这已经失败,并在Pi上显示错误消息。 (见下文)
然而,在我的Ubuntu开发机器上使用OpenGL 2.0配置文件执行它时运行正常。
#!/usr/bin/env python
import sys
from PIL import Image
from PyQt5.QtCore import QSize, Qt
from PyQt5.QtGui import (QColor, QSurfaceFormat, QOpenGLVersionProfile)
from PyQt5.QtWidgets import QApplication, QGridLayout, QOpenGLWidget, QWidget
class GLWidget(QOpenGLWidget):
def __init__(self, path, width, height, parent=None):
super(GLWidget, self).__init__(parent)
self.path = path
self.width = width
self.height = height
self.texture_array = []
self.current_texture_index = 0
self.fps = 0
self.elapsed = 0
self.clearColor = QColor(Qt.black)
def sizeHint(self):
return QSize(self.width, self.height)
def initializeGL(self):
version = QOpenGLVersionProfile()
version.setVersion(2, 0)
self.gl = self.context().versionFunctions(version)
self.gl.initializeOpenGLFunctions()
self.gl.glEnable(self.gl.GL_DEPTH_TEST)
self.gl.glEnable(self.gl.GL_TEXTURE_2D)
self.gl.glClearColor(self.clearColor.redF(), self.clearColor.greenF(),
self.clearColor.blueF(), self.clearColor.alphaF())
img = Image.open(self.path)
img_data = img.convert("RGBA").tobytes("raw", "RGBA")
self.texture_array.append(self.frameToTex(img_data, self.width, self.height))
def frameToTex(self, data, width, height):
texture_id = self.gl.glGenTextures(1)
self.gl.glBindTexture(self.gl.GL_TEXTURE_2D, texture_id)
self.gl.glTexParameterf(self.gl.GL_TEXTURE_2D, self.gl.GL_TEXTURE_MIN_FILTER, self.gl.GL_LINEAR_MIPMAP_LINEAR)
self.gl.glTexParameterf(self.gl.GL_TEXTURE_2D, self.gl.GL_TEXTURE_MAG_FILTER, self.gl.GL_LINEAR)
self.gl.glTexParameteri(self.gl.GL_TEXTURE_2D, self.gl.GL_GENERATE_MIPMAP, self.gl.GL_TRUE)
self.gl.glTexImage2D(self.gl.GL_TEXTURE_2D, 0, self.gl.GL_RGBA, width,
height, 0, self.gl.GL_RGBA, self.gl.GL_UNSIGNED_BYTE,
data)
return texture_id
def paintGL(self):
self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
self.gl.glMatrixMode(self.gl.GL_MODELVIEW)
self.gl.glLoadIdentity()
self.gl.glBindTexture(self.gl.GL_TEXTURE_2D, self.texture_array[self.current_texture_index])
self.gl.glRotatef(-90, 0.0, 0.0, 1.0)
self.gl.glBegin(self.gl.GL_QUADS)
self.gl.glTexCoord2f(0.0, 0.0)
self.gl.glVertex2f(-1.0, -1.0)
self.gl.glTexCoord2f(0.0, 1.0)
self.gl.glVertex2f(1.0, -1.0)
self.gl.glTexCoord2f(1.0, 1.0)
self.gl.glVertex2f(1.0, 1.0)
self.gl.glTexCoord2f(1.0, 0.0)
self.gl.glVertex2f(-1.0, 1.0)
self.gl.glEnd()
def resizeGL(self, width, height):
side = min(width, height)
self.gl.glViewport((width - side) // 2, (height - side) // 2, side,
side)
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
main_layout = QGridLayout()
main_layout.setContentsMargins(0, 0, 0, 0)
widget = GLWidget('images/bg.jpg', 800, 480)
main_layout.addWidget(widget)
self.setLayout(main_layout)
self.currentGlWidget = widget
self.setWindowTitle("Texture Test")
def setCurrentGlWidget(self):
self.currentGlWidget = self.sender()
if __name__ == '__main__':
app = QApplication(sys.argv)
format = QSurfaceFormat()
format.setDepthBufferSize(24)
QSurfaceFormat.setDefaultFormat(format)
window = Window()
window.show()
sys.exit(app.exec_())
在RPI上执行此代码时不起作用。显示以下错误:
$ python3 GLWidget.py
MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
MESA-LOADER: failed to retrieve device information
Traceback (most recent call last):
File "GLWidget.py", line 43, in initializeGL
self.texture_array.append(self.frameToTex(img_data, self.width, self.height))
File "GLWidget.py", line 46, in frameToTex
texture_id = self.gl.glGenTextures(1)
TypeError: QOpenGLFunctions_ES2.glGenTextures(): not enough arguments
Abort
我查看了两个绑定的签名:
void glGenTextures(GLsizei n, SIP_PYOBJECT *textures /TypeHint="Union[int, Tuple[int, ...]]"/);
void glGenTextures(GLsizei n, SIP_PYOBJECT textures /TypeHint="Union[int, Tuple[int, ...]]"/);
由于不熟悉python-sip,我尝试使用int-array并将其传递给glGenTexturesleads但没有成功。该数组仍为空。
如何使用PyQT5的RPI OpenGL支持,特别是显示简单的图像纹理?