X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=src%2Fvg%2Fvg_shader.h;h=516d1a84c67587c7e44d56fe2853c870de252138;hb=3dd767bb10e6fee9cbffeb185d1a9685810c17b5;hp=0f1303bc3c540768e3218c57f5047af7c3c3e462;hpb=f9b8c958c6221365d88a248e645aaebb6f7f1b90;p=vg.git diff --git a/src/vg/vg_shader.h b/src/vg/vg_shader.h index 0f1303b..516d1a8 100644 --- a/src/vg/vg_shader.h +++ b/src/vg/vg_shader.h @@ -1,69 +1,47 @@ /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */ -const char *vg_shader_gl_ver = "#version 330 core\n"; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-type" -static inline int static_str_index( const char *list[], int len, - const char *str ) -{ - for( int i = 0; i < len; i ++ ) - { - if( !strcmp(list[i],str) ) - return i; - } - - #ifndef VG_RELEASE - fprintf( stderr, "That was not a static string index!! (%s)\n", str ); - abort(); - #endif -} -#pragma GCC diagnostic pop +#ifndef VG_SHADER_H +#define VG_SHADER_H -#define SHADER_NAME( NAME ) (NAME##_static_shader.program) -#define SHADER_USE( NAME ) glUseProgram( NAME##_static_shader.program ) +#include "vg/vg.h" +#include "vg/vg_platform.h" -#define SHADER_UNIFORM( NAME, U ) \ - NAME##_shader_uniforms[ STR_STATIC_INDEX( NAME##_shader_names, U ) ] -#define SHADER_UNIFORM_NAME( NAME, UID ) NAME##_shader_names[ UID ] -#define STR_STATIC_INDEX( LIST, STR ) \ - static_str_index( LIST, vg_list_size(LIST), STR ) +#if 0 +#define STB_INCLUDE_IMPLEMENTATION +#define STB_INCLUDE_LINE_GLSL +#define STB_MALLOC vg_alloc +#define STB_FREE vg_free +#define STB_REALLOC vg_realloc +#include "stb/stb_include.h" +#endif -#define UNIFORMS(...) __VA_ARGS__ - -#define SHADER_DEFINE( NAME, VERT, FRAG, UNIFORMS ) \ - const char * NAME##_shader_names[] = UNIFORMS; \ - GLint NAME##_shader_uniforms[ vg_list_size( NAME##_shader_names ) ]; \ - struct vg_shader NAME##_static_shader = { \ - .src_vert = VERT, .src_frag = FRAG, \ - .sym = #NAME "_static.shader", \ - .uniform_names = NAME##_shader_names, \ - .uniforms = NAME##_shader_uniforms, \ - .uniform_count = vg_list_size( NAME##_shader_names ), \ - }; - -#define SHADER_INIT( NAME ) arrpush( vg_shaders_active, &NAME##_static_shader ) +const char *vg_shader_gl_ver = "#version 330 core\n"; -#define SHADER_STATUS_NONE 0x00 -#define SHADER_STATUS_COMPILED 0x1 +typedef struct vg_shader vg_shader; -struct vg_shader +struct { - GLuint program; - - const char *src_vert; - const char *src_frag; - const char *src_geo; - const char *sym; - - const char **uniform_names; - GLint *uniforms; - u32 uniform_count; - u32 status; + struct vg_shader + { + GLuint id; + const char *name; + + struct vg_subshader + { + const char *orig_file, + *static_src; + } + vs, fs; + + void (*link)(void); + int compiled; + } + * shaders[32]; + u32 count; } -** vg_shaders_active = NULL; +static vg_shaders; -static GLuint vg_shader_subshader( const char *src, GLint gliShaderType ) +VG_STATIC GLuint vg_shader_subshader( const char *src, GLint gliShaderType ) { GLint shader = glCreateShader( gliShaderType ); @@ -73,7 +51,7 @@ static GLuint vg_shader_subshader( const char *src, GLint gliShaderType ) return 0; } - glShaderSource( shader, 2, (const char *[2]){ vg_shader_gl_ver, src }, NULL ); + glShaderSource( shader, 2, (const char*[2]){ vg_shader_gl_ver, src }, NULL ); glCompileShader( shader ); GLint status; @@ -92,92 +70,150 @@ static GLuint vg_shader_subshader( const char *src, GLint gliShaderType ) return shader; } -static int vg_shader_compile( struct vg_shader *shader ) +VG_STATIC int vg_shader_compile( struct vg_shader *shader ) { - vg_info( "Compile shader '%s'\n", shader->sym ); + vg_info( "Compile shader '%s'\n", shader->name ); - GLuint vert, frag, geo = 0; + GLuint program, vert, frag; + const char *svs, *sfs; + char *avs, *afs; + + int static_src = 1; + + /* If we are compiling this again, we obviously need to try to take the src + * from the disk instead. + * + * Only do this if we have filenames set on the shader, so engine shaders + * dont have to do it (text.. etc). + */ + if( shader->compiled ) + { + if( shader->vs.orig_file && shader->fs.orig_file ) + static_src = 0; + else return 1; + } + + if( static_src ) + { + svs = shader->vs.static_src; + sfs = shader->fs.static_src; + } + else + { + vg_fatal_exit_loop( "Unimplemented" ); + +#if 0 + char error[260]; + char path[260]; + strcpy( path, shader->vs.orig_file ); + avs = stb_include_file( path, "", "../../shaders", error ); + + strcpy( path, shader->fs.orig_file ); + afs = stb_include_file( path, "", "../../shaders", error ); + + if( !avs || !afs ) + { + vg_error( "Could not find shader source files (%s)\n", + shader->vs.orig_file ); + + vg_free( avs ); + vg_free( afs ); + return 0; + } + + svs = avs; + sfs = afs; +#endif + } - vert = vg_shader_subshader( shader->src_vert, GL_VERTEX_SHADER ); - frag = vg_shader_subshader( shader->src_frag, GL_FRAGMENT_SHADER ); + vert = vg_shader_subshader( svs, GL_VERTEX_SHADER ); + frag = vg_shader_subshader( sfs, GL_FRAGMENT_SHADER ); +#if 0 + if( !static_src ) + { + free( avs ); + free( afs ); + } +#endif + if( !vert || !frag ) return 0; - if( shader->src_geo ) - { - geo = vg_shader_subshader( shader->src_geo, GL_GEOMETRY_SHADER ); - - if( !geo ) - return 0; - } - - shader->program = glCreateProgram(); - if( geo ) - glAttachShader( shader->program, geo ); + program = glCreateProgram(); - glAttachShader( shader->program, vert ); - glAttachShader( shader->program, frag ); - glLinkProgram( shader->program ); + glAttachShader( program, vert ); + glAttachShader( program, frag ); + glLinkProgram( program ); glDeleteShader( vert ); glDeleteShader( frag ); - - if( geo ) - glDeleteShader( geo ); /* Check for link errors */ char infoLog[ 512 ]; int success_link = 1; - glGetProgramiv( shader->program, GL_LINK_STATUS, &success_link ); + glGetProgramiv( program, GL_LINK_STATUS, &success_link ); if( !success_link ) { - glGetProgramInfoLog( shader->program, 512, NULL, infoLog ); + glGetProgramInfoLog( program, 512, NULL, infoLog ); vg_error( "Link failed: %s\n", infoLog ); - glDeleteProgram( shader->program ); - + glDeleteProgram( program ); return 0; } - /* Complete linkeage */ - for( int i = 0; i < shader->uniform_count; i ++ ) - { - shader->uniforms[ i ] = - glGetUniformLocation( shader->program, shader->uniform_names[i] ); - } - - shader->status |= SHADER_STATUS_COMPILED; + if( shader->compiled ) + glDeleteProgram( shader->id ); + + shader->id = program; + shader->compiled = 1; + if( shader->link ) + shader->link(); return 1; } -static void vg_shaders_free(void) +VG_STATIC void vg_free_shader( struct vg_shader *shader ) { - for( int i = 0; i < arrlen( vg_shaders_active ); i ++ ) - { - struct vg_shader *shader = vg_shaders_active[i]; - - if( shader->status & SHADER_STATUS_COMPILED ) - glDeleteProgram( shader->program ); - } - - arrfree( vg_shaders_active ); + if( shader->compiled ) + { + glDeleteProgram( shader->id ); + shader->compiled = 0; + } } -static int vg_shaders_compile(void) +VG_STATIC void vg_shaders_compile(void) { vg_info( "Compiling shaders\n" ); - for( int i = 0; i < arrlen( vg_shaders_active ); i ++ ) + for( int i=0; icompiled = 0; + shader->id = 0; /* TODO: make this an error shader */ + vg_shaders.shaders[ vg_shaders.count ++ ] = shader; +} + +#endif /* VG_SHADER_H */