13cc5d423c2b364da639e4a06f8d86ed077101a7
3 static void particle_spawn( particle_system
*sys
,
4 v3f co
, v3f v
, f32 lifetime
, u32 colour
){
5 if( sys
->alive
== sys
->max
) return;
7 particle
*p
= &sys
->array
[ sys
->alive
++ ];
14 static void particle_spawn_cone( particle_system
*sys
,
15 v3f co
, v3f dir
, f32 angle
, f32 speed
,
16 f32 lifetime
, u32 colour
){
17 if( sys
->alive
== sys
->max
) return;
19 particle
*p
= &sys
->array
[ sys
->alive
++ ];
22 v3_tangent_basis( dir
, tx
, ty
);
25 vg_rand_cone( rand
, angle
);
26 v3_muls( tx
, rand
[0]*speed
, p
->v
);
27 v3_muladds( p
->v
, ty
, rand
[1]*speed
, p
->v
);
28 v3_muladds( p
->v
, dir
, rand
[2]*speed
, p
->v
);
35 static void particle_system_update( particle_system
*sys
, f32 dt
){
37 iter
: if( i
== sys
->alive
) return;
39 particle
*p
= &sys
->array
[i
];
43 *p
= sys
->array
[ -- sys
->alive
];
47 v3_muladds( p
->co
, p
->v
, dt
, p
->co
);
48 p
->v
[1] += -9.8f
* dt
;
54 static void particle_system_debug( particle_system
*sys
){
55 for( u32 i
=0; i
<sys
->alive
; i
++ ){
56 particle
*p
= &sys
->array
[i
];
58 v3_muladds( p
->co
, p
->v
, 0.2f
, p1
);
59 vg_line( p
->co
, p1
, p
->colour
);
63 struct particle_init_args
{
68 static void async_particle_init( void *payload
, u32 size
){
69 struct particle_init_args
*args
= payload
;
70 particle_system
*sys
= args
->sys
;
72 glGenVertexArrays( 1, &sys
->vao
);
73 glGenBuffers( 1, &sys
->vbo
);
74 glGenBuffers( 1, &sys
->ebo
);
75 glBindVertexArray( sys
->vao
);
77 size_t stride
= sizeof(particle_vert
);
79 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
80 glBufferData( GL_ARRAY_BUFFER
, sys
->max
*stride
*4, NULL
, GL_DYNAMIC_DRAW
);
81 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER
, sys
->ebo
);
82 glBufferData( GL_ELEMENT_ARRAY_BUFFER
,
83 sys
->max
*sizeof(u16
)*6, args
->indices
, GL_STATIC_DRAW
);
86 glVertexAttribPointer( 0, 3, GL_FLOAT
, GL_FALSE
, stride
, (void*)0 );
87 glEnableVertexAttribArray( 0 );
90 glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE
, GL_TRUE
,
91 stride
, (void *)offsetof(particle_vert
, colour
) );
92 glEnableVertexAttribArray( 1 );
97 static void particle_alloc( particle_system
*sys
, u32 max
){
100 shader_particle_register();
104 size_t stride
= sizeof(particle_vert
);
107 sys
->array
= vg_linear_alloc( vg_mem
.rtmemory
, max
*sizeof(particle
) );
108 sys
->vertices
= vg_linear_alloc( vg_mem
.rtmemory
, max
*stride
*4 );
110 vg_async_item
*call
=
111 vg_async_alloc( sizeof(particle_system
*) + max
*sizeof(u16
)*6 );
112 struct particle_init_args
*init
= call
->payload
;
115 for( u32 i
=0; i
<max
; i
++ ){
116 init
->indices
[i
*6+0] = i
*4;
117 init
->indices
[i
*6+1] = i
*4+1;
118 init
->indices
[i
*6+2] = i
*4+2;
119 init
->indices
[i
*6+3] = i
*4;
120 init
->indices
[i
*6+4] = i
*4+2;
121 init
->indices
[i
*6+5] = i
*4+3;
124 vg_async_dispatch( call
, async_particle_init
);
127 static void particle_system_prerender( particle_system
*sys
){
128 for( u32 i
=0; i
<sys
->alive
; i
++ ){
129 particle
*p
= &sys
->array
[i
];
130 particle_vert
*vs
= &sys
->vertices
[i
*4];
135 f32 vm
= v3_length( p
->v
);
136 v3_muls( v
, 1.0f
/vm
, v
);
137 v3_cross( v
, (v3f
){0,1,0}, right
);
139 f32 l
= (sys
->scale
+sys
->velocity_scale
*vm
),
143 v3_muladds( p
->co
, p
->v
, l
, p0
);
144 v3_muladds( p
->co
, p
->v
, -l
, p1
);
146 v3_muladds( p0
, right
, w
, vs
[0].co
);
147 v3_muladds( p1
, right
, w
, vs
[1].co
);
148 v3_muladds( p1
, right
, -w
, vs
[2].co
);
149 v3_muladds( p0
, right
, -w
, vs
[3].co
);
151 vs
[0].colour
= p
->colour
;
152 vs
[1].colour
= p
->colour
;
153 vs
[2].colour
= p
->colour
;
154 vs
[3].colour
= p
->colour
;
157 glBindVertexArray( sys
->vao
);
159 size_t stride
= sizeof(particle_vert
);
160 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
161 glBufferSubData( GL_ARRAY_BUFFER
, 0, sys
->alive
*stride
*4, sys
->vertices
);
164 static void particle_system_render( particle_system
*sys
, camera
*cam
){
165 glDisable( GL_CULL_FACE
);
166 glEnable( GL_DEPTH_TEST
);
168 shader_particle_use();
169 shader_particle_uPv( cam
->mtx
.pv
);
170 shader_particle_uPvPrev( cam
->mtx_prev
.pv
);
172 glBindVertexArray( sys
->vao
);
173 glDrawElements( GL_TRIANGLES
, sys
->alive
*6, GL_UNSIGNED_SHORT
, NULL
);