2 #include "vg/vg_engine.h"
3 #include "vg/vg_platform.h"
5 #include "vg/vg_lines.h"
6 #include "vg/vg_async.h"
7 #include "vg/vg_camera.h"
9 #include "shaders/particle.h"
10 #include "shaders/trail.h"
12 static void trail_increment( trail_system
*sys
){
15 if( sys
->head
== sys
->max
)
18 /* undesirable effect: will remove active points if out of space! */
19 if( sys
->count
< sys
->max
)
23 void trail_system_update( trail_system
*sys
, f32 dt
,
24 v3f co
, v3f normal
, f32 alpha
)
26 /* update existing points and clip dead ones */
27 bool clip_allowed
= 1;
28 for( i32 i
=0; i
<sys
->count
; i
++ ){
29 i32 i0
= sys
->head
- sys
->count
+ i
;
30 if( i0
< 0 ) i0
+= sys
->max
;
32 trail_point
*p0
= &sys
->array
[i0
];
33 p0
->alpha
-= dt
/sys
->lifetime
;
36 if( p0
->alpha
<= 0.0f
)
43 i32 icur
= sys
->head
-1,
47 if( icur
< 0 ) icur
+= sys
->max
;
48 if( iprev
< 0 ) iprev
+= sys
->max
;
50 trail_point
*pcur
= &sys
->array
[ icur
],
51 *pprev
= &sys
->array
[ iprev
],
52 *phead
= &sys
->array
[ ihead
],
58 if( sys
->count
== 0 ){
59 trail_increment( sys
);
60 v3_copy( (v3f
){0,0,-1}, dir
);
63 else if( sys
->count
== 1 ){
64 if( v3_dist2( pcur
->co
, co
) < k_min
*k_min
)
67 trail_increment( sys
);
69 v3_sub( co
, pcur
->co
, dir
);
72 if( v3_dist2( pprev
->co
, co
) < k_min
*k_min
)
75 if( v3_dist2( pprev
->co
, co
) > sys
->min_dist
*sys
->min_dist
){
76 trail_increment( sys
);
82 v3_sub( co
, pprev
->co
, dir
);
85 v3_cross( dir
, normal
, pdest
->right
);
86 v3_normalize( pdest
->right
);
87 v3_copy( co
, pdest
->co
);
88 v3_copy( normal
, pdest
->normal
);
92 void trail_system_debug( trail_system
*sys
)
94 for( i32 i
=0; i
<sys
->count
; i
++ ){
95 i32 i0
= sys
->head
- sys
->count
+ i
;
96 if( i0
< 0 ) i0
+= sys
->max
;
98 trail_point
*p0
= &sys
->array
[i0
];
99 vg_line_point( p0
->co
, 0.04f
, 0xff000000 | (u32
)(p0
->alpha
*255.0f
) );
100 vg_line_arrow( p0
->co
, p0
->right
, 0.3f
, VG__GREEN
);
102 if( i
== sys
->count
-1 ) break;
105 if( i1
== sys
->max
) i1
= 0;
107 trail_point
*p1
= &sys
->array
[i1
];
108 vg_line( p0
->co
, p1
->co
, VG__RED
);
112 struct trail_init_args
{
116 void async_trail_init( void *payload
, u32 size
)
118 struct trail_init_args
*args
= payload
;
119 trail_system
*sys
= args
->sys
;
121 glGenVertexArrays( 1, &sys
->vao
);
122 glGenBuffers( 1, &sys
->vbo
);
123 glBindVertexArray( sys
->vao
);
125 size_t stride
= sizeof(trail_vert
);
127 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
128 glBufferData( GL_ARRAY_BUFFER
, sys
->max
*stride
*2, NULL
, GL_DYNAMIC_DRAW
);
131 glVertexAttribPointer( 0, 4, GL_FLOAT
, GL_FALSE
, stride
, (void*)0 );
132 glEnableVertexAttribArray( 0 );
137 void trail_alloc( trail_system
*sys
, u32 max
)
139 size_t stride
= sizeof(trail_vert
);
141 sys
->array
= vg_linear_alloc( vg_mem
.rtmemory
, max
*sizeof(trail_point
) );
142 sys
->vertices
= vg_linear_alloc( vg_mem
.rtmemory
, max
*stride
*2 );
144 vg_async_item
*call
= vg_async_alloc( sizeof(struct trail_init_args
) );
146 struct trail_init_args
*init
= call
->payload
;
148 vg_async_dispatch( call
, async_trail_init
);
151 void trail_system_prerender( trail_system
*sys
)
153 if( sys
->count
< 2 ) return;
155 for( i32 i
=0; i
<sys
->count
; i
++ ){
156 i32 i0
= sys
->head
- sys
->count
+ i
;
157 if( i0
< 0 ) i0
+= sys
->max
;
159 trail_point
*p0
= &sys
->array
[i0
];
160 trail_vert
*v0
= &sys
->vertices
[i
*2+0],
161 *v1
= &sys
->vertices
[i
*2+1];
163 v3_muladds( p0
->co
, p0
->right
, -sys
->width
, v0
->co
);
164 v3_muladds( p0
->co
, p0
->right
, sys
->width
, v1
->co
);
165 v0
->co
[3] = p0
->alpha
;
166 v1
->co
[3] = p0
->alpha
;
169 glBindVertexArray( sys
->vao
);
171 size_t stride
= sizeof(trail_vert
);
172 glBindBuffer( GL_ARRAY_BUFFER
, sys
->vbo
);
173 glBufferSubData( GL_ARRAY_BUFFER
, 0, sys
->count
*stride
*2, sys
->vertices
);
176 void trail_system_render( trail_system
*sys
, vg_camera
*cam
)
178 if( sys
->count
< 2 ) return;
179 glDisable( GL_CULL_FACE
);
180 glEnable( GL_DEPTH_TEST
);
183 shader_trail_uPv( cam
->mtx
.pv
);
184 shader_trail_uPvPrev( cam
->mtx_prev
.pv
);
185 shader_trail_uColour( (v4f
){1.0f
,1.0f
,1.0f
,1.0f
} );
187 glBindVertexArray( sys
->vao
);
188 glDrawArrays( GL_TRIANGLE_STRIP
, 0, sys
->count
*2 );