1 #include "vg/vg_lines.h"
2 #include "vg/vg_async.h"
4 #include "shaders/particle.h"
6 struct particle_system particles_grind
= {
8 .velocity_scale
= 0.001f
,
13 .velocity_scale
= 0.001f
,
17 void particle_spawn( particle_system
*sys
, v3f co
, v3f v
,
18 f32 lifetime
, u32 colour
)
20 if( sys
->alive
== sys
->max
) return;
22 particle
*p
= &sys
->array
[ sys
->alive
++ ];
29 void particle_spawn_cone( particle_system
*sys
,
30 v3f co
, v3f dir
, f32 angle
, f32 speed
,
31 f32 lifetime
, u32 colour
)
33 if( sys
->alive
== sys
->max
) return;
35 particle
*p
= &sys
->array
[ sys
->alive
++ ];
38 v3_tangent_basis( dir
, tx
, ty
);
41 vg_rand_cone( &vg
.rand
, rand
, angle
);
42 v3_muls( tx
, rand
[0]*speed
, p
->v
);
43 v3_muladds( p
->v
, ty
, rand
[1]*speed
, p
->v
);
44 v3_muladds( p
->v
, dir
, rand
[2]*speed
, p
->v
);
51 void particle_system_update( particle_system
*sys
, f32 dt
)
54 iter
: if( i
== sys
->alive
) return;
56 particle
*p
= &sys
->array
[i
];
60 *p
= sys
->array
[ -- sys
->alive
];
64 v3_muladds( p
->co
, p
->v
, dt
, p
->co
);
65 p
->v
[1] += -9.8f
* dt
;
71 void particle_system_debug( particle_system
*sys
)
73 for( u32 i
=0; i
<sys
->alive
; i
++ ){
74 particle
*p
= &sys
->array
[i
];
76 v3_muladds( p
->co
, p
->v
, 0.2f
, p1
);
77 vg_line( p
->co
, p1
, p
->colour
);
81 struct particle_init_args
{
86 static void async_particle_init( void *payload
, u32 size
){
87 struct particle_init_args
*args
= payload
;
88 particle_system
*sys
= args
->sys
;
90 glGenVertexArrays( 1, &sys
->vao
);
91 glGenBuffers( 1, &sys
->vbo
);
92 glGenBuffers( 1, &sys
->ebo
);
93 glBindVertexArray( sys
->vao
);
95 size_t stride
= sizeof(particle_vert
);
97 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
98 glBufferData( GL_ARRAY_BUFFER
, sys
->max
*stride
*4, NULL
, GL_DYNAMIC_DRAW
);
99 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER
, sys
->ebo
);
100 glBufferData( GL_ELEMENT_ARRAY_BUFFER
,
101 sys
->max
*sizeof(u16
)*6, args
->indices
, GL_STATIC_DRAW
);
104 glVertexAttribPointer( 0, 3, GL_FLOAT
, GL_FALSE
, stride
, (void*)0 );
105 glEnableVertexAttribArray( 0 );
108 glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE
, GL_TRUE
,
109 stride
, (void *)offsetof(particle_vert
, colour
) );
110 glEnableVertexAttribArray( 1 );
115 void particle_alloc( particle_system
*sys
, u32 max
)
117 size_t stride
= sizeof(particle_vert
);
120 sys
->array
= vg_linear_alloc( vg_mem
.rtmemory
, max
*sizeof(particle
) );
121 sys
->vertices
= vg_linear_alloc( vg_mem
.rtmemory
, max
*stride
*4 );
123 vg_async_item
*call
=
124 vg_async_alloc( sizeof(particle_system
*) + max
*sizeof(u16
)*6 );
125 struct particle_init_args
*init
= call
->payload
;
128 for( u32 i
=0; i
<max
; i
++ ){
129 init
->indices
[i
*6+0] = i
*4;
130 init
->indices
[i
*6+1] = i
*4+1;
131 init
->indices
[i
*6+2] = i
*4+2;
132 init
->indices
[i
*6+3] = i
*4;
133 init
->indices
[i
*6+4] = i
*4+2;
134 init
->indices
[i
*6+5] = i
*4+3;
137 vg_async_dispatch( call
, async_particle_init
);
140 void particle_system_prerender( particle_system
*sys
)
142 for( u32 i
=0; i
<sys
->alive
; i
++ ){
143 particle
*p
= &sys
->array
[i
];
144 particle_vert
*vs
= &sys
->vertices
[i
*4];
149 f32 vm
= v3_length( p
->v
);
150 v3_muls( v
, 1.0f
/vm
, v
);
151 v3_cross( v
, (v3f
){0,1,0}, right
);
153 f32 l
= (sys
->scale
+sys
->velocity_scale
*vm
),
157 v3_muladds( p
->co
, p
->v
, l
, p0
);
158 v3_muladds( p
->co
, p
->v
, -l
, p1
);
160 v3_muladds( p0
, right
, w
, vs
[0].co
);
161 v3_muladds( p1
, right
, w
, vs
[1].co
);
162 v3_muladds( p1
, right
, -w
, vs
[2].co
);
163 v3_muladds( p0
, right
, -w
, vs
[3].co
);
165 vs
[0].colour
= p
->colour
;
166 vs
[1].colour
= p
->colour
;
167 vs
[2].colour
= p
->colour
;
168 vs
[3].colour
= p
->colour
;
171 glBindVertexArray( sys
->vao
);
173 size_t stride
= sizeof(particle_vert
);
174 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
175 glBufferSubData( GL_ARRAY_BUFFER
, 0, sys
->alive
*stride
*4, sys
->vertices
);
178 void particle_system_render( particle_system
*sys
, vg_camera
*cam
)
180 glDisable( GL_CULL_FACE
);
181 glEnable( GL_DEPTH_TEST
);
183 shader_particle_use();
184 shader_particle_uPv( cam
->mtx
.pv
);
185 shader_particle_uPvPrev( cam
->mtx_prev
.pv
);
187 glBindVertexArray( sys
->vao
);
188 glDrawElements( GL_TRIANGLES
, sys
->alive
*6, GL_UNSIGNED_SHORT
, NULL
);