PyQt5 应用程序中的极简 PyOpenGL 示例
minimalist PyOpenGL example in PyQt5 application
我正在学习 PyOpenGL
并将其用于 PyQt5
应用程序。我正在尝试将我的一些旧的简单示例从 C++
/Qt
转换为 Python
。以下示例应在黑色背景上绘制白色三角形。至少在相应的 C++
/Qt
代码中是这样。但它什么都不做,只是一个黑色window。有什么想法我想念的吗?请注意,我需要使用着色器的 'modern' 方法(但据我所知 - 我可能是错的 - 以下代码应该只使用默认的普通着色器,即 2D 中的白色)而不是所有旧的 glBegin()
, glEnd()
.
import numpy as np
from OpenGL import GL
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
class OpenGLWidget(QOpenGLWidget):
def initializeGL(self):
vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)
bufferId = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.size, vertices, GL.GL_STATIC_DRAW)
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, 0)
def paintGL(self):
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()
好的,终于,我发现了我的错误:
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW) # nbytes instead of size
和
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None) # i.e. None instead of 0
完整的简约示例如下:
import numpy as np
from OpenGL import GL
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
class OpenGLWidget(QOpenGLWidget):
def initializeGL(self):
vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)
bufferId = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW)
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None)
def paintGL(self):
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()
请注意,这不符合 'best practice' - 您应该使用着色器和 VAO!这段代码真的只是最短的可能...
如果你使用 PySide2(它是 Qt 的官方绑定)你需要写这行代码
QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
main.py
import numpy as np
from OpenGL import GL
from PySide2.QtWidgets import QOpenGLWidget, QApplication
from PySide2.QtCore import Qt
class OpenGLWidget(QOpenGLWidget):
def initializeGL(self):
vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)
bufferId = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW)
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None)
def paintGL(self):
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()
我正在学习 PyOpenGL
并将其用于 PyQt5
应用程序。我正在尝试将我的一些旧的简单示例从 C++
/Qt
转换为 Python
。以下示例应在黑色背景上绘制白色三角形。至少在相应的 C++
/Qt
代码中是这样。但它什么都不做,只是一个黑色window。有什么想法我想念的吗?请注意,我需要使用着色器的 'modern' 方法(但据我所知 - 我可能是错的 - 以下代码应该只使用默认的普通着色器,即 2D 中的白色)而不是所有旧的 glBegin()
, glEnd()
.
import numpy as np
from OpenGL import GL
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
class OpenGLWidget(QOpenGLWidget):
def initializeGL(self):
vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)
bufferId = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.size, vertices, GL.GL_STATIC_DRAW)
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, 0)
def paintGL(self):
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()
好的,终于,我发现了我的错误:
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW) # nbytes instead of size
和
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None) # i.e. None instead of 0
完整的简约示例如下:
import numpy as np
from OpenGL import GL
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
class OpenGLWidget(QOpenGLWidget):
def initializeGL(self):
vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)
bufferId = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW)
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None)
def paintGL(self):
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()
请注意,这不符合 'best practice' - 您应该使用着色器和 VAO!这段代码真的只是最短的可能...
如果你使用 PySide2(它是 Qt 的官方绑定)你需要写这行代码
QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
main.py
import numpy as np
from OpenGL import GL
from PySide2.QtWidgets import QOpenGLWidget, QApplication
from PySide2.QtCore import Qt
class OpenGLWidget(QOpenGLWidget):
def initializeGL(self):
vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)
bufferId = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW)
GL.glEnableVertexAttribArray(0)
GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None)
def paintGL(self):
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()