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