Skip to content

Commit 242166e

Browse files
committed
Transform feedback example
1 parent a36f38e commit 242166e

File tree

6 files changed

+199
-0
lines changed

6 files changed

+199
-0
lines changed

examples/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ Simple example showing three cubes
1313
![screenshot](https://raw.githubusercontent.com/Contraz/demosys-py/master/examples/images/cubes.png)
1414

1515
Texture source : http://free-texture-site.blogspot.com/2010/10/free-game-crate-texture.html
16+
17+
Feedback
18+
--------
19+
20+
Basic example of using transform feedback. Thousands of particles are being
21+
affected by newton's law with a pulsing gravity field in the middle of the scene.
22+

examples/feedback/effect.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import math
2+
import random
3+
4+
import numpy
5+
6+
import moderngl as mgl
7+
from demosys.effects import effect
8+
from demosys.opengl import VAO
9+
from pyrr import matrix44, vector3
10+
11+
12+
class FeedbackEffect(effect.Effect):
13+
14+
def __init__(self):
15+
self.feedback = self.get_shader("feedback/transform.glsl")
16+
self.shader = self.get_shader("feedback/billboards.glsl")
17+
self.texture = self.get_texture("feedback/particle.png")
18+
19+
# VAOs representing the two different buffer bindings
20+
self.particles1 = None
21+
self.particles2 = None
22+
self.particles = None
23+
24+
# VBOs for each position buffer
25+
self.pos1 = None
26+
self.pos2 = None
27+
self.pos = None
28+
self.init_particles()
29+
30+
@effect.bind_target
31+
def draw(self, time, frametime, target):
32+
self.ctx.disable(mgl.DEPTH_TEST)
33+
self.ctx.enable(mgl.BLEND)
34+
self.ctx.blend_func = mgl.SRC_ALPHA, mgl.ONE_MINUS_SRC_ALPHA
35+
36+
m_proj = self.create_projection(90.0, 1.0, 1000.0)
37+
38+
# Rotate and translate
39+
m_mv = self.create_transformation(rotation=(time * 0.0, time * 0, time * 0),
40+
translation=(0.0, 0.0, -40.0))
41+
42+
# Apply the rotation and translation from the system camera
43+
m_mv = matrix44.multiply(m_mv, self.sys_camera.view_matrix)
44+
45+
gravity_pos = vector3.create(math.sin(time) * 5,
46+
math.cos(time) * 5,
47+
math.sin(time / 3) * 5)
48+
gravity_force = math.cos(time / 2) * 3.0 + 3.0
49+
# gravity_force = 2.0
50+
51+
# Transform positions
52+
self.feedback.uniform("gravity_pos", gravity_pos.astype('f4').tobytes())
53+
self.feedback.uniform("gravity_force", gravity_force)
54+
self.feedback.uniform("timedelta", frametime)
55+
self.particles.transform(self.feedback, self.pos)
56+
57+
# Draw particles
58+
self.shader.uniform("m_proj", m_proj.astype('f4').tobytes())
59+
self.shader.uniform("m_mv", m_mv.astype('f4').tobytes())
60+
self.texture.use(location=0)
61+
self.shader.uniform("texture0", 0)
62+
self.particles.draw(self.shader)
63+
64+
# Swap buffers
65+
self.pos = self.pos1 if self.pos == self.pos2 else self.pos2
66+
self.particles = self.particles1 if self.particles == self.particles2 else self.particles2
67+
68+
def init_particles(self):
69+
count = 50000
70+
area = 100.0
71+
speed = 5.0
72+
73+
def gen():
74+
for _ in range(count):
75+
# Position
76+
yield random.uniform(-area, area)
77+
yield random.uniform(-area, area)
78+
yield random.uniform(-area, area)
79+
# Velocity
80+
yield random.uniform(-speed, speed)
81+
yield random.uniform(-speed, speed)
82+
yield random.uniform(-speed, speed)
83+
84+
data1 = numpy.fromiter(gen(), count=count * 6, dtype=numpy.float32)
85+
data2 = numpy.fromiter(gen(), count=count * 6, dtype=numpy.float32)
86+
87+
self.pos1 = self.ctx.buffer(data1.tobytes())
88+
self.particles1 = VAO("particles1", mode=mgl.POINTS)
89+
self.particles1.buffer(self.pos1, '3f 3f', ['in_position', 'in_velocity'])
90+
91+
self.pos2 = self.ctx.buffer(data2.tobytes())
92+
self.particles2 = VAO("particles2", mode=mgl.POINTS)
93+
self.particles2.buffer(self.pos2, '3f 3f', ['in_position', 'in_velocity'])
94+
95+
# Set initial start buffers
96+
self.particles = self.particles1
97+
self.pos = self.pos2
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#version 330
2+
3+
#if defined VERTEX_SHADER
4+
5+
layout (location = 0) in vec3 in_position;
6+
layout (location = 1) in vec3 in_velocity;
7+
8+
out vec3 vert_color;
9+
10+
void main() {
11+
vert_color = vec3(length(in_velocity) / 15.0, 0.25, 0.25);
12+
gl_Position = vec4(in_position, 1.0);
13+
}
14+
15+
#elif defined GEOMETRY_SHADER
16+
17+
layout (points) in;
18+
layout (triangle_strip, max_vertices = 4) out;
19+
20+
uniform mat4 m_proj;
21+
uniform mat4 m_mv;
22+
23+
in vec3 vert_color[1];
24+
out vec2 uv;
25+
out vec3 geo_color;
26+
27+
void main() {
28+
//float size = gl_in[0].gl_PointSize;
29+
//color = size;
30+
const float size = 2.0;
31+
vec3 pos = gl_in[0].gl_Position.xyz;
32+
vec3 right = vec3(m_mv[0][0], m_mv[1][0], m_mv[2][0]);
33+
vec3 up = vec3(m_mv[0][1], m_mv[1][1], m_mv[2][1]);
34+
35+
uv = vec2(1.0, 1.0);
36+
geo_color = vert_color[0];
37+
gl_Position = m_proj * m_mv * vec4(pos + (right + up) * size, 1.0);
38+
EmitVertex();
39+
40+
uv = vec2(0.0, 1.0);
41+
geo_color = vert_color[0];
42+
gl_Position = m_proj * m_mv * vec4(pos + (-right + up) * size, 1.0);
43+
EmitVertex();
44+
45+
uv = vec2(1.0, 0.0);
46+
geo_color = vert_color[0];
47+
gl_Position = m_proj * m_mv * vec4(pos + (right - up) * size, 1.0);
48+
EmitVertex();
49+
50+
uv = vec2(0.0, 0.0);
51+
geo_color = vert_color[0];
52+
gl_Position = m_proj * m_mv * vec4(pos + (-right - up) * size, 1.0);
53+
EmitVertex();
54+
55+
EndPrimitive();
56+
}
57+
58+
#elif defined FRAGMENT_SHADER
59+
60+
out vec4 outColor;
61+
in vec2 uv;
62+
in vec3 geo_color;
63+
64+
uniform sampler2D texture0;
65+
66+
void main() {
67+
outColor = texture(texture0, uv) * vec4(geo_color, 1.0);
68+
}
69+
70+
#endif
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#version 330
2+
3+
#if defined VERTEX_SHADER
4+
5+
layout (location = 0) in vec3 in_position;
6+
layout (location = 1) in vec3 in_velocity;
7+
8+
out vec3 out_position;
9+
out vec3 out_velocity;
10+
11+
uniform float timedelta;
12+
uniform vec3 gravity_pos;
13+
uniform float gravity_force;
14+
15+
void main() {
16+
// direction towards the gravity point
17+
vec3 dir = normalize(gravity_pos - in_position) * gravity_force;
18+
float l = length(gravity_pos - in_position) / 10.0;
19+
// Add gravity to velocity
20+
vec3 vel = in_velocity - (dir / l * timedelta);
21+
out_velocity = vel;
22+
out_position = in_position - (vel * timedelta);
23+
}
24+
25+
#endif
21 KB
Loading
1.14 MB
Loading

0 commit comments

Comments
 (0)