forked from glumpy/glumpy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeometry-parametric.py
executable file
·145 lines (117 loc) · 4.01 KB
/
geometry-parametric.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# -----------------------------------------------------------------------------
# Copyright (c) 2009-2016 Nicolas P. Rougier. All rights reserved.
# Distributed under the (new) BSD License.
# -----------------------------------------------------------------------------
import numpy as np
from glumpy import app, gl, glm, gloo, data
from glumpy.geometry import surface
vertex = """
uniform mat4 view;
uniform mat4 model;
uniform mat4 projection;
attribute vec3 normal;
attribute vec3 position;
attribute vec2 texcoord;
varying vec3 v_normal;
varying vec3 v_position;
varying vec2 v_texcoord;
void main()
{
v_texcoord = texcoord;
v_normal = normal;
v_position = position;
gl_Position = projection * view * model * vec4(v_position, 1.0);
}
"""
fragment = """
uniform mat4 view;
uniform mat4 model;
uniform mat4 normal;
uniform mat4 projection;
uniform vec3 light1_position;
uniform vec3 light2_position;
uniform vec3 light3_position;
uniform vec3 light1_color;
uniform vec3 light2_color;
uniform vec3 light3_color;
uniform sampler2D texture;
varying vec3 v_normal;
varying vec3 v_position;
varying vec2 v_texcoord;
float lighting(vec3 light_position)
{
// Calculate normal in world coordinates
vec3 n = normalize(normal * vec4(v_normal,1.0)).xyz;
// Calculate the location of this fragment (pixel) in world coordinates
vec3 position = vec3(view * model * vec4(v_position, 1));
// Calculate the vector from this pixels surface to the light source
vec3 surface_to_light = light_position - position;
// Calculate the cosine of the angle of incidence (brightness)
float brightness = dot(n, surface_to_light) /
(length(surface_to_light) * length(n));
brightness = max(min(brightness,1.0),0.0);
return brightness;
}
void main()
{
vec4 l1 = vec4(light1_color * lighting(light1_position), 1);
vec4 l2 = vec4(light2_color * lighting(light2_position), 1);
vec4 l3 = vec4(light3_color * lighting(light3_position), 1);
float r = texture2D(texture, v_texcoord).r;
vec4 color = vec4(r,r,r,1);
// Calculate final color of the pixel, based on:
// 1. The angle of incidence: brightness
// 2. The color/intensities of the light: light.intensities
// 3. The texture and texture coord: texture(tex, fragTexCoord)
gl_FragColor = color *( 0.25 + 0.75*(l1+l2+l3));
}
"""
window = app.Window(width=1024, height=1024, color=(1,1,1,1))
@window.event
def on_draw(dt):
global phi, theta, duration
window.clear()
program.draw(gl.GL_TRIANGLES, indices)
theta += 0.5
phi += 0.5
model = np.eye(4, dtype=np.float32)
glm.rotate(model, theta, 0, 0, 1)
glm.rotate(model, phi, 0, 1, 0)
program['model'] = model
program['normal'] = np.array(np.matrix(np.dot(view, model)).I.T)
@window.event
def on_resize(width, height):
program['projection'] = glm.perspective(45.0, width / float(height), 2.0, 100.0)
@window.event
def on_init():
gl.glEnable(gl.GL_DEPTH_TEST)
def klein(u, v):
from math import pi, cos, sin
if u < pi:
x = 3 * cos(u) * (1 + sin(u)) + (2 * (1 - cos(u) / 2)) * cos(u) * cos(v)
z = -8 * sin(u) - 2 * (1 - cos(u) / 2) * sin(u) * cos(v)
else:
x = 3 * cos(u) * (1 + sin(u)) + (2 * (1 - cos(u) / 2)) * cos(v + pi)
z = -8 * sin(u)
y = -2 * (1 - cos(u) / 2) * sin(v)
return x/5, y/5, z/5
vertices, indices = surface(klein, urepeat=3)
program = gloo.Program(vertex, fragment)
program.bind(vertices)
view = np.eye(4, dtype=np.float32)
model = np.eye(4, dtype=np.float32)
projection = np.eye(4, dtype=np.float32)
glm.translate(view, 0, 0, -5)
program['model'] = model
program['view'] = view
program['normal'] = np.array(np.matrix(np.dot(view, model)).I.T)
program['texture'] = data.checkerboard()
program['texture'].wrapping = gl.GL_REPEAT
program["light1_position"] = 3, 0, 0+5
program["light2_position"] = 0, 3, 0+5
program["light3_position"] = -3, -3, +5
program["light1_color"] = 1, 0, 0
program["light2_color"] = 0, 1, 0
program["light3_color"] = 0, 0, 1
phi, theta = 0, 0
app.run()