X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_loader.c;fp=vg_loader.c;h=86c7417c2f9112a3d0b37b88f85143e7562224dc;hp=0000000000000000000000000000000000000000;hb=3b14f3dcd5bf9dd3c85144f2123d667bfa4bb63f;hpb=fce86711735b15bff37de0f70716808410fcf269 diff --git a/vg_loader.c b/vg_loader.c new file mode 100644 index 0000000..86c7417 --- /dev/null +++ b/vg_loader.c @@ -0,0 +1,188 @@ +#include "vg_loader.h" +#include "vg_shader.h" + +struct vg_loader vg_loader; + +static struct vg_shader _shader_loader = +{ + .name = "[vg] loader", + .link = NULL, + + /* This is the new foreground shader */ + .vs = + { + .orig_file = NULL, + .static_src = "" + "layout (location=0) in vec2 a_co;" + "out vec2 aUv;" + "void main()" + "{" + "gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);" + "aUv = a_co;" + "}" + }, + .fs = + { + .orig_file = NULL, + .static_src = + + "out vec4 FragColor;" + "uniform float uTime;" + "uniform float uRatio;" + "uniform float uOpacity;" + "in vec2 aUv;" + + "float eval_zero( vec2 uv )" + "{" + "vec4 vsines = sin( (uTime+uv.y*80.0) * vec4(1.1,2.0234,3.73,2.444) );" + "float gradient = min( uv.y, 0.0 );" + "float offset = vsines.x*vsines.y*vsines.z*vsines.w*gradient;" + + "vec2 vpos = uv + vec2( offset, 0.0 );" + "float dist = dot( vpos, vpos );" + + "float fring = step(0.1*0.1,dist) * step(dist,0.15*0.15);" + "return max( 0.0, fring * 1.0+gradient*6.0 );" + "}" + + "void main()" + "{" + "vec3 col = 0.5+0.5*sin( uTime + aUv.xyx + vec3(0.0,2.0,4.0) );" + + "vec2 uvx = aUv - vec2( 0.5 );" + "uvx.x *= uRatio;" + "uvx.y *= 0.75;" + + "float zero = eval_zero( uvx );" + + "float dither=fract(dot(vec2(171.0,231.0),gl_FragCoord.xy)/71.0)-0.5;" + "float fmt1 = step( 0.5, zero*zero + dither )*0.8+0.2;" + + "FragColor = vec4(vec3(fmt1),uOpacity);" + "}" + } +}; + +void vg_loader_init(void) +{ + float quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }; + + glGenVertexArrays( 1, &vg_loader.vao ); + glGenBuffers( 1, &vg_loader.vbo ); + glBindVertexArray( vg_loader.vao ); + glBindBuffer( GL_ARRAY_BUFFER, vg_loader.vbo ); + glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW ); + glBindVertexArray( vg_loader.vao ); + glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, (void*)0 ); + glEnableVertexAttribArray( 0 ); + + VG_CHECK_GL_ERR(); + + if( !vg_shader_compile( &_shader_loader ) ) + vg_fatal_error( "failed to compile shader" ); +} + +static void vg_loader_free(void) +{ + vg_info( "vg_loader_free\n" ); + glDeleteVertexArrays( 1, &vg_loader.vao ); + glDeleteBuffers( 1, &vg_loader.vbo ); + + for( int i=0; i %p\n", step->fn_free ); + step->fn_free(); + } +} + +void vg_loader_render_ring( f32 opacity ) +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + + opacity *= opacity; + + glUseProgram( _shader_loader.id ); + glUniform1f( glGetUniformLocation( _shader_loader.id, "uTime" ), vg.time ); + f32 ratio = (f32)vg.window_x / (f32)vg.window_y; + glUniform1f( glGetUniformLocation( _shader_loader.id, "uRatio"), ratio ); + glUniform1f( glGetUniformLocation( _shader_loader.id, "uOpacity"), opacity ); + glBindVertexArray( vg_loader.vao ); + glDrawArrays( GL_TRIANGLES, 0, 6 ); +} + +void vg_loader_render(void) +{ + glViewport( 0,0, vg.window_x, vg.window_y ); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + vg.loader_ring = 1.0f; +} + +static int _vg_loader_thread( void *pfn ){ + if( setjmp( vg.env_loader_exit ) ) + return 0; + + /* Run client loader */ + //vg_info( "Starting client loader thread @%p\n", pfn ); + void (*call_func)(void *data) = pfn; + call_func( vg.thread_data ); + + SDL_SemPost( vg.sem_loader ); + vg.thread_id_loader = 0; + + return 0; +} + +int vg_loader_availible(void) +{ + if( SDL_SemValue( vg.sem_loader ) ){ + if( !(vg_async.start) ) + return 1; + } + + return 0; +} + +void vg_loader_start( void(*pfn)(void *data), void *data ) +{ + SDL_SemWait( vg.sem_loader ); + + vg.thread_data = data; + SDL_CreateThread( _vg_loader_thread, "vg: loader", pfn ); +} + +/* + * Schedule something to be ran now, freed later. Checks in with engine status + */ +void _vg_loader_step( void( *fn_load )(void), void( *fn_free )(void), + const char *alias ){ + + u64 t0 = SDL_GetPerformanceCounter(); + vg.time_hp_last = vg.time_hp; + + if( fn_load ) + fn_load(); + + u64 udt = SDL_GetPerformanceCounter() - t0; + double dt = (double)udt / (double)SDL_GetPerformanceFrequency(); + vg_info( "ltime [%p] %s: %fs\n", fn_load, alias, dt ); + + if( fn_free ){ + struct loader_free_step step; + step.fn_free = fn_free; + + if( vg_loader.step_count == vg_list_size(vg_loader.step_buffer) ) + vg_fatal_error( "Too many free steps" ); + + vg_loader.step_buffer[ vg_loader.step_count ++ ] = step; + } + + /* TODO: There was a quit checker here, re-add this? */ +}