self.openGLWidget如何添加三维图像
时间: 2023-12-12 22:05:47 浏览: 157
要在 `QOpenGLWidget` 中添加三维图像,你需要使用一些三维图像渲染库,比如OpenGL或者Qt3D等库。下面是一个基本的示例代码,展示如何在 `QOpenGLWidget` 中添加一个简单的三维图形:
```python
from PyQt5.QtGui import QOpenGLShader, QOpenGLShaderProgram, QOpenGLTexture
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
from PyQt5.QtCore import Qt, QCoreApplication
import numpy as np
import OpenGL.GL as gl
class MyOpenGLWidget(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
# 初始化三维图像
self.vertices = np.array([
[-1.0, -1.0, 1.0],
[ 1.0, -1.0, 1.0],
[ 1.0, 1.0, 1.0],
[-1.0, 1.0, 1.0],
[-1.0, -1.0, -1.0],
[ 1.0, -1.0, -1.0],
[ 1.0, 1.0, -1.0],
[-1.0, 1.0, -1.0]
]).astype(np.float32)
self.indices = np.array([
[0, 1, 2], [2, 3, 0],
[1, 5, 6], [6, 2, 1],
[7, 6, 5], [5, 4, 7],
[4, 0, 3], [3, 7, 4],
[4, 5, 1], [1, 0, 4],
[3, 2, 6], [6, 7, 3]
]).astype(np.uint32)
# 初始化着色器程序
self.shader_program = QOpenGLShaderProgram(self)
vertex_shader = QOpenGLShader(QOpenGLShader.Vertex, self)
vertex_shader.compileSourceCode("""
attribute vec3 a_position;
uniform mat4 u_mvp_matrix;
void main() {
gl_Position = u_mvp_matrix * vec4(a_position, 1.0);
}
""")
fragment_shader = QOpenGLShader(QOpenGLShader.Fragment, self)
fragment_shader.compileSourceCode("""
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
""")
self.shader_program.addShader(vertex_shader)
self.shader_program.addShader(fragment_shader)
self.shader_program.link()
# 初始化纹理
self.texture = QOpenGLTexture(QOpenGLTexture.Target2D)
self.texture.setData(QCoreApplication.instance().applicationDirPath() + "/texture.jpg")
# 设置背景颜色
self.setBackgroundColor(Qt.black)
def setBackgroundColor(self, color):
r, g, b, a = color.getRgbF()
gl.glClearColor(r, g, b, a)
def initializeGL(self):
gl.glEnable(gl.GL_DEPTH_TEST) # 启用深度测试
def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
self.shader_program.bind()
self.shader_program.enableAttributeArray("a_position")
self.shader_program.setAttributeArray("a_position", self.vertices)
mvp_matrix = np.eye(4, dtype=np.float32)
aspect_ratio = self.width() / self.height()
mvp_matrix = np.dot(mvp_matrix, self.getProjectionMatrix(aspect_ratio))
mvp_matrix = np.dot(mvp_matrix, self.getViewMatrix())
self.shader_program.setUniformValue("u_mvp_matrix", mvp_matrix)
self.texture.bind()
gl.glDrawElements(gl.GL_TRIANGLES, self.indices.size, gl.GL_UNSIGNED_INT, self.indices)
def getProjectionMatrix(self, aspect_ratio):
fov = 45.0
znear = 0.1
zfar = 100.0
projection_matrix = np.zeros((4, 4), dtype=np.float32)
tan_half_fov = np.tan(np.deg2rad(fov / 2.0))
projection_matrix[0, 0] = 1.0 / (tan_half_fov * aspect_ratio)
projection_matrix[1, 1] = 1.0 / tan_half_fov
projection_matrix[2, 2] = -(zfar + znear) / (zfar - znear)
projection_matrix[2, 3] = -2.0 * zfar * znear / (zfar - znear)
projection_matrix[3, 2] = -1.0
return projection_matrix
def getViewMatrix(self):
eye = np.array([0.0, 0.0, 5.0])
target = np.array([0.0, 0.0, 0.0])
up = np.array([0.0, 1.0, 0.0])
view_matrix = np.zeros((4, 4), dtype=np.float32)
view_matrix[:3, :3] = self.getLookAtMatrix(eye, target, up)
view_matrix[:3, 3] = eye
view_matrix[3, 3] = 1.0
return view_matrix
def getLookAtMatrix(self, eye, target, up):
forward = target - eye
forward = forward / np.linalg.norm(forward)
side = np.cross(forward, up)
side = side / np.linalg.norm(side)
up = np.cross(side, forward)
up = up / np.linalg.norm(up)
look_at_matrix = np.zeros((4, 4), dtype=np.float32)
look_at_matrix[0, :3] = side
look_at_matrix[1, :3] = up
look_at_matrix[2, :3] = -forward
look_at_matrix[3, 3] = 1.0
return look_at_matrix
if __name__ == '__main__':
app = QApplication([])
w = MyOpenGLWidget()
w.show()
app.exec_()
```
该示例代码展示了如何在 `QOpenGLWidget` 中绘制一个简单的立方体,并使用着色器程序和纹理进行渲染。你可以根据需要修改代码,来绘制你自己的三维图形。
阅读全文