python - 物体的不可见部分
问题描述
我一直在尝试在 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, 0.0, 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, 0.0, -10.0)
gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
gl.glRotated(self.zRot / 16.0, 0.0, 0.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, -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.0, 1.0, 0.5)
glNormal3f(0.0, 0.0, 1.0) # Allows for light to reflect off certain parts of surface
glVertex3f(1.0, 0.0, 0.0)
glVertex3f(1.0, 1.0, 0.0)
glVertex3f(1.0, 1.0, 1.0)
glVertex3f(1.0, 0.0, 1.0)
glEnd()
# Back face - Green
glPushName(2)
glBegin(GL_QUADS)
glColor4f(0.0, 1.0, 0.0, 0.5)
glNormal3f(0.0, 0.0, -1.0)
glVertex3f(0.0, 0.0, 0.0)
glVertex3f(0.0, 1.0, 0.0)
glVertex3f(0.0, 1.0, 1.0)
glVertex3f(0.0, 0.0, 1.0)
glEnd()
# Left face - Red
glPushName(3)
glBegin(GL_QUADS)
glColor4f(1.0, 0.0, 0.0, 0.5)
glNormal3f(-1.0, 0.0, 0.0)
glVertex3f(0.0, 0.0, 0.0)
glVertex3f(1.0, 0.0, 0.0)
glVertex3f(1.0, 0.0, 1.0)
glVertex3f(0.0, 0.0, 1.0)
glEnd()
# Right face - Orange
glPushName(4)
glBegin(GL_QUADS)
glColor4f(1.0, 0.55, 0.0, 0.5)
glNormal3f(1.0, 0.0, 0.0)
glVertex3f(1.0, 1.0, 0.0)
glVertex3f(1.0, 1.0, 1.0)
glVertex3f(0.0, 1.0, 1.0)
glVertex3f(0.0, 1.0, 0.0)
glEnd()
# Top face - White
glPushName(5)
glBegin(GL_QUADS)
glColor4f(1.0, 1.0, 1.0, 1.0)
glNormal3f(0.0, 1.0, 0.0)
glVertex3f(0.0, 0.0, 1.0)
glVertex3f(1.0, 0.0, 1.0)
glVertex3f(1.0, 1.0, 1.0)
glVertex3f(0.0, 1.0, 1.0)
glEnd()
# Bottom face - Yellow
glPushName(6)
glBegin(GL_QUADS)
glColor4f(1.0, 1.0, 0.0, 1.0)
glNormal3f(0.0, -1.0, 0.0)
glVertex3f(0.0, 0.0, 0.0)
glVertex3f(0.0, 1.0, 0.0)
glVertex3f(1.0, 1.0, 0.0)
glVertex3f(1.0, 0.0, 0.0)
glEnd()
# Window on Front (Blue) Face
glPushName(7)
glBegin(GL_QUADS)
glColor4f(0.0, 1.0, 1.0, 0.4)
glNormal3f(0.0, 0.0, 1.0)
glVertex3f(1.0, 0.25, 0.25)
glVertex3f(1.0, 0.75, 0.25)
glVertex3f(1.0, 0.75, 0.75)
glVertex3f(1.0, 0.25, 0.75)
glEnd()
gluCylinder(self.quadric,0.4,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.greenF(), c.blueF(), 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)
推荐阅读
- eclipse - 持久 SWT shell 窗口位置
- docker - 容器运行后通过 Dockerfile 运行命令
- amazon-web-services - 如何使用 terraform 在多个区域创建 SNS 主题?
- sql - JIRA 的 SQL 脚本 - 如何同时包含用户登录计数和未登录帐户
- javascript - 使用 javascript 播放音频
- javascript - Redux 状态变量未定义
- python - 查找数组中最“空”的位置
- python-3.x - Matplotlib - Fill_Between 似乎不起作用
- php - PHP文件上传无法正常工作,如何解决?
- scala - StreamingKMeans setSeed()