pygame is
pygame.org is
|
Wiki
GLSLExampleThe following uses ctypes to get to the OpenGL 1.5/2.0 functions not exported by PyOpenGL. See GLSL_ARB_Example for an implementation using the OpenGL ARB extensions. from ctypes import * import sys import pygame from pygame.locals import * try: # For OpenGL-ctypes from OpenGL import platform gl = platform.OpenGL except ImportError: try: # For PyOpenGL gl = cdll.LoadLibrary('libGL.so') except OSError: # Load for Mac from ctypes.util import find_library # finds the absolute path to the framework path = find_library('OpenGL') gl = cdll.LoadLibrary(path) from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * glCreateShader = gl.glCreateShader glShaderSource = gl.glShaderSource glShaderSource.argtypes = [c_int, c_int, POINTER(c_char_p), POINTER(c_int)] glCompileShader = gl.glCompileShader glGetShaderiv = gl.glGetShaderiv glGetShaderiv.argtypes = [c_int, c_int, POINTER(c_int)] glGetShaderInfoLog = gl.glGetShaderInfoLog glGetShaderInfoLog.argtypes = [c_int, c_int, POINTER(c_int), c_char_p] glDeleteShader = gl.glDeleteShader glCreateProgram = gl.glCreateProgram glAttachShader = gl.glAttachShader glLinkProgram = gl.glLinkProgram glGetError = gl.glGetError glUseProgram = gl.glUseProgram GL_FRAGMENT_SHADER = 0x8B30 GL_VERTEX_SHADER = 0x8B31 GL_COMPILE_STATUS = 0x8B81 GL_LINK_STATUS = 0x8B82 GL_INFO_LOG_LENGTH = 0x8B84 def compile_shader(source, shader_type): shader = glCreateShader(shader_type) source = c_char_p(source) length = c_int(-1) glShaderSource(shader, 1, byref(source), byref(length)) glCompileShader(shader) status = c_int() glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status)) if not status.value: print_log(shader) glDeleteShader(shader) raise ValueError, 'Shader compilation failed' return shader def compile_program(vertex_source, fragment_source): vertex_shader = None fragment_shader = None program = glCreateProgram() if vertex_source: vertex_shader = compile_shader(vertex_source, GL_VERTEX_SHADER) glAttachShader(program, vertex_shader) if fragment_source: fragment_shader = compile_shader(fragment_source, GL_FRAGMENT_SHADER) glAttachShader(program, fragment_shader) glLinkProgram(program) if vertex_shader: glDeleteShader(vertex_shader) if fragment_shader: glDeleteShader(fragment_shader) return program def print_log(shader): length = c_int() glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length)) if length.value > 0: log = create_string_buffer(length.value) glGetShaderInfoLog(shader, length, byref(length), log) print >> sys.stderr, log.value Example usage (draws a spinning teapot coloured by a fragment shader, using a pass-through vertex shader): if __name__ == '__main__': glutInit(sys.argv) width, height = 640, 480 pygame.init() pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF) program = compile_program(''' // Vertex program varying vec3 pos; void main() { pos = gl_Vertex.xyz; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; } ''', ''' // Fragment program varying vec3 pos; void main() { gl_FragColor.rgb = pos.xyz; } ''') glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(90.0, width/float(height), 1.0, 100.0) glMatrixMode(GL_MODELVIEW) glEnable(GL_DEPTH_TEST) quit = False angle = 0 while not quit: for e in pygame.event.get(): if e.type in (QUIT, KEYDOWN): quit = True glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslate(0.0, 0.0, -2.5) glRotate(angle, 0.0, 1.0, 0.0) glUseProgram(program) glutSolidTeapot(1.0) angle += 0.1 pygame.display.flip() Here's another shader that does "cartoon" shading. It was adapted from here . It works off of the position of GL_LIGHT0. It doesn't actually use any parameters of the light, so you could actually just set a parameter with the "light" position. The two shaders are: // Vertex program
varying vec3 normal;
void main() {
normal = gl_NormalMatrix * gl_Normal;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
// Fragment program
varying vec3 normal;
void main() {
float intensity;
vec4 color;
vec3 n = normalize(normal);
vec3 l = normalize(gl_LightSource[0].position).xyz;
// quantize to 5 steps (0, .25, .5, .75 and 1)
intensity = (floor(dot(l, n) * 4.0) + 1.0)/4.0;
color = vec4(intensity*1.0, intensity*0.5, intensity*0.5,
intensity*1.0);
gl_FragColor = color;
}
[edit] |
|