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