bad char
[vg.git] / vg_loader.c
1 #include "vg_engine.h"
2 #include "vg_loader.h"
3 #include "vg_shader.h"
4 #include "vg_async.h"
5
6 struct vg_loader vg_loader;
7
8 static struct vg_shader _shader_loader =
9 {
10 .name = "[vg] loader",
11
12 /* This is the new foreground shader */
13 .vs =
14 {
15 .orig_file = NULL,
16 .static_src = ""
17 "layout (location=0) in vec2 a_co;"
18 "out vec2 aUv;"
19 "void main()"
20 "{"
21 "gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);"
22 "aUv = a_co;"
23 "}"
24 },
25 .fs =
26 {
27 .orig_file = NULL,
28 .static_src =
29
30 "out vec4 FragColor;"
31 "uniform float uTime;"
32 "uniform float uRatio;"
33 "uniform float uOpacity;"
34 "in vec2 aUv;"
35
36 "float eval_zero( vec2 uv )"
37 "{"
38 "vec4 vsines = sin( (uTime+uv.y*80.0) * vec4(1.1,2.0234,3.73,2.444) );"
39 "float gradient = min( uv.y, 0.0 );"
40 "float offset = vsines.x*vsines.y*vsines.z*vsines.w*gradient;"
41
42 "vec2 vpos = uv + vec2( offset, 0.0 );"
43 "float dist = dot( vpos, vpos );"
44
45 "float fring = step(0.1*0.1,dist) * step(dist,0.15*0.15);"
46 "return max( 0.0, fring * 1.0+gradient*6.0 );"
47 "}"
48
49 "void main()"
50 "{"
51 "vec3 col = 0.5+0.5*sin( uTime + aUv.xyx + vec3(0.0,2.0,4.0) );"
52
53 "vec2 uvx = aUv - vec2( 0.5 );"
54 "uvx.x *= uRatio;"
55 "uvx.y *= 0.75;"
56
57 "float zero = eval_zero( uvx );"
58
59 "float dither=fract(dot(vec2(171.0,231.0),gl_FragCoord.xy)/71.0)-0.5;"
60 "float fmt1 = step( 0.5, zero*zero + dither )*0.8+0.2;"
61
62 "FragColor = vec4(vec3(fmt1),uOpacity);"
63 "}"
64 }
65 };
66
67 void vg_loader_init(void)
68 {
69 float quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
70 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
71
72 glGenVertexArrays( 1, &vg_loader.vao );
73 glGenBuffers( 1, &vg_loader.vbo );
74 glBindVertexArray( vg_loader.vao );
75 glBindBuffer( GL_ARRAY_BUFFER, vg_loader.vbo );
76 glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW );
77 glBindVertexArray( vg_loader.vao );
78 glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, (void*)0 );
79 glEnableVertexAttribArray( 0 );
80
81 VG_CHECK_GL_ERR();
82
83 if( !vg_shader_compile( &_shader_loader ) )
84 vg_fatal_error( "failed to compile shader" );
85 }
86
87 static void vg_loader_free(void)
88 {
89 vg_info( "vg_loader_free\n" );
90 glDeleteVertexArrays( 1, &vg_loader.vao );
91 glDeleteBuffers( 1, &vg_loader.vbo );
92
93 for( int i=0; i<vg_loader.step_count; i++ )
94 {
95 struct loader_free_step *step =
96 &vg_loader.step_buffer[vg_loader.step_count -1 -i];
97
98 vg_info( " -> %p\n", step->fn_free );
99 step->fn_free();
100 }
101 }
102
103 void vg_loader_render_ring( f32 opacity )
104 {
105 glEnable(GL_BLEND);
106 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
107 glBlendEquation(GL_FUNC_ADD);
108
109 opacity *= opacity;
110
111 glUseProgram( _shader_loader.id );
112 glUniform1f( glGetUniformLocation( _shader_loader.id, "uTime" ), vg.time );
113 f32 ratio = (f32)vg.window_x / (f32)vg.window_y;
114 glUniform1f( glGetUniformLocation( _shader_loader.id, "uRatio"), ratio );
115 glUniform1f( glGetUniformLocation( _shader_loader.id, "uOpacity"), opacity );
116 glBindVertexArray( vg_loader.vao );
117 glDrawArrays( GL_TRIANGLES, 0, 6 );
118 }
119
120 void vg_loader_render(void)
121 {
122 glViewport( 0,0, vg.window_x, vg.window_y );
123 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
124 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
125 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
126 vg.loader_ring = 1.0f;
127 }
128
129 static int _vg_loader_thread( void *pfn ){
130 if( setjmp( vg.env_loader_exit ) )
131 return 0;
132
133 /* Run client loader */
134 //vg_info( "Starting client loader thread @%p\n", pfn );
135 void (*call_func)(void *data) = pfn;
136 call_func( vg.thread_data );
137
138 SDL_SemPost( vg.sem_loader );
139 vg.thread_id_loader = 0;
140
141 return 0;
142 }
143
144 int vg_loader_availible(void)
145 {
146 if( SDL_SemValue( vg.sem_loader ) ){
147 if( !(vg_async.start) )
148 return 1;
149 }
150
151 return 0;
152 }
153
154 void vg_loader_start( void(*pfn)(void *data), void *data )
155 {
156 SDL_SemWait( vg.sem_loader );
157
158 vg.thread_data = data;
159 SDL_CreateThread( _vg_loader_thread, "vg: loader", pfn );
160 }
161
162 /*
163 * Schedule something to be ran now, freed later. Checks in with engine status
164 */
165 void _vg_loader_step( void( *fn_load )(void), void( *fn_free )(void),
166 const char *alias ){
167
168 u64 t0 = SDL_GetPerformanceCounter();
169 vg.time_hp_last = vg.time_hp;
170
171 if( fn_load )
172 fn_load();
173
174 u64 udt = SDL_GetPerformanceCounter() - t0;
175 double dt = (double)udt / (double)SDL_GetPerformanceFrequency();
176 vg_info( "ltime [%p] %s: %fs\n", fn_load, alias, dt );
177
178 if( fn_free ){
179 struct loader_free_step step;
180 step.fn_free = fn_free;
181
182 if( vg_loader.step_count == vg_list_size(vg_loader.step_buffer) )
183 vg_fatal_error( "Too many free steps" );
184
185 vg_loader.step_buffer[ vg_loader.step_count ++ ] = step;
186 }
187
188 /* TODO: There was a quit checker here, re-add this? */
189 }