在PyOpenGL中绘制透明的子表面(窗口)?
我有一个简单的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
你遇到了两个问题。首先,你需要设置混合模式,这样不透明的物体才能透过半透明的窗户显示出来:
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()
的具体参数,以获得理想的效果。