【问题标题】:Drawing transparent subsurfaces (windows) in PyOpenGL?在 PyOpenGL 中绘制透明的子表面(窗口)?
【发布时间】:2014-05-12 16:02:29
【问题描述】:

我有一个绘制立方体的简单 PyOpenGL 程序。我试图在立方体的正面绘制一个透明的次表面(窗口)。我可以让两个表面都显示出来,但不能以代表窗口的方式显示。

这是我绘制立方体的代码:

    # Draws the six faces of a cube
def DrawCube(self):
    # Front face - Blue
    glPushName(1)
    glBegin(GL_QUADS)
    glColor4f(0.0, 0.0, 1.0, 1.0)
    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, 1.0)
    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, 1.0)
    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, 1.0)
    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()

这是我正在绘制的结果。

我想让窗口完全透明,这样你就可以看到立方体的另一侧。我该怎么做?

【问题讨论】:

  • 很难确定,但是您可以考虑使用模板缓冲区来切出由“窗口”定义的立方体面区域,而不会出现那些深度对抗伪影。当然,您需要按特定顺序绘制立方体的其余部分,并且您可能希望禁用面部剔除,以便有一些可见的东西。
  • 1.重写你的模型,这样你的透明面就不会与任何其他四边形重叠。 2.要结合透明和实心多边形,您必须对多边形进行 Z 排序(从最远到最近绘制所有多边形)Z-Buffer 是不够的!!!
  • 我发现你可以使用镶嵌来绘制复杂的多边形。对于任何想要做类似事情的人来说,这是一个很棒的链接。 OpenGL Tesselation

标签: python opengl graphics transparency pyopengl


【解决方案1】:

你有两个问题。首先,您需要设置混合,以便不透明的几何图形通过半透明窗口显示:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

您看到的工件来自于绘制两个共面多边形。在理想的世界中,它们最终会在相同像素处获得相同的深度值。但由于所有计算都是以有限的精度完成的,因此可能存在细微差异,并且由于舍入误差,一个多边形出现在另一个多边形的前面。这通常被称为“深度战斗”或“z 战斗”。

为避免深度战斗问题,您必须将窗口稍微画在立方体前面。您可以通过为窗口使用稍大的 x 坐标来做到这一点。 OpenGL 也有一个内置机制,用于

glPolygonOffset(1.0f, 1.0f);
glEnable(GL_POLYGON_OFFSET_FILL);

您可能希望使用glPolygonOffset() 的确切参数来获得理想的结果。

【讨论】:

  • 不会在立方体前面稍微绘制窗口仍然使立方体不透明吗?这将有助于渲染伪影,但我的前蓝色表面仍然是不透明的,不是吗?
  • 对。偏移避免了伪影。启用混合可以让您透过窗口看到。但是对于您现在正在渲染的内容,您将通过窗口看到的第一件事是蓝色的“墙”。这并不奇怪,因为你在窗户后面画了一堵实心墙。要在窗户所在的位置留出开口,您必须将前墙分成多个四边形,并且只绘制窗户周围的部分。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 2015-05-26
  • 2013-02-21
  • 2013-07-09
  • 2014-03-13
  • 2016-11-23
相关资源
最近更新 更多