gpt4 book ai didi

python - 将 PyOpenGL 从 PyGame 转移到 PyQt5 的困惑

转载 作者:行者123 更新时间:2023-12-01 06:24:15 26 4
gpt4 key购买 nike

我正在尝试为 PyGame PyOpenGL tutorial 拼凑示例代码进入 PyQt5 QOpenGLWidget 的示例代码。此代码的目标是设置一个角向上倾斜的立方体,以便识别相机的角度。在PyGame中工作正常,但在PyQt5版本中存在几个问题:

首先,纵横比似乎不对。其次,每次我再次激活它时,窗口都会调用paintGL。第三,对于 glTranslatef 和 glRotatef,大多数变量的传输方式不同。

我用于 PyGame 的代码:

import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *

verticies = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 2),
(1, 1, 1),
(-1, -1, 1),
(-1, 1, 1)
)

edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
(5,4),
(5,7)
)

colors = (
(1,0,0),
(0,1,0),
(0,0,1),
(0,1,0),
(1,1,1),
(0,1,1),
(1,0,0),
(0,1,0),
(0,0,1),
(1,0,0),
(1,1,1),
(0,1,1),
)

surfaces = (
(0,1,2,3),
(3,2,7,6),
(6,7,5,4),
(4,5,1,0),
(1,5,7,2),
(4,0,3,6)
)

def Cube():
glBegin(GL_QUADS)
for surface in surfaces:
x = 0
for vertex in surface:
x+=1
glColor3fv(colors[x])
glVertex3fv(verticies[vertex])
glEnd()

glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()


def main():
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glTranslatef(0,0, -10) #these two lines set the camera facing at the cube from the position 0, -10, 0.
glRotatef(-90, 2, 0, 0)

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()

if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
glTranslatef(-0.5,0,0)
if event.key == pygame.K_RIGHT:
glTranslatef(0.5,0,0)

if event.key == pygame.K_UP:
glTranslatef(0,1,0)
if event.key == pygame.K_DOWN:
glTranslatef(0,-1,0)

if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
glTranslatef(0,0,1.0)

if event.button == 5:
glTranslatef(0,0,-1.0)

#glRotatef(1, 3, 1, 1) #rotation code that was commented out.
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube()
pygame.display.flip()
pygame.time.wait(10)
main()

结果: PyGame version of the cube

PyQt5 代码:

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.uic import *

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

class mainWindow(QMainWindow): #Main class.

verticies = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 2),
(1, 1, 1),
(-1, -1, 1),
(-1, 1, 1)
)

edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
(5,4),
(5,7)
)

colors = (
(1,0,0),
(0,1,0),
(0,0,1),
(0,1,0),
(1,1,1),
(0,1,1),
(1,0,0),
(0,1,0),
(0,0,1),
(1,0,0),
(1,1,1),
(0,1,1),
)

surfaces = (
(0,1,2,3),
(3,2,7,6),
(6,7,5,4),
(4,5,1,0),
(1,5,7,2),
(4,0,3,6)
)

def __init__(self):
super(mainWindow, self).__init__()
self.width = 700 #Variables used for the setting of the size of everything
self.height = 600
self.setGeometry(0, 0, self.width, self.height) #Set the window size

def setupUI(self):
self.openGLWidget = QOpenGLWidget(self) #Create the GLWidget
self.openGLWidget.setGeometry(0, 0, self.width, self.height) #Size it the same as the window.
self.openGLWidget.initializeGL()
self.openGLWidget.resizeGL(self.width, self.height) #Resize GL's knowledge of the window to match the physical size?
self.openGLWidget.paintGL = self.paintGL #override the default function with my own?

def paintGL(self):
gluPerspective(45, self.width / self.height, 0.1, 50.0) #set perspective?
glTranslatef(0, 0, -2) #I used -10 instead of -2 in the PyGame version.
glRotatef(-90, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) #Straight from the PyGame version, with 'self' inserted occasionally

glBegin(GL_QUADS) #tell GL to draw surfaces
for surface in self.surfaces:
x = 0
for vertex in surface:
x+=1
glColor3fv(self.colors[x])
glVertex3fv(self.verticies[vertex])
glEnd() #tell GL to stop drawing surfaces

glBegin(GL_LINES) #tell GL to draw lines
for edge in self.edges:
for vertex in edge:
glVertex3fv(self.verticies[vertex])
glEnd() #tell GL to stop drawing lines.

app = QApplication([])
window = mainWindow()
window.setupUI()
window.show()
sys.exit(app.exec_())

结果:

PyQt5 version of the cube

当我切换到另一个窗口,然后切换回 Qt 窗口时,场景会更新并再次调用 PaintGL。此外,立方体似乎被压扁了,相机的行为也有所不同。我可以做什么来解决这些问题?

Python 3.8Windows 10

最佳答案

OpenGL 矩阵运算(如 gluPerspectiveglTranslateglRotate 、...)不仅仅设置矩阵。这些操作定义一个新矩阵并将当前矩阵乘以新矩阵。每次调用paintGL时,导致矩阵不断地、渐进地变化。
通过 glLoadIdentity 加载单位矩阵即可轻松解决该问题在 paintGL::

的开头
class mainWindow(QMainWindow):
# [...]

def paintGL(self):
glLoadIdentity()
gluPerspective(45, self.width / self.height, 0.1, 50.0) #set perspective?
glTranslatef(0, 0, -10) #I used -10 instead of -2 in the PyGame version.
glRotatef(-90, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.

但是Legacy OpenGL提供不同的矩阵(参见 glMatrixMode )。
建议将投影矩阵pout到当前GL_PROJECTION矩阵,将模型 View 矩阵pout到当前GL_MODELVIEW矩阵。
在调整大小事件回调 (resizeGL) 中更新视口(viewport)矩形 ( glViewport ) 和投影矩阵。在paintGL中设置模型 View 矩阵:

class mainWindow(QMainWindow):
# [...]

def setupUI(self):
# [...]

self.openGLWidget.paintGL = self.paintGL
self.openGLWidget.resizeGL = self.resizeGL

def resizeGL(self, width, height):
self.width, self.height = width, height
# update viewport
glViewport(0, 0, self.width, self.height)
# set projection matrix
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, self.width / self.height, 0.1, 50.0) #set perspective?

def paintGL(self):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -10) #I used -10 instead of -2 in the PyGame version.
glRotatef(-90, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) #Straight from the PyGame version, with 'self' inserted occasionally

glBegin(GL_QUADS) #tell GL to draw surfaces
for surface in self.surfaces:
x = 0
for vertex in surface:
x+=1
glColor3fv(self.colors[x])
glVertex3fv(self.verticies[vertex])
glEnd() #tell GL to stop drawing surfaces

glBegin(GL_LINES) #tell GL to draw lines
for edge in self.edges:
for vertex in edge:
glVertex3fv(self.verticies[vertex])
glEnd() #tell GL to stop drawing lines.

关于python - 将 PyOpenGL 从 PyGame 转移到 PyQt5 的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60239642/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com