PyOpenGL 如何选择颜色来绘制每个形状?
How does PyOpenGL pick the colors to draw each shape?
我正在进行 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
class 中的列表的大小,然后将立方体的实例 class 附加到该列表。然后我可以在附加之前使用大小来引用该实例。这是渲染函数的代码:
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))
结果:
如何让我的线框以默认的白色或其他颜色呈现?我希望 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
之前设置当前颜色。当当前颜色改变时,设置一次就足够了。新颜色与以下所有顶点关联。
我正在进行 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
class 中的列表的大小,然后将立方体的实例 class 附加到该列表。然后我可以在附加之前使用大小来引用该实例。这是渲染函数的代码:
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))
结果:
如何让我的线框以默认的白色或其他颜色呈现?我希望 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
之前设置当前颜色。当当前颜色改变时,设置一次就足够了。新颜色与以下所有顶点关联。