b492cabc36b7d0580fcc029786b4ead5eb0e804a
3 #include "shaders/particle.h"
4 #include "shaders/trail.h"
6 static void trail_increment( trail_system
*sys
){
9 if( sys
->head
== sys
->max
)
12 /* undesirable effect: will remove active points if out of space! */
13 if( sys
->count
< sys
->max
)
17 static void trail_system_update( trail_system
*sys
, f32 dt
,
18 v3f co
, v3f normal
, f32 alpha
){
19 /* update existing points and clip dead ones */
20 bool clip_allowed
= 1;
21 for( i32 i
=0; i
<sys
->count
; i
++ ){
22 i32 i0
= sys
->head
- sys
->count
+ i
;
23 if( i0
< 0 ) i0
+= sys
->max
;
25 trail_point
*p0
= &sys
->array
[i0
];
26 p0
->alpha
-= dt
/sys
->lifetime
;
29 if( p0
->alpha
<= 0.0f
)
36 i32 icur
= sys
->head
-1,
40 if( icur
< 0 ) icur
+= sys
->max
;
41 if( iprev
< 0 ) iprev
+= sys
->max
;
43 trail_point
*pcur
= &sys
->array
[ icur
],
44 *pprev
= &sys
->array
[ iprev
],
45 *phead
= &sys
->array
[ ihead
],
51 if( sys
->count
== 0 ){
52 trail_increment( sys
);
53 v3_copy( (v3f
){0,0,-1}, dir
);
56 else if( sys
->count
== 1 ){
57 if( v3_dist2( pcur
->co
, co
) < k_min
*k_min
)
60 trail_increment( sys
);
62 v3_sub( co
, pcur
->co
, dir
);
65 if( v3_dist2( pprev
->co
, co
) < k_min
*k_min
)
68 if( v3_dist2( pprev
->co
, co
) > sys
->min_dist
*sys
->min_dist
){
69 trail_increment( sys
);
75 v3_sub( co
, pprev
->co
, dir
);
78 v3_cross( dir
, normal
, pdest
->right
);
79 v3_normalize( pdest
->right
);
80 v3_copy( co
, pdest
->co
);
81 v3_copy( normal
, pdest
->normal
);
85 static void trail_system_debug( trail_system
*sys
){
86 for( i32 i
=0; i
<sys
->count
; i
++ ){
87 i32 i0
= sys
->head
- sys
->count
+ i
;
88 if( i0
< 0 ) i0
+= sys
->max
;
90 trail_point
*p0
= &sys
->array
[i0
];
91 vg_line_point( p0
->co
, 0.04f
, 0xff000000 | (u32
)(p0
->alpha
*255.0f
) );
92 vg_line_arrow( p0
->co
, p0
->right
, 0.3f
, VG__GREEN
);
94 if( i
== sys
->count
-1 ) break;
97 if( i1
== sys
->max
) i1
= 0;
99 trail_point
*p1
= &sys
->array
[i1
];
100 vg_line( p0
->co
, p1
->co
, VG__RED
);
104 struct trail_init_args
{
108 static void async_trail_init( void *payload
, u32 size
){
109 struct trail_init_args
*args
= payload
;
110 trail_system
*sys
= args
->sys
;
112 glGenVertexArrays( 1, &sys
->vao
);
113 glGenBuffers( 1, &sys
->vbo
);
114 glBindVertexArray( sys
->vao
);
116 size_t stride
= sizeof(trail_vert
);
118 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
119 glBufferData( GL_ARRAY_BUFFER
, sys
->max
*stride
*2, NULL
, GL_DYNAMIC_DRAW
);
122 glVertexAttribPointer( 0, 4, GL_FLOAT
, GL_FALSE
, stride
, (void*)0 );
123 glEnableVertexAttribArray( 0 );
128 static void trail_alloc( trail_system
*sys
, u32 max
){
129 size_t stride
= sizeof(trail_vert
);
131 sys
->array
= vg_linear_alloc( vg_mem
.rtmemory
, max
*sizeof(trail_point
) );
132 sys
->vertices
= vg_linear_alloc( vg_mem
.rtmemory
, max
*stride
*2 );
134 vg_async_item
*call
= vg_async_alloc( sizeof(struct trail_init_args
) );
136 struct trail_init_args
*init
= call
->payload
;
138 vg_async_dispatch( call
, async_trail_init
);
141 static void trail_system_prerender( trail_system
*sys
){
142 if( sys
->count
< 2 ) return;
144 for( i32 i
=0; i
<sys
->count
; i
++ ){
145 i32 i0
= sys
->head
- sys
->count
+ i
;
146 if( i0
< 0 ) i0
+= sys
->max
;
148 trail_point
*p0
= &sys
->array
[i0
];
149 trail_vert
*v0
= &sys
->vertices
[i
*2+0],
150 *v1
= &sys
->vertices
[i
*2+1];
152 v3_muladds( p0
->co
, p0
->right
, -sys
->width
, v0
->co
);
153 v3_muladds( p0
->co
, p0
->right
, sys
->width
, v1
->co
);
154 v0
->co
[3] = p0
->alpha
;
155 v1
->co
[3] = p0
->alpha
;
158 glBindVertexArray( sys
->vao
);
160 size_t stride
= sizeof(trail_vert
);
161 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
162 glBufferSubData( GL_ARRAY_BUFFER
, 0, sys
->count
*stride
*2, sys
->vertices
);
165 static void trail_system_render( trail_system
*sys
, camera
*cam
){
166 if( sys
->count
< 2 ) return;
167 glDisable( GL_CULL_FACE
);
168 glEnable( GL_DEPTH_TEST
);
171 shader_trail_uPv( cam
->mtx
.pv
);
172 shader_trail_uPvPrev( cam
->mtx_prev
.pv
);
174 glBindVertexArray( sys
->vao
);
175 glDrawArrays( GL_TRIANGLE_STRIP
, 0, sys
->count
*2 );