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