pyqt 使用openglwidget导入obj模型
时间: 2023-05-17 19:02:37 浏览: 168
QT+OpenGL读obj模型
5星 · 资源好评率100%
可以使用 PyOpenGL 库来加载和渲染 obj 模型,然后将其嵌入到 PyQt 的 OpenGLWidget 中。以下是一个简单的示例代码:
```python
from PyQt5.QtWidgets import QApplication, QMainWindow, QOpenGLWidget
from PyQt5.QtGui import QOpenGLShader, QOpenGLShaderProgram
from PyQt5.QtCore import Qt
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys
class MyOpenGLWidget(QOpenGLWidget):
def __init__(self, parent=None):
super(MyOpenGLWidget, self).__init__(parent)
self.vertices = []
self.normals = []
self.texcoords = []
self.indices = []
self.shaderProgram = None
self.vbo = None
self.vao = None
def initializeGL(self):
glClearColor(0.0, 0.0, 0.0, 1.0)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_TEXTURE_2D)
self.loadObj('model.obj')
self.initShader()
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0.0, 0.0, -10.0)
glRotatef(30, 1.0, 0.0, 0.0)
glRotatef(30, 0.0, 1.0, 0.0)
self.shaderProgram.bind()
self.vao.bind()
glDrawElements(GL_TRIANGLES, len(self.indices), GL_UNSIGNED_INT, None)
self.vao.release()
self.shaderProgram.release()
def resizeGL(self, w, h):
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, w / h, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
def loadObj(self, filename):
with open(filename, 'r') as f:
for line in f:
if line.startswith('v '):
self.vertices.append(list(map(float, line.split()[1:])))
elif line.startswith('vn '):
self.normals.append(list(map(float, line.split()[1:])))
elif line.startswith('vt '):
self.texcoords.append(list(map(float, line.split()[1:])))
elif line.startswith('f '):
face = line.split()[1:]
for i in range(1, len(face) - 1):
self.indices.append(int(face[0].split('/')[0]) - 1)
self.indices.append(int(face[i].split('/')[0]) - 1)
self.indices.append(int(face[i + 1].split('/')[0]) - 1)
def initShader(self):
vertexShader = QOpenGLShader(QOpenGLShader.Vertex, self)
vertexShader.compileSourceCode('''
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_texcoord;
uniform mat4 u_mvpMatrix;
varying vec3 v_normal;
varying vec2 v_texcoord;
void main() {
gl_Position = u_mvpMatrix * vec4(a_position, 1.0);
v_normal = a_normal;
v_texcoord = a_texcoord;
}
''')
fragmentShader = QOpenGLShader(QOpenGLShader.Fragment, self)
fragmentShader.compileSourceCode('''
varying vec3 v_normal;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0));
vec3 normal = normalize(v_normal);
float diffuse = max(dot(normal, lightDir), 0.0);
vec4 texel = texture2D(u_texture, v_texcoord);
gl_FragColor = vec4(texel.rgb * diffuse, texel.a);
}
''')
self.shaderProgram = QOpenGLShaderProgram(self)
self.shaderProgram.addShader(vertexShader)
self.shaderProgram.addShader(fragmentShader)
self.shaderProgram.link()
self.shaderProgram.bind()
self.vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBufferData(GL_ARRAY_BUFFER, len(self.vertices) * 12 + len(self.normals) * 12 + len(self.texcoords) * 8, None, GL_STATIC_DRAW)
glBufferSubData(GL_ARRAY_BUFFER, 0, len(self.vertices) * 12, (GLfloat * len(self.vertices) * 3)(*self.vertices))
glBufferSubData(GL_ARRAY_BUFFER, len(self.vertices) * 12, len(self.normals) * 12, (GLfloat * len(self.normals) * 3)(*self.normals))
glBufferSubData(GL_ARRAY_BUFFER, len(self.vertices) * 12 + len(self.normals) * 12, len(self.texcoords) * 8, (GLfloat * len(self.texcoords) * 2)(*self.texcoords))
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glEnableVertexAttribArray(2)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(len(self.vertices) * 12))
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(len(self.vertices) * 12 + len(self.normals) * 12))
glBindVertexArray(0)
self.shaderProgram.release()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = QMainWindow()
glWidget = MyOpenGLWidget(mainWindow)
mainWindow.setCentralWidget(glWidget)
mainWindow.resize(640, 480)
mainWindow.show()
sys.exit(app.exec_())
```
这个例子中,我们使用 PyOpenGL 库来加载 obj 模型文件,并将其渲染到 PyQt 的 OpenGLWidget 中。我们还使用了 GLSL 着色器来实现光照和纹理映射。
阅读全文