【问题标题】:invisible part of object物体的不可见部分
【发布时间】:2021-05-03 10:29:01
【问题描述】:

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

结果如下:

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

【问题讨论】:

    标签: python opengl cube


    【解决方案1】:

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

    禁用面部剔除:

    gl.glDisable(gl.GL_CULL_FACE)
    

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

    gl.glEnable(gl.GL_CULL_FACE)

    【讨论】:

    • 人脸剔除是 GL_FACE_CULL 而不是 GL_DEPTH_TEST!并且提问者的代码没有使用它......
    • @user253751 1.) 谢谢,这是一个复制/过去的问题。 2)gl.glEnable(gl.GL_CULL_FACE)initializeGL()
    • 一定是我搜索的时候打错了
    • @user253751 不是GL_FACE_CULL,而是GL_CULL_FACE
    • 哦,呵呵。可能是因为我使用了 GL_DEPTH_TEST(动词第二)。
    猜你喜欢
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2012-11-09
    • 1970-01-01
    相关资源
    最近更新 更多