gpt4 book ai didi

python - PyOpenGL 如何选择颜色来绘制每个形状?

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

我正在进行 PyQt5 PyOpenGL 项目。我正在尝试用一堆彩色实心立方体绘制一个白色线框立方体。线框立方体是从元组点列表以及对这些点的元组引用列表中绘制的。实心立方体是从对点的元组引用列表中绘制的。这是立方体代码:

class cube():
render = True
solid = False
color = (1, 1, 1)

def config(self, x, y, z, size = 0.1, solid = False, color = (1, 1, 1)):
self.solid = solid
self.color = color
self.size = size / 2
s = self.size
self.vertices = [
(-s + x, s + y, -s + z),
(s + x, s + y, -s + z),
(s + x, -s + y, -s + z),
(-s + x, -s + y, -s + z),
(-s + x, s + y, s + z),
(s + x, s + y, s + z),
(s + x, -s + y, s + z),
(-s + x, -s + y, s + z)
]
self.edges = [
(0,1), (0,3), (0,4), (2,1),
(2,3), (2,6), (7,3), (7,4),
(7,6), (5,1), (5,4), (5,6)
]
self.facets = [
(0, 1, 2, 3), (0, 1, 6, 5),
(0, 3, 7, 4), (6, 5, 1, 2),
(6, 7, 4, 5), (6, 7, 3, 2)
]
def show(self):
self.render = True
def hide(self):
self.render = False

为了渲染立方体,我获取 mainWindow 类中保存的列表的大小,然后将立方体类的实例附加到该列表。然后我可以在附加之前使用大小来引用该实例。这是渲染函数的代码:

def paintGL(self):
glLoadIdentity()
gluPerspective(45, self.width / self.height, 0.1, 110.0) #set perspective?
glTranslatef(0, 0, self.zoomLevel) #I used -10 instead of -2 in the PyGame version.
glRotatef(self.rotateDegreeV, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.
glRotatef(self.rotateDegreeH, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

if len(self.shapes) != 0:
glBegin(GL_LINES)
for s in self.shapes:
if s.render and not s.solid:
for e in s.edges:
for v in e:
glVertex3fv(s.vertices[v])
glEnd()

glBegin(GL_QUADS)
for s in self.shapes:
if s.render and s.solid:
for f in s.facets:
for v in f:
glColor3fv(s.color)
glVertex3fv(s.vertices[v])
glEnd()

如果我在线框中仅渲染一个立方体,它会呈现白色。如果我在其后添加一个红色实心立方体和一个蓝色实心立方体,则线框立方体将以最后使用的颜色着色,无论它是什么。例如:

    self.shapes.append(self.cube())
self.shapes.append(self.cube())
self.shapes.append(self.cube())
self.shapes[0].config(-1, 0, 0, size = 0.5, solid = False)
self.shapes[1].config(0, 0, 0, size = 0.5, solid = True, color = (1, 0, 0))
self.shapes[2].config(1, 0, 0, size = 0.5, solid = True, color = (0, 0, 1))

结果:

cubes

如何使我的线框以默认白色或其他颜色渲染?我希望 glClear() 会重置它并以白色绘制线框,因为它是第一个。

完整代码如下:

import sys
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QSlider,
QOpenGLWidget, QLabel, QPushButton
)
from PyQt5.QtCore import Qt
from OpenGL.GL import (
glLoadIdentity, glTranslatef, glRotatef,
glClear, glBegin, glEnd,
glColor3fv, glVertex3fv,
GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT,
GL_QUADS, GL_LINES
)
from OpenGL.GLU import gluPerspective

class mainWindow(QMainWindow): #Main class.
shapes = [] #this will hold instances of the following classes:
zoomLevel = -10
rotateDegreeV = -90
rotateDegreeH = 0

class cube():
render = True
solid = False
color = (1, 1, 1)

def config(self, x, y, z, size = 0.1, solid = False, color = (1, 1, 1)):
self.solid = solid
self.color = color
self.size = size
s = self.size / 2
self.vertices = [
(-s + x, s + y, -s + z),
(s + x, s + y, -s + z),
(s + x, -s + y, -s + z),
(-s + x, -s + y, -s + z),
(-s + x, s + y, s + z),
(s + x, s + y, s + z),
(s + x, -s + y, s + z),
(-s + x, -s + y, s + z)
]
self.edges = [
(0,1), (0,3), (0,4), (2,1),
(2,3), (2,6), (7,3), (7,4),
(7,6), (5,1), (5,4), (5,6)
]
self.facets = [
(0, 1, 2, 3), (0, 1, 6, 5),
(0, 3, 7, 4), (6, 5, 1, 2),
(6, 7, 4, 5), (6, 7, 3, 2)
]
def show(self):
self.render = True
def hide(self):
self.render = False

def keyPressEvent(self, event): #This is the keypress detector. I use this to determine input to edit grids.
try:
key = event.key()
if key == 87:
self.rotateV(5)
elif key == 65:
self.rotateH(5)
elif key == 83:
self.rotateV(-5)
elif key == 68:
self.rotateH(-5)
elif key == 67:
self.zoom(1)
elif key == 88:
self.zoom(-1)
except:
pass

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
self.shapes.append(self.cube())
self.shapes.append(self.cube())
self.shapes.append(self.cube())
self.shapes[0].config(-1, 0, 0, size = 0.5, solid = False)
self.shapes[1].config(0, 0, 0, size = 0.5, solid = True, color = (1, 0, 0))
self.shapes[2].config(1, 0, 0, size = 0.5, solid = True, color = (0, 0, 1))

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 zoom(self, value):
self.zoomLevel += value
self.openGLWidget.update()

def rotateV(self, value):
self.rotateDegreeV += value
self.openGLWidget.update()

def rotateH(self, value):
self.rotateDegreeH += value
self.openGLWidget.update()

def paintGL(self):
glLoadIdentity()
gluPerspective(45, self.width / self.height, 0.1, 110.0) #set perspective?
glTranslatef(0, 0, self.zoomLevel) #I used -10 instead of -2 in the PyGame version.
glRotatef(self.rotateDegreeV, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.
glRotatef(self.rotateDegreeH, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

if len(self.shapes) != 0:
glBegin(GL_LINES)
for s in self.shapes:
if s.render and not s.solid:
for e in s.edges:
for v in e:
glVertex3fv(s.vertices[v])
glEnd()

glBegin(GL_QUADS)
for s in self.shapes:
if s.render and s.solid:
for f in s.facets:
for v in f:
glColor3fv(s.color)
glVertex3fv(s.vertices[v])
glEnd()


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

最佳答案

OpenGL 是一个状态引擎。一旦设置了状态,它就会被保留,直到再次更改,甚至超出帧。当前颜色是全局状态。当glColor* 被调用,然后设置当前颜色。
glVertex* 被调用,则当前颜色、法线和纹理坐标与顶点相关联。

这意味着,在指定顶点之前必须设置正确的颜色。在绘制线框立方体之前,您错过了设置颜色属性:

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

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

if len(self.shapes) != 0:
glBegin(GL_LINES)
for s in self.shapes:
glColor3fv(s.color) # <------------------------
if s.render and not s.solid:
for e in s.edges:
for v in e:
glVertex3fv(s.vertices[v])
glEnd()

glBegin(GL_QUADS)
for s in self.shapes:
glColor3fv(s.color)
if s.render and s.solid:
for f in s.facets:
for v in f:
glVertex3fv(s.vertices[v])
glEnd()

请注意,不必在每次调用 glVertex3fv 之前设置当前颜色。当当前颜色改变时,设置一次就足够了。新颜色与以下所有顶点相关联。

关于python - PyOpenGL 如何选择颜色来绘制每个形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60289464/

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