微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

物体的不可见部分

如何解决物体的不可见部分

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。