首页 > 解决方案 > 物体的不可见部分

问题描述

我一直在尝试在 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_())

结果如下:

我不知道如何解决这个问题,我将不胜感激

标签: pythonopenglcube

解决方案


该问题是由Face Culling引起的。只有当所有图元的缠绕顺序相同时,面剔除才能正常工作。

禁用面部剔除:

gl.glDisable(gl.GL_CULL_FACE)

或者简单地不启用它(默认情况下面部剔除被禁用)。

gl.glEnable(gl.GL_CULL_FACE)


推荐阅读