Kameron Kincade
Kameron Kincade

Reputation: 623

Drawing transparent subsurfaces (windows) in PyOpenGL?

I have a simple PyOpenGL program that draws a cube. I am attempting to draw a transparent subsurface (window) on the front face of the cube. I can get both surfaces to show up, but not in the way that represents a window.

Here is my code for drawing the cube:

    # 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()

Here is the result of what I'm drawing. Cube Rendering

I want to make the window completely transparent so you can see through to the other side of the cube. How do I do this?

Upvotes: 1

Views: 1679

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54592

You have two problems. First, you need to set up blending so that the opaque geometry shows through the translucent window:

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

The artifacts you're seeing is from drawing two coplanar polygons. In an ideal world, they would end up with the same depth value at the same pixel. But because all calculations are done with limited precision, there can be slight differences, and one polygon shows up in front of the other due to rounding errors. This is commonly referred to as "depth fighting" or "z fighting".

To avoid the depth fighting issue, you have to draw your window slightly in front of the cube. You can do that by using slightly larger x-coordinates for your window. OpenGL also has a built-in mechanism for

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

You may want to play with the exact parameters to glPolygonOffset() to get the ideal result.

Upvotes: 2

Related Questions