Hide
Need a quick chart or graph for your blog? Try our reStructured Text renderer. Join Siafoo Now or Learn More

Using GLSL with PyOpenGL

Revision 4 vs. Revision 5

Changelog: * Minor cleanups * Added version warning since PyOpenGL seems to include the necessary code

Legend:

Unmodified
Added
Removed
  • Description

    r4 r5  
    1 It seems that some of the GLSL features are not implemented in `PyOpenGL <http://pyopengl.sourceforge.net/>`_ making it difficult to use shaders in PyOpenGL.   This excellent piece of code from the pygame wiki defines the required features for shader development.  
     1It seems that some of the GLSL features are not implemented in **older versions** of `PyOpenGL <http://pyopengl.sourceforge.net/>`_ making it difficult to use shaders in PyOpenGL.   This excellent piece of code from the `pygame <http://www.pygame.org/news.html>`_ wiki defines the required features for shader development.  
     2  
     3.. warning:: You shouldn't need or use this code if you have a recent version of PyOpenGL (~3.0)  
    24  
    35The main function draws the `Utah Teapot <http://www.sjbaker.org/wiki/index.php?title=The_History_of_The_Teapot>`_ with a rainbow sort of color, like this:  
    46  
    57.. image:: 29 
  • Code

    r4 r5  
    1919        path = find_library('OpenGL') 
    2020        gl = cdll.LoadLibrary(path) 
    2121  
    2222from OpenGL.GL import * 
    2323from OpenGL.GLU import * 
    24 from OpenGL.GLUT import * 
    2524  
    2625glCreateShader = gl.glCreateShader 
    2726glShaderSource = gl.glShaderSource 
    2827glShaderSource.argtypes = [c_int, c_int, POINTER(c_char_p), POINTER(c_int)] 
    2928glCompileShader = gl.glCompileShader 
     
    5958        print_log(shader) 
    6059        glDeleteShader(shader) 
    6160        raise ValueError, 'Shader compilation failed' 
    6261    return shader 
    6362  
    64 def compile_program(vertex_source, fragment_source): 
    65     vertex_shader = None 
    66     fragment_shader = None 
     63def compile_program(vertex_src, fragment_src): 
     64    ''' 
     65    Compile a Shader program given the vertex 
     66    and fragment sources 
     67    ''' 
     68     
     69    shaders = [] 
     70     
    6771    program = glCreateProgram() 
    68   
    69     if vertex_source: 
    70         vertex_shader = compile_shader(vertex_source, GL_VERTEX_SHADER) 
    71         glAttachShader(program, vertex_shader) 
    72     if fragment_source: 
    73         fragment_shader = compile_shader(fragment_source, GL_FRAGMENT_SHADER) 
    74         glAttachShader(program, fragment_shader) 
    75   
     72 
     73    for shader_type, src in ((GL_VERTEX_SHADER, vertex_src), 
     74                             (GL_FRAGMENT_SHADER, fragment_src)): 
     75        shader = compile_shader(src, shader_type) 
     76        glAttachShader(program, shader) 
     77        shaders.append(shader) 
     78 
    7679    glLinkProgram(program) 
    7780  
    78     if vertex_shader: 
    79         glDeleteShader(vertex_shader) 
    80     if fragment_shader: 
    81         glDeleteShader(fragment_shader) 
     81    for shader in shaders: 
     82        glDeleteShader(shader) 
    8283  
    8384    return program 
    8485  
    8586def print_log(shader): 
    8687    length = c_int() 
     
    9091        log = create_string_buffer(length.value) 
    9192        glGetShaderInfoLog(shader, length, byref(length), log) 
    9293        print >> sys.stderr, log.value 
    9394 
    9495if __name__ == '__main__': 
     96 
     97    from OpenGL.GLUT import glutInit, glutSolidTeapot 
    9598    glutInit(sys.argv) 
    9699    width, height = 640, 480 
    97100    pygame.init() 
    98101    pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF) 
    99102  
     
    112115    } 
    113116    ''') 
    114117  
    115118    glMatrixMode(GL_PROJECTION) 
    116119    glLoadIdentity() 
    117     gluPerspective(90.0, width/float(height), 1.0, 100.0) 
     120    gluPerspective(90.0, width / float(height), 1.0, 100.0) 
    118121    glMatrixMode(GL_MODELVIEW) 
    119122    glEnable(GL_DEPTH_TEST) 
    120123     
    121124    quit = False 
    122125    angle = 0 
     
    124127        for e in pygame.event.get(): 
    125128            if e.type in (QUIT, KEYDOWN): 
    126129                quit = True 
    127130        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    128131        glLoadIdentity() 
    129         glTranslate(0.0, 0.0, -2.5) 
     132        glTranslate(0.0, 0.0, - 2.5) 
    130133        glRotate(angle, 0.0, 1.0, 0.0) 
    131134        glUseProgram(program) 
    132135        glutSolidTeapot(1.0) 
    133136        angle += 0.1  
    134137        pygame.display.flip()