Particle SystemΒΆ

particle_system

Particle System

 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
import math
import random
import struct

import GLWindow
import ModernGL

# Window & Context

wnd = GLWindow.create_window()
ctx = ModernGL.create_context()

tvert = ctx.vertex_shader('''
    #version 330

    uniform vec2 acc;

    in vec2 in_pos;
    in vec2 in_prev;

    out vec2 out_pos;
    out vec2 out_prev;

    void main() {
        out_pos = in_pos * 2.0 - in_prev + acc;
        out_prev = in_pos;
    }
''')

vert = ctx.vertex_shader('''
    #version 330

    in vec2 vert;

    void main() {
        gl_Position = vec4(vert, 0.0, 1.0);
    }
''')

frag = ctx.fragment_shader('''
    #version 330

    out vec4 color;

    void main() {
        color = vec4(0.30, 0.50, 1.00, 1.0);
    }
''')

prog = ctx.program([vert, frag])

transform = ctx.program(tvert, ['out_pos', 'out_prev'])


def particle():
    a = random.uniform(0.0, math.pi * 2.0)
    r = random.uniform(0.0, 0.001)

    return struct.pack('2f2f', 0.0, 0.0, math.cos(a) * r - 0.003, math.sin(a) * r - 0.008)


vbo1 = ctx.buffer(b''.join(particle() for i in range(1024)))
vbo2 = ctx.buffer(reserve=vbo1.size)

vao1 = ctx.simple_vertex_array(transform, vbo1, ['in_pos', 'in_prev'])
vao2 = ctx.simple_vertex_array(transform, vbo2, ['in_pos', 'in_prev'])

render_vao = ctx.vertex_array(prog, [
    (vbo1, '2f8x', ['vert']),
])

transform.uniforms['acc'].value = (0, -0.0001)

idx = 0

ctx.point_size = 5.0

while wnd.update():
    ctx.viewport = wnd.viewport
    ctx.clear(0.9, 0.9, 0.9)

    for i in range(8):
        vbo1.write(particle(), offset=idx * struct.calcsize('2f2f'))
        idx = (idx + 1) % 1024

    render_vao.render(ModernGL.POINTS, 1024)
    vao1.transform(vbo2, ModernGL.POINTS, 1024)
    ctx.copy_buffer(vbo1, vbo2)