Hide
Don't get spied on – We respect your privacy and provide numerous options to protect it. Join Siafoo Now or Learn More
Note: You are viewing an old version of this snippet. View Latest Version

Using GLSL with PyOpenGL Atom Feed 0

In Brief It seems that some of the GLSL features are not implemented in 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 *
24from OpenGL.GLUT import *
25
26glCreateShader = gl.glCreateShader
27glShaderSource = gl.glShaderSource
28glShaderSource.argtypes = [c_int, c_int, POINTER(c_char_p), POINTER(c_int)]
29glCompileShader = gl.glCompileShader
30glGetShaderiv = gl.glGetShaderiv
31glGetShaderiv.argtypes = [c_int, c_int, POINTER(c_int)]
32glGetShaderInfoLog = gl.glGetShaderInfoLog
33glGetShaderInfoLog.argtypes = [c_int, c_int, POINTER(c_int), c_char_p]
34glGetUniformLocation = gl.glGetUniformLocation
35glUniform1i = gl.glUniform1i
36glDeleteShader = gl.glDeleteShader
37glCreateProgram = gl.glCreateProgram
38glAttachShader = gl.glAttachShader
39glLinkProgram = gl.glLinkProgram
40glGetError = gl.glGetError
41glUseProgram = gl.glUseProgram
42
43GL_FRAGMENT_SHADER = 0x8B30
44GL_VERTEX_SHADER = 0x8B31
45GL_COMPILE_STATUS = 0x8B81
46GL_LINK_STATUS = 0x8B82
47GL_INFO_LOG_LENGTH = 0x8B84
48
49def compile_shader(source, shader_type):
50 shader = glCreateShader(shader_type)
51 source = c_char_p(source)
52 length = c_int(-1)
53 glShaderSource(shader, 1, byref(source), byref(length))
54 glCompileShader(shader)
55
56 status = c_int()
57 glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status))
58 if not status.value:
59 print_log(shader)
60 glDeleteShader(shader)
61 raise ValueError, 'Shader compilation failed'
62 return shader
63
64def compile_program(vertex_source, fragment_source):
65 vertex_shader = None
66 fragment_shader = None
67 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
76 glLinkProgram(program)
77
78 if vertex_shader:
79 glDeleteShader(vertex_shader)
80 if fragment_shader:
81 glDeleteShader(fragment_shader)
82
83 return program
84
85def print_log(shader):
86 length = c_int()
87 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length))
88
89 if length.value > 0:
90 log = create_string_buffer(length.value)
91 glGetShaderInfoLog(shader, length, byref(length), log)
92 print >> sys.stderr, log.value
93
94if __name__ == '__main__':
95 glutInit(sys.argv)
96 width, height = 640, 480
97 pygame.init()
98 pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF)
99
100 program = compile_program('''
101 // Vertex program
102 varying vec3 pos;
103 void main() {
104 pos = gl_Vertex.xyz;
105 gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
106 }
107 ''', '''
108 // Fragment program
109 varying vec3 pos;
110 void main() {
111 gl_FragColor.rgb = pos.xyz;
112 }
113 ''')
114
115 glMatrixMode(GL_PROJECTION)
116 glLoadIdentity()
117 gluPerspective(90.0, width/float(height), 1.0, 100.0)
118 glMatrixMode(GL_MODELVIEW)
119 glEnable(GL_DEPTH_TEST)
120
121 quit = False
122 angle = 0
123 while not quit:
124 for e in pygame.event.get():
125 if e.type in (QUIT, KEYDOWN):
126 quit = True
127 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
128 glLoadIdentity()
129 glTranslate(0.0, 0.0, -2.5)
130 glRotate(angle, 0.0, 1.0, 0.0)
131 glUseProgram(program)
132 glutSolidTeapot(1.0)
133 angle += 0.1
134 pygame.display.flip()

It seems that some of the GLSL features are not implemented in 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.

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

/image/29