1
by Miriam Ruiz
Import upstream version 0.5.20070616 |
1 |
from ctypes import * |
2 |
import sys |
|
3 |
||
4 |
import pygame |
|
5 |
from pygame.locals import * |
|
6 |
||
7 |
try: |
|
8 |
# For OpenGL-ctypes
|
|
9 |
from OpenGL import platform |
|
10 |
gl = platform.OpenGL |
|
11 |
except ImportError: |
|
12 |
# For PyOpenGL
|
|
13 |
gl = cdll.LoadLibrary('libGL.so') |
|
14 |
||
15 |
from OpenGL.GL import * |
|
16 |
from OpenGL.GLU import * |
|
17 |
from OpenGL.GLUT import * |
|
18 |
||
19 |
GL_FRAGMENT_SHADER_ARB = 0x8B30 |
|
20 |
GL_VERTEX_SHADER_ARB = 0x8B31 |
|
21 |
GL_OBJECT_COMPILE_STATUS_ARB= 0x8B81 |
|
22 |
GL_OBJECT_LINK_STATUS_ARB = 0x8B82 |
|
23 |
GL_INFO_LOG_LENGTH_ARB = 0x8B84 |
|
24 |
||
25 |
||
26 |
glCreateShaderObjectARB = gl.glCreateShaderObjectARB |
|
27 |
glShaderSourceARB = gl.glShaderSourceARB |
|
28 |
glShaderSourceARB.argtypes = [c_int, c_int, POINTER(c_char_p), POINTER(c_int)] |
|
29 |
glCompileShaderARB = gl.glCompileShaderARB |
|
30 |
glGetObjectParameterivARB = gl.glGetObjectParameterivARB |
|
31 |
glGetObjectParameterivARB.argtypes = [c_int, c_int, POINTER(c_int)] |
|
32 |
glCreateProgramObjectARB = gl.glCreateProgramObjectARB |
|
33 |
glGetInfoLogARB = gl.glGetShaderInfoLog |
|
34 |
glGetInfoLogARB.argtypes = [c_int, c_int, POINTER(c_int), c_char_p] |
|
35 |
glAttachObjectARB = gl.glAttachObjectARB |
|
36 |
glLinkProgramARB = gl.glLinkProgramARB |
|
37 |
glDeleteObjectARB = gl.glDeleteObjectARB |
|
38 |
glGetError = gl.glGetError |
|
39 |
glUseProgramObjectARB = gl.glUseProgramObjectARB |
|
40 |
||
41 |
||
42 |
def print_log(shader): |
|
43 |
length = c_int() |
|
44 |
glGetObjectParameterivARB(shader, GL_INFO_LOG_LENGTH, byref(length)) |
|
45 |
||
46 |
if length.value > 0: |
|
47 |
log = create_string_buffer(length.value) |
|
48 |
glGetInfoLogARB(shader, length, byref(length), log) |
|
49 |
print >> sys.stderr, log.value |
|
50 |
||
51 |
def compile_shader(source, shader_type): |
|
52 |
shader = glCreateShaderObjectARB(shader_type) |
|
53 |
source = c_char_p(source) |
|
54 |
length = c_int(-1) |
|
55 |
glShaderSourceARB(shader, 1, byref(source), byref(length)) |
|
56 |
glCompileShaderARB(shader) |
|
57 |
status = c_int() |
|
58 |
glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, |
|
59 |
byref(status)) |
|
60 |
if (not status.value): |
|
61 |
print_log(shader) |
|
62 |
raise SystemExit |
|
63 |
return shader |
|
64 |
||
65 |
||
66 |
def compile_program(vertex_source, fragment_source): |
|
67 |
vertex_shader = None |
|
68 |
fragment_shader = None |
|
69 |
program = glCreateProgramObjectARB() |
|
70 |
||
71 |
if vertex_source: |
|
72 |
vertex_shader = compile_shader(vertex_source, GL_VERTEX_SHADER_ARB) |
|
73 |
glAttachObjectARB(program, vertex_shader) |
|
74 |
if fragment_source: |
|
75 |
fragment_shader = compile_shader(fragment_source, |
|
76 |
GL_FRAGMENT_SHADER_ARB) |
|
77 |
glAttachObjectARB(program, fragment_shader) |
|
78 |
||
79 |
glLinkProgramARB(program) |
|
80 |
||
81 |
if vertex_shader: |
|
82 |
glDeleteObjectARB(vertex_shader) |
|
83 |
if fragment_shader: |
|
84 |
glDeleteObjectARB(fragment_shader) |
|
85 |
||
86 |
return program |
|
87 |
||
88 |
def toon_program(): |
|
89 |
return compile_program(''' |
|
90 |
varying vec3 normal;
|
|
91 |
void main() {
|
|
92 |
normal = gl_NormalMatrix * gl_Normal;
|
|
93 |
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
|
94 |
gl_FrontColor = gl_Color;
|
|
95 |
}
|
|
96 |
''', ''' |
|
97 |
varying vec3 normal;
|
|
98 |
void main() {
|
|
99 |
float intensity;
|
|
100 |
vec3 n = normalize(normal);
|
|
101 |
vec3 l = normalize(gl_LightSource[0].position).xyz;
|
|
102 |
||
103 |
// quantize to 5 steps (.4, .6, .8 and 1)
|
|
104 |
intensity = dot(l, n);
|
|
105 |
if (intensity < .15) intensity = .5;
|
|
106 |
else if (intensity >= .15 && intensity < .5) intensity = .7;
|
|
107 |
else if (intensity >= .5 && intensity < .75) intensity = .9;
|
|
108 |
else intensity = 1;
|
|
109 |
||
110 |
gl_FragColor = gl_Color * intensity;
|
|
111 |
}
|
|
112 |
''') |
|
113 |
||
114 |
def outline_program(): |
|
115 |
return compile_program(''' |
|
116 |
uniform vec3 camPos;
|
|
117 |
uniform float outlineThreshold;
|
|
118 |
uniform float edgeThreshold;
|
|
119 |
||
120 |
varying vec3 norm;
|
|
121 |
||
122 |
void main(){
|
|
123 |
vec4 pos = gl_Vertex;
|
|
124 |
vec3 dir = camPos - gl_Vertex.xyz;
|
|
125 |
||
126 |
pos.w = float(
|
|
127 |
dot(dir, gl_MultiTexCoord0.xyz) *
|
|
128 |
dot(dir, gl_MultiTexCoord1.xyz) < outlineThreshold ||
|
|
129 |
dot(gl_MultiTexCoord0.xyz, gl_MultiTexCoord1.xyz) < edgeThreshold);
|
|
130 |
||
131 |
gl_Position = gl_ModelViewProjectionMatrix * pos;
|
|
132 |
}
|
|
133 |
''', ''' |
|
134 |
varying vec3 norm;
|
|
135 |
||
136 |
void main(){
|
|
137 |
gl_FragColor = vec4(0.0);
|
|
138 |
}
|
|
139 |
''') |
|
140 |
||
141 |
if __name__ == '__main__': |
|
142 |
glutInit(sys.argv) |
|
143 |
width, height = 640, 480 |
|
144 |
pygame.init() |
|
145 |
pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF) |
|
146 |
||
147 |
program = toon_program() |
|
148 |
||
149 |
glMatrixMode(GL_PROJECTION) |
|
150 |
glLoadIdentity() |
|
151 |
gluPerspective(90.0, width/float(height), 1.0, 100.0) |
|
152 |
glMatrixMode(GL_MODELVIEW) |
|
153 |
glEnable(GL_DEPTH_TEST) |
|
154 |
||
155 |
quit = False |
|
156 |
angle = 0 |
|
157 |
while not quit: |
|
158 |
for e in pygame.event.get(): |
|
159 |
if e.type in (QUIT, KEYDOWN): |
|
160 |
quit = True |
|
161 |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
|
162 |
glLoadIdentity() |
|
163 |
glTranslate(0.0, 0.0, -2.5) |
|
164 |
glRotate(angle, 0.0, 1.0, 0.0) |
|
165 |
glUseProgramObjectARB(program) |
|
166 |
glColor(1.0, .5, .5, 1.0) |
|
167 |
glutSolidTeapot(1.0) |
|
168 |
angle += 0.1 |
|
169 |
pygame.display.flip() |
|
170 |