Hide
Know what you're getting – Unlike many sites, all our code is clearly licensed. Join Siafoo Now or Learn More

Using GLSL with PyOpenGL Atom Feed 0

In Brief It seems that some of the GLSL features are not implemented in older versions of PyOpenGL making it difficult to use shaders in PyOpenGL. This excellent piece of code from the pygame wiki defines the required features for shader development.... more
# 's
  1from ctypes import *
2import sys
3
4import pygame
5from pygame.locals import *
6
7try:
8 # For OpenGL-ctypes
9 from OpenGL import platform
10 gl = platform.OpenGL
11except ImportError:
12 try:
13 # For PyOpenGL
14 gl = cdll.LoadLibrary('libGL.so')
15 except OSError:
16 # Load for Mac
17 from ctypes.util import find_library
18 # finds the absolute path to the framework
19 path = find_library('OpenGL')
20 gl = cdll.LoadLibrary(path)
21
22from OpenGL.GL import *
23from OpenGL.GLU import *
24
25glCreateShader = gl.glCreateShader
26glShaderSource = gl.glShaderSource
27glShaderSource.argtypes = [c_int, c_int, POINTER(c_char_p), POINTER(c_int)]
28glCompileShader = gl.glCompileShader
29glGetShaderiv = gl.glGetShaderiv
30glGetShaderiv.argtypes = [c_int, c_int, POINTER(c_int)]
31glGetShaderInfoLog = gl.glGetShaderInfoLog
32glGetShaderInfoLog.argtypes = [c_int, c_int, POINTER(c_int), c_char_p]
33glGetUniformLocation = gl.glGetUniformLocation
34glUniform1i = gl.glUniform1i
35glDeleteShader = gl.glDeleteShader
36glCreateProgram = gl.glCreateProgram
37glAttachShader = gl.glAttachShader
38glLinkProgram = gl.glLinkProgram
39glGetError = gl.glGetError
40glUseProgram = gl.glUseProgram
41
42GL_FRAGMENT_SHADER = 0x8B30
43GL_VERTEX_SHADER = 0x8B31
44GL_COMPILE_STATUS = 0x8B81
45GL_LINK_STATUS = 0x8B82
46GL_INFO_LOG_LENGTH = 0x8B84
47
48def compile_shader(source, shader_type):
49 shader = glCreateShader(shader_type)
50 source = c_char_p(source)
51 length = c_int(-1)
52 glShaderSource(shader, 1, byref(source), byref(length))
53 glCompileShader(shader)
54
55 status = c_int()
56 glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status))
57 if not status.value:
58 print_log(shader)
59 glDeleteShader(shader)
60 raise ValueError, 'Shader compilation failed'
61 return shader
62
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
71 program = glCreateProgram()
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
79 glLinkProgram(program)
80
81 for shader in shaders:
82 glDeleteShader(shader)
83
84 return program
85
86def print_log(shader):
87 length = c_int()
88 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length))
89
90 if length.value > 0:
91 log = create_string_buffer(length.value)
92 glGetShaderInfoLog(shader, length, byref(length), log)
93 print >> sys.stderr, log.value
94
95if __name__ == '__main__':
96
97 from OpenGL.GLUT import glutInit, glutSolidTeapot
98 glutInit(sys.argv)
99 width, height = 640, 480
100 pygame.init()
101 pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF)
102
103 program = compile_program('''
104 // Vertex program
105 varying vec3 pos;
106 void main() {
107 pos = gl_Vertex.xyz;
108 gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
109 }
110 ''', '''
111 // Fragment program
112 varying vec3 pos;
113 void main() {
114 gl_FragColor.rgb = pos.xyz;
115 }
116 ''')
117
118 glMatrixMode(GL_PROJECTION)
119 glLoadIdentity()
120 gluPerspective(90.0, width / float(height), 1.0, 100.0)
121 glMatrixMode(GL_MODELVIEW)
122 glEnable(GL_DEPTH_TEST)
123
124 quit = False
125 angle = 0
126 while not quit:
127 for e in pygame.event.get():
128 if e.type in (QUIT, KEYDOWN):
129 quit = True
130 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
131 glLoadIdentity()
132 glTranslate(0.0, 0.0, - 2.5)
133 glRotate(angle, 0.0, 1.0, 0.0)
134 glUseProgram(program)
135 glutSolidTeapot(1.0)
136 angle += 0.1
137 pygame.display.flip()

It seems that some of the GLSL features are not implemented in older versions of PyOpenGL making it difficult to use shaders in PyOpenGL. This excellent piece of code from the pygame wiki defines the required features for shader development.

Warning

You shouldn't need or use this code if you have a recent version of PyOpenGL (~3.0)

The main function draws the Utah Teapot with a rainbow sort of color, like this:

http://www.siafoo.net/image/29