Search code examples
openglpython-3.xpyopengl

how to defining the contour of a shape PyOpenGL


I have a one problem,I have many Sphere's in my scene with PyOpenGL, but I can't get differentiate one from another sphere.

How it's possible create a contour over the shape ?.


Solution

  • A straightforward way of creating contours or silhouettes around a mesh using the fixed pipeline (< OpenGL-3.x) is given below:

    1. Disable lighting: glDisable(GL_LIGHTING)
    2. Pick a colour for the silhouette: glColor(R, G, B)
    3. Turn on front face culling: glCullFace(GL_FRONT)
    4. Scale the mesh (sphere) by some small percentage: glScale(sx, sy, sz)
    5. render the sphere as you would normally: glutSolidSphere(radius, slices, stacks)

    Using Core profile OpenGL 3.x or later you would do the exact same operations but in a vertex shader instead.

    The code needed to achieve this using the fixed pipeline is as simple as:

        # Render silhouette around object
        glPushMatrix()
        glCullFace(GL_FRONT) # Front face culling makes us render only the inside of the sphere, which gives the illusion of a silhouette
        glScale(1.04, 1.04, 1.04) # This makes the silhouette show up around the object
        glDisable(GL_LIGHTING) # We only want a plain single colour silhouette
        glColor(0., 1., 0.) # Silhouette colour
        glutSolidSphere(2,20,20) # This can be any object, not limited to spheres (even non-convex objects)
        glPopMatrix()
    

    Below is a simple example PyOpenGL program rendering a sphere with a silhouette, base on the GLUT example found at http://code.activestate.com/recipes/325391-open-a-glut-window-and-draw-a-sphere-using-pythono/:

    from OpenGL.GLUT import *
    from OpenGL.GLU import *
    from OpenGL.GL import *
    import sys
    
    name = 'ball_glut'
    
    def main():
        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(400,400)
        glutCreateWindow(name)
    
        glClearColor(0.,0.,1.,1.)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_CULL_FACE)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_LIGHTING)
        lightZeroPosition = [10.,4.,10.,1.]
        lightZeroColor = [1.0,1.0,1.0,1.0]
        glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition)
        glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor)
        glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1)
        glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05)
        glEnable(GL_LIGHT0)
        glutDisplayFunc(display)
        glMatrixMode(GL_PROJECTION)
        gluPerspective(40.,1.,1.,40.)
        glMatrixMode(GL_MODELVIEW)
        gluLookAt(0,0,10,
                  0,0,0,
                  0,1,0)
        glPushMatrix()
        glutMainLoop()
        return
    
    def display():
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        glMatrixMode(GL_MODELVIEW)
    
        # Render sphere normally
        glPushMatrix()
        color = [1.0,0.,0.,1.]
        glMaterialfv(GL_FRONT,GL_DIFFUSE,color)
        glCullFace(GL_BACK)
        glEnable(GL_LIGHTING)
        glutSolidSphere(2,20,20)
    
        # Render silhouette around object
        glPushMatrix()
        glCullFace(GL_FRONT) # Front face culling makes us render only the inside of the sphere, which gives the illusion of a silhouette
        glScale(1.04, 1.04, 1.04) # This makes the silhouette show up around the object
        glDisable(GL_LIGHTING) # We only want a plain fixed colour silhouette
        glColor(0., 1., 0.) # Silhouette colour
        glutSolidSphere(2,20,20) # This can be any object, not limited to spheres (even non-convex objects)
        glPopMatrix()
    
        glPopMatrix()
        glutSwapBuffers() # Display results.
        return
    
    if __name__ == '__main__': main()