pyqt openglwidget中实现立方体的旋转
时间: 2023-05-16 14:07:42 浏览: 99
可以使用QOpenGLWidget和QOpenGLFunctions类来实现立方体的旋转。首先,需要在QOpenGLWidget的initializeGL()函数中初始化OpenGL环境,然后在paintGL()函数中绘制立方体,并在每次绘制时更新立方体的旋转角度。以下是一个简单的示例代码:
```python
from PyQt5.QtWidgets import QApplication, QOpenGLWidget
from PyQt5.QtGui import QOpenGLShader, QOpenGLShaderProgram, QOpenGLBuffer, QOpenGLVertexArrayObject
from PyQt5.QtCore import Qt, QTimer
import numpy as np
class CubeWidget(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.vertices = np.array([
[-1, -1, -1],
[1, -1, -1],
[1, 1, -1],
[-1, 1, -1],
[-1, -1, 1],
[1, -1, 1],
[1, 1, 1],
[-1, 1, 1]
], dtype=np.float32)
self.indices = np.array([
[0, 1, 2],
[0, 2, 3],
[1, 5, 6],
[1, 6, 2],
[5, 4, 7],
[5, 7, 6],
[4, 0, 3],
[4, 3, 7],
[3, 2, 6],
[3, 6, 7],
[4, 5, 1],
[4, 1, 0]
], dtype=np.uint32)
self.angle = 0
self.timer = QTimer(self)
self.timer.timeout.connect(self.update)
self.timer.start(16)
def initializeGL(self):
self.gl = self.context().versionFunctions()
self.gl.glClearColor(0.2, 0.2, 0.2, 1.0)
self.gl.glEnable(self.gl.GL_DEPTH_TEST)
self.program = QOpenGLShaderProgram(self)
self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, '''
attribute vec3 position;
uniform mat4 modelViewProjection;
void main() {
gl_Position = modelViewProjection * vec4(position, 1.0);
}
''')
self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, '''
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
''')
self.program.link()
self.vao = QOpenGLVertexArrayObject(self)
self.vao.create()
self.vao.bind()
self.vbo = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer)
self.vbo.create()
self.vbo.bind()
self.vbo.allocate(self.vertices.tobytes())
self.program.enableAttributeArray(0)
self.program.setAttributeBuffer(0, self.gl.GL_FLOAT, 0, 3)
self.ebo = QOpenGLBuffer(QOpenGLBuffer.IndexBuffer)
self.ebo.create()
self.ebo.bind()
self.ebo.allocate(self.indices.tobytes())
def paintGL(self):
self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
self.program.bind()
self.gl.glViewport(0, 0, self.width(), self.height())
projection = np.array([
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, -5.0],
[0.0, 0.0, 0.0, 1.0]
], dtype=np.float32)
model = np.array([
[np.cos(self.angle), 0.0, np.sin(self.angle), 0.0],
[0.0, 1.0, 0.0, 0.0],
[-np.sin(self.angle), 0.0, np.cos(self.angle), 0.0],
[0.0, 0.0, 0.0, 1.0]
], dtype=np.float32)
view = np.array([
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0]
], dtype=np.float32)
mvp = projection @ view @ model
self.program.setUniformValue('modelViewProjection', mvp)
self.gl.glDrawElements(self.gl.GL_TRIANGLES, len(self.indices) * 3, self.gl.GL_UNSIGNED_INT, None)
self.program.release()
self.angle += 0.01
def resizeGL(self, width, height):
self.gl.glViewport(0, 0, width, height)
if __name__ == '__main__':
app = QApplication([])
widget = CubeWidget()
widget.show()
app.exec_()
```
这个示例代码使用了numpy库来定义立方体的顶点和索引,使用QOpenGLShaderProgram类来编译和链接着色器程序,使用QOpenGLVertexArrayObject和QOpenGLBuffer类来管理顶点和索引数据,使用QTimer类来定时更新立方体的旋转角度。在paintGL()函数中,使用glDrawElements()函数来绘制立方体。
相关推荐
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)