gpu_particle_burst_05.py Full Listing#
gpu_particle_burst_05.py#
1"""
2Example showing how to create particle explosions via the GPU.
3"""
4import random
5import time
6import math
7from array import array
8from dataclasses import dataclass
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 angle = random.uniform(0, 2 * math.pi)
68 speed = abs(random.gauss(0, 1)) * .5
69 dx = math.sin(angle) * speed
70 dy = math.cos(angle) * speed
71 yield initial_x
72 yield initial_y
73 yield dx
74 yield dy
75
76 # Recalculate the coordinates from pixels to the OpenGL system with
77 # 0, 0 at the center.
78 x2 = x / self.width * 2. - 1.
79 y2 = y / self.height * 2. - 1.
80
81 # Get initial particle data
82 initial_data = _gen_initial_data(x2, y2)
83
84 # Create a buffer with that data
85 buffer = self.ctx.buffer(data=array('f', initial_data))
86
87 # Create a buffer description that says how the buffer data is formatted.
88 buffer_description = arcade.gl.BufferDescription(buffer,
89 '2f 2f',
90 ['in_pos', 'in_vel'])
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()