gpu_particle_burst_03.py Full Listing#
gpu_particle_burst_03.py#
1"""
2Example showing how to create particle explosions via the GPU.
3"""
4import random
5import time
6from array import array
7from dataclasses import dataclass
8import arcade
9import arcade.gl
10
11SCREEN_WIDTH = 1024
12SCREEN_HEIGHT = 768
13SCREEN_TITLE = "GPU Particle Explosion"
14
15PARTICLE_COUNT = 300
16
17
18@dataclass
19class Burst:
20 """ Track for each burst. """
21 buffer: arcade.gl.Buffer
22 vao: arcade.gl.Geometry
23 start_time: float
24
25
26class MyWindow(arcade.Window):
27 """ Main window"""
28 def __init__(self):
29 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
30 self.burst_list = []
31
32 # Program to visualize the points
33 self.program = self.ctx.load_program(
34 vertex_shader="vertex_shader_v1.glsl",
35 fragment_shader="fragment_shader.glsl",
36 )
37
38 self.ctx.enable_only()
39
40 def on_draw(self):
41 """ Draw everything """
42 self.clear()
43
44 # Set the particle size
45 self.ctx.point_size = 2 * self.get_pixel_ratio()
46
47 # Loop through each burst
48 for burst in self.burst_list:
49
50 # Set the uniform data
51 self.program['time'] = time.time() - burst.start_time
52
53 # Render the burst
54 burst.vao.render(self.program, mode=self.ctx.POINTS)
55
56 def on_update(self, dt):
57 """ Update everything """
58 pass
59
60 def on_mouse_press(self, x: float, y: float, button: int, modifiers: int):
61 """ User clicks mouse """
62
63 def _gen_initial_data(initial_x, initial_y):
64 """ Generate data for each particle """
65 for i in range(PARTICLE_COUNT):
66 dx = random.uniform(-.2, .2)
67 dy = random.uniform(-.2, .2)
68 yield initial_x
69 yield initial_y
70 yield dx
71 yield dy
72
73 # Recalculate the coordinates from pixels to the OpenGL system with
74 # 0, 0 at the center.
75 x2 = x / self.width * 2. - 1.
76 y2 = y / self.height * 2. - 1.
77
78 # Get initial particle data
79 initial_data = _gen_initial_data(x2, y2)
80
81 # Create a buffer with that data
82 buffer = self.ctx.buffer(data=array('f', initial_data))
83
84 # Create a buffer description that says how the buffer data is formatted.
85 buffer_description = arcade.gl.BufferDescription(buffer,
86 '2f 2f',
87 ['in_pos', 'in_vel'])
88 # Create our Vertex Attribute Object
89 vao = self.ctx.geometry([buffer_description])
90
91 # Create the Burst object and add it to the list of bursts
92 burst = Burst(buffer=buffer, vao=vao, start_time=time.time())
93 self.burst_list.append(burst)
94
95
96if __name__ == "__main__":
97 window = MyWindow()
98 window.center_window()
99 arcade.run()