trail rendering basics
[carveJwlIkooP6JGAAIwe30JlM.git] / trail.c
1 #pragma once
2 #include "trail.h"
3
4 static void trail_system_update( trail_system *sys, f32 dt,
5 v3f co, v3f normal, f32 alpha ){
6 /* update existing points and clip dead ones */
7 bool clip_allowed = 1;
8 for( i32 i=0; i<sys->count; i ++ ){
9 i32 i0 = sys->head - sys->count + i;
10 if( i0 < 0 ) i0 += sys->max;
11
12 trail_point *p0 = &sys->array[i0];
13 p0->alpha -= dt/sys->lifetime;
14
15 if( clip_allowed ){
16 if( p0->alpha <= 0.0f )
17 sys->count --;
18 else
19 clip_allowed = 0;
20 }
21 }
22
23 bool add_point = 1;
24 i32 index_current = sys->head;
25 if( sys->count >= 2 ) index_current = sys->head -1;
26
27 i32 index_prev = index_current -1;
28
29 if( index_current < 0 ) index_current += sys->max;
30 if( index_prev < 0 ) index_prev += sys->max;
31
32 /* always enforced non-zero distance */
33 if( sys->count >= 1 ){
34 if( v3_dist2( sys->array[index_prev].co, co ) < 0.001f*0.001f )
35 return;
36 }
37
38 /* copy new info in */
39 trail_point *p_current = &sys->array[index_current];
40 v3_copy( co, p_current->co );
41 v3_copy( normal, p_current->normal );
42 p_current->alpha = alpha;
43
44 /* update direction */
45 if( sys->count >= 2 ){
46 trail_point *p_prev = &sys->array[index_prev];
47
48 v3f dir;
49 v3_sub( co, p_prev->co, dir );
50 v3_normalize( dir );
51 v3_cross( dir, normal, p_current->right );
52 v3_copy( p_current->right, p_prev->right );
53
54 /* decide if to prevent split based on user min-distance */
55 if( v3_dist2( p_prev->co, co ) < sys->min_dist*sys->min_dist )
56 add_point = 0;
57 }
58 else
59 v3_zero( p_current->right );
60
61 if( add_point ){
62 sys->head ++;
63
64 if( sys->head == sys->max )
65 sys->head = 0;
66
67 /* undesirable effect: will remove active points if out of space! */
68 if( sys->count < sys->max )
69 sys->count ++;
70
71 index_current = sys->head;
72 }
73
74 p_current = &sys->array[index_current];
75 v3_copy( co, p_current->co );
76 v3_copy( normal, p_current->normal );
77 p_current->alpha = alpha;
78 v3_zero( p_current->right );
79 }
80
81 static void trail_system_debug( trail_system *sys ){
82 for( i32 i=0; i<sys->count; i ++ ){
83 i32 i0 = sys->head - sys->count + i;
84 if( i0 < 0 ) i0 += sys->max;
85
86 trail_point *p0 = &sys->array[i0];
87 vg_line_point( p0->co, 0.04f, 0xff000000 | (u32)(p0->alpha*255.0f) );
88 vg_line_arrow( p0->co, p0->right, 0.3f, VG__GREEN );
89
90 if( i == sys->count-1 ) break;
91
92 i32 i1 = i0+1;
93 if( i1 == sys->max ) i1 = 0;
94
95 trail_point *p1 = &sys->array[i1];
96 vg_line( p0->co, p1->co, VG__RED );
97 }
98 }
99
100 struct trail_init_args {
101 trail_system *sys;
102 };
103
104 static void async_trail_init( void *payload, u32 size ){
105 struct trail_init_args *args = payload;
106 trail_system *sys = args->sys;
107
108 glGenVertexArrays( 1, &sys->vao );
109 glGenBuffers( 1, &sys->vbo );
110 glBindVertexArray( sys->vao );
111
112 size_t stride = sizeof(trail_vert);
113
114 glBindBuffer( GL_ARRAY_BUFFER, sys->vbo );
115 glBufferData( GL_ARRAY_BUFFER, sys->max*stride*2, NULL, GL_DYNAMIC_DRAW );
116
117 /* 0: coordinates */
118 glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, (void*)0 );
119 glEnableVertexAttribArray( 0 );
120
121 VG_CHECK_GL_ERR();
122 }
123
124 static void trail_alloc( trail_system *sys, u32 max ){
125 size_t stride = sizeof(trail_vert);
126 sys->max = max;
127 sys->array = vg_linear_alloc( vg_mem.rtmemory, max*sizeof(trail_point) );
128 sys->vertices = vg_linear_alloc( vg_mem.rtmemory, max*stride*2 );
129
130 vg_async_item *call = vg_async_alloc( sizeof(struct trail_init_args) );
131
132 struct trail_init_args *init = call->payload;
133 init->sys = sys;
134 vg_async_dispatch( call, async_trail_init );
135 }
136
137 static void trail_system_prerender( trail_system *sys ){
138 #if 0
139 glBindVertexArray( sys->vao );
140
141 size_t stride = sizeof(trail_vert);
142 glBindBuffer( GL_ARRAY_BUFFER, sys->vbo );
143 glBufferSubData( GL_ARRAY_BUFFER, 0, sys->alive*stride*4, sys->vertices );
144 #endif
145 }
146
147 static void trail_system_render( trail_system *sys, camera *cam ){
148 #if 0
149 glDisable( GL_CULL_FACE );
150 glEnable( GL_DEPTH_TEST );
151
152 shader_trail_use();
153 shader_trail_uPv( cam->mtx.pv );
154 shader_trail_uPvPrev( cam->mtx_prev.pv );
155
156 glBindVertexArray( sys->vao );
157 glDrawElements( GL_TRIANGLES, sys->alive*6, GL_UNSIGNED_SHORT, NULL );
158 #endif
159 }