问题描述
我一直在尝试在 opengl 上创建一些对象,但在对象的某些部分消失时遇到了麻烦。
import sys
from PyQt5.QtCore import pyqtSignal,QPoint,QSize,Qt
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import (QApplication,QHBoxLayout,qopenglwidget,QSlider,QWidget)
import OpenGL.GL as gl
from OpenGL.GL import *
from OpenGL.glu import *
class Window(QWidget):
def __init__(self):
super(Window,self).__init__()
self.glWidget = GLWidget()
mainLayout = QHBoxLayout()
mainLayout.addWidget(self.glWidget)
self.setLayout(mainLayout)
self.setwindowTitle("Hello GL")
class GLWidget(qopenglwidget):
xRotationChanged = pyqtSignal(int)
yRotationChanged = pyqtSignal(int)
zRotationChanged = pyqtSignal(int)
def __init__(self,parent=None):
super(GLWidget,self).__init__(parent)
self.object = 0
self.xRot = 0
self.yRot = 0
self.zRot = 0
self.lastPos = QPoint()
self.trolltechGreen = QColor.fromCmykF(0.40,0.0,1.0,0.0)
self.trolltechPurple = QColor.fromCmykF(0.0,1.0)
self.quadric = gluNewQuadric()
def initializeGL(self):
print(self.getopenglInfo())
self.setClearColor(self.trolltechPurple.darker())
self.object = self.main()
gl.glBlendFunc(gl.GL_SRC_ALPHA,gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glEnable(gl.GL_BLEND)
gl.glShadeModel(gl.GL_FLAT)
gl.glEnable(gl.GL_DEPTH_TEST)
gl.glEnable(gl.GL_CULL_FACE)
def mousepressEvent(self,event):
self.lastPos = event.pos()
def minimumSizeHint(self):
return QSize(100,100)
def sizeHint(self):
return QSize(600,600)
def setXRotation(self,angle):
angle = self.normalizeAngle(angle)
if angle != self.xRot:
self.xRot = angle
self.xRotationChanged.emit(angle)
self.update()
def setYRotation(self,angle):
angle = self.normalizeAngle(angle)
if angle != self.yRot:
self.yRot = angle
self.yRotationChanged.emit(angle)
self.update()
def setZRotation(self,angle):
angle = self.normalizeAngle(angle)
if angle != self.zRot:
self.zRot = angle
self.zRotationChanged.emit(angle)
self.update()
def mousepressEvent(self,event):
self.lastPos = event.pos()
def mouseMoveEvent(self,event):
dx = event.x() - self.lastPos.x()
dy = event.y() - self.lastPos.y()
if event.buttons() & Qt.LeftButton:
self.setXRotation(self.xRot + 8 * dy)
self.setYRotation(self.yRot + 8 * dx)
elif event.buttons() & Qt.RightButton:
self.setXRotation(self.xRot + 8 * dy)
self.setZRotation(self.zRot + 8 * dx)
self.lastPos = event.pos()
def getopenglInfo(self):
info = """
vendor: {0}
Renderer: {1}
OpenGL Version: {2}
Shader Version: {3}
""".format(
gl.glGetString(gl.GL_vendOR),gl.glGetString(gl.GL_RENDERER),gl.glGetString(gl.GL_VERSION),gl.glGetString(gl.GL_SHADING_LANGUAGE_VERSION)
)
return info
def paintGL(self):
gl.glClear(
gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glLoadIdentity()
gl.glTranslated(0.0,-10.0)
gl.glrotated(self.xRot / 16.0,0.0)
gl.glrotated(self.yRot / 16.0,0.0)
gl.glrotated(self.zRot / 16.0,1.0)
gl.glCallList(self.object)
def resizeGL(self,width,height):
side = min(width,height)
if side < 0:
return
gl.glViewport((width - side) // 2,(height - side) // 2,side,side)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(-3,3,-3,4.0,55.0)
gl.glMatrixMode(gl.GL_MODELVIEW)
立方体和圆柱体草图
def main(self):
genList = gl.glGenLists(1)
gl.glNewList(genList,gl.GL_COMPILE)
glPushName(1)
glBegin(GL_QUADS)
glColor4f(0.0,0.5)
glnormal3f(0.0,1.0) # Allows for light to reflect off certain parts of surface
glVertex3f(1.0,0.0)
glVertex3f(1.0,1.0)
glVertex3f(1.0,1.0)
glEnd()
# Back face - Green
glPushName(2)
glBegin(GL_QUADS)
glColor4f(0.0,-1.0)
glVertex3f(0.0,0.0)
glVertex3f(0.0,1.0)
glVertex3f(0.0,1.0)
glEnd()
# Left face - Red
glPushName(3)
glBegin(GL_QUADS)
glColor4f(1.0,0.5)
glnormal3f(-1.0,1.0)
glEnd()
# Right face - Orange
glPushName(4)
glBegin(GL_QUADS)
glColor4f(1.0,0.55,0.5)
glnormal3f(1.0,0.0)
glEnd()
# Top face - White
glPushName(5)
glBegin(GL_QUADS)
glColor4f(1.0,1.0)
glnormal3f(0.0,1.0)
glEnd()
# Bottom face - Yellow
glPushName(6)
glBegin(GL_QUADS)
glColor4f(1.0,-1.0,0.0)
glEnd()
# Window on Front (Blue) Face
glPushName(7)
glBegin(GL_QUADS)
glColor4f(0.0,0.4)
glnormal3f(0.0,0.25,0.25)
glVertex3f(1.0,0.75,0.75)
glVertex3f(1.0,0.75)
glEnd()
gluCylinder(self.quadric,0.4,0.3,16,1)
gl.glEndList()
return genList
def setClearColor(self,c):
gl.glClearColor(c.redF(),c.greenF(),c.blueF(),c.alphaF())
def setColor(self,c):
gl.glColor4f(c.redF(),c.alphaF())
def normalizeAngle(self,angle):
while angle < 0:
angle += 360 * 16
while angle > 360 * 16:
angle -= 360 * 16
return angle
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
结果如下:
我不知道如何解决这个问题,我将不胜感激
解决方法
问题是由 Face Culling 引起的。只有所有图元的缠绕顺序相同时,面部剔除才能正常工作。
禁用面部剔除:
gl.glDisable(gl.GL_CULL_FACE)
或者简单的不启用它(默认情况下面部剔除是禁用的)。
gl.glEnable(gl.GL_CULL_FACE)