From: hgn Date: Fri, 23 Feb 2024 03:33:37 +0000 (+0000) Subject: revision 2 X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=commitdiff_plain;h=7108996fc9e1baebc3b3f09e950ce08487f9d5a6 revision 2 --- diff --git a/vg_build.h b/vg_build.h index 9e5d9a7..b582d0f 100644 --- a/vg_build.h +++ b/vg_build.h @@ -433,7 +433,7 @@ struct vg_engine_config { bool use_3d, legacy_support_vg_msg1, log_source_info, steam_api, custom_game_settings, - release_mode; + release_mode, custom_shaders; i32 fixed_update_hz; } vg_engine_default_config = { @@ -443,7 +443,8 @@ vg_engine_default_config = { .log_source_info = 1, .steam_api = 0, .custom_game_settings = 0, - .release_mode = 0 + .release_mode = 0, + .custom_shaders = 0 }; void vg_add_engine( struct vg_project *proj, struct vg_engine_config *config ) @@ -463,6 +464,8 @@ void vg_add_engine( struct vg_project *proj, struct vg_engine_config *config ) vg_strcat( &config_string, "-DVG_GAME_SETTINGS \\\n" ); if( config->custom_game_settings ) vg_strcat( &config_string, "-DVG_RELEASE \\\n" ); + if( config->custom_shaders ) + vg_strcat( &config_string, "-DVG_CUSTOM_SHADERS \\\n" ); vg_strcat( &config_string, "\\\n" ); diff --git a/vg_build_utils_shader.h b/vg_build_utils_shader.h index 5747cf9..cb4cc4b 100644 --- a/vg_build_utils_shader.h +++ b/vg_build_utils_shader.h @@ -18,6 +18,12 @@ struct uniform_uid; char shader_dir[ 256 ]; char current_shader_name[ 128 ]; + + vg_str code_register, + code_link, + code_function_body; + + bool init; } static vg_shaderbuild; @@ -71,7 +77,7 @@ static void parse_uniform_name( char *start, struct uniform *uf ) uf->name ); } -static int compile_subshader( FILE *header, char *name ) +static int compile_subshader( vg_str *str, char *name ) { char error[256]; char *full = stb_include_file( name, "", vg_shaderbuild.shader_dir, error ); @@ -83,7 +89,7 @@ static int compile_subshader( FILE *header, char *name ) } else { - fprintf( header, "{\n" + vg_strcatf( str, "{\n" ".orig_file = \"%s\",\n" ".static_src = \n", name ); @@ -95,8 +101,8 @@ static int compile_subshader( FILE *header, char *name ) if( c == '\n' || c == '\0' ) { *cur = '\0'; - fputs( "\"", header ); - fputs( start, header ); + vg_strcatf( str, "\"" ); + vg_strcatf( str, start ); if( !strncmp(start,"uniform",7) ) { @@ -110,76 +116,104 @@ static int compile_subshader( FILE *header, char *name ) if( c == '\0' ) { - fputs( "\"", header ); + vg_strcatf( str, "\"" ); break; } - fputs( "\\n\"\n", header ); + vg_strcatf( str, "\\n\"\n" ); start = cur+1; } cur ++; } - fputs( "},", header ); + vg_strcatf( str, "}," ); } free( full ); return 1; } +void vg_build_shader_impl( char *path ) +{ + FILE *fp = fopen( path, "w" ); + fputs( vg_shaderbuild.code_function_body.buffer, fp ); + fputs( "\n\n", fp ); + + fputs( "void vg_auto_shader_link(void)\n{\n", fp ); + fputs( vg_shaderbuild.code_link.buffer, fp ); + fputs( "}\n\n", fp ); + + fputs( "void vg_auto_shader_register(void)\n{\n", fp ); + fputs( vg_shaderbuild.code_register.buffer, fp ); + fputs( "}\n\n", fp ); + + fclose( fp ); +} + int vg_build_shader( char *src_vert, /* path/to/vert.vs */ char *src_frag, /* path/to/frag.fs */ char *src_geo, /* unused currently */ char *dst_h, /* folder where .h go */ char *name /* shader name */ ) { - char path[260]; + if( !vg_shaderbuild.init ) + { + vg_strnull( &vg_shaderbuild.code_link, NULL, -1 ); + vg_strnull( &vg_shaderbuild.code_register, NULL, -1 ); + vg_strnull( &vg_shaderbuild.code_function_body, NULL, -1 ); + vg_shaderbuild.init = 1; + } + + vg_str *c_link = &vg_shaderbuild.code_link, + *c_reg = &vg_shaderbuild.code_register, + *c_body = &vg_shaderbuild.code_function_body; + + char path_header[260]; strcpy( vg_shaderbuild.current_shader_name, name ); - - strcpy( path, dst_h ); - strcat( path, "/" ); - strcat( path, name ); - strcat( path, ".h" ); + strcpy( path_header, dst_h ); + strcat( path_header, "/" ); + strcat( path_header, name ); + strcat( path_header, ".h" ); vg_low( "Compiling shader called '%s'\r", name ); - FILE *header = fopen( path, "w" ); + FILE *header = fopen( path_header, "w" ); if( !header ) { - fprintf(stderr, "Could not open '%s'\n", path ); + fprintf(stderr, "Could not open '%s'\n", path_header ); return 0; } - fprintf( header, "#ifndef SHADER_%s_H\n" - "#define SHADER_%s_H\n", name, name ); - fprintf( header, "static void shader_%s_link(void);\n", name ); - fprintf( header, "static void shader_%s_register(void);\n", name ); - fprintf( header, "static struct vg_shader _shader_%s = {\n" - " .name = \"%s\",\n" - " .link = shader_%s_link,\n" - " .vs = \n", name, name, name ); + fprintf( header, "#pragma once\n" ); + fprintf( header, "#include \"vg/vg_engine.h\"\n" ); + vg_strcatf( c_body, "#include \"%s\"\n", path_header ); + fprintf( header, "extern struct vg_shader _shader_%s;\n", name ); + vg_strcatf( c_body, "struct vg_shader _shader_%s = {\n" + " .name = \"%s\",\n" + " .vs = \n", name, name, name ); vg_shaderbuild.uniform_count = 0; - if( !compile_subshader(header,src_vert) ) + if( !compile_subshader( c_body, src_vert ) ) { fclose( header ); return 0; } - fprintf( header, "\n .fs = \n" ); - if( !compile_subshader(header,src_frag) ) + vg_strcatf( c_body, "\n .fs = \n" ); + if( !compile_subshader( c_body, src_frag ) ) { fclose( header ); return 0; } - fprintf( header, "\n};\n\n" ); + vg_strcatf( c_body, "\n};\n\n" ); for( int i=0; iuniform_code_id ); + fprintf( header, "extern GLuint %s;\n", uf->uniform_code_id ); + vg_strcatf( c_body, "GLuint %s;\n", uf->uniform_code_id ); } struct type_info @@ -190,19 +224,17 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs */ } types[] = { - { "float", "float f", "glUniform1f(%s,f);" }, + { "float", "f32 f", "glUniform1f(%s,f);" }, { "bool", "int b", "glUniform1i(%s,b);" }, - { "vec2", "v2f v", "glUniform2fv(%s,1,v);" }, { "vec3", "v3f v", "glUniform3fv(%s,1,v);" }, { "vec4", "v4f v", "glUniform4fv(%s,1,v);" }, - { "sampler2D", "int i", "glUniform1i(%s,i);" }, { "samplerCube", "int i", "glUniform1i(%s,i);" }, - { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(float*)m);" }, - { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(float*)m);" }, - { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(float*)m);" }, - { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(float*)m);" }, + { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(f32*)m);" }, + { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(f32*)m);" }, + { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(f32*)m);" }, + { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(f32*)m);" }, }; for( int i=0; iglsl_type, uf->type ) ) { - fprintf( header, "static void shader_%s_%s(%s){\n", - name, uf->name, inf->args ); + fprintf( header, "static inline void shader_%s_%s(%s)\n{\n", + name, uf->name, inf->args ); fprintf( header, " " ); fprintf( header, inf->gl_call_pattern, uf->uniform_code_id ); fprintf( header, "\n}\n" ); @@ -226,33 +258,21 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs */ } } - fprintf( header, - "static void shader_%s_register(void){\n" - " vg_shader_register( &_shader_%s );\n" - "}\n", - name,name ); - - fprintf( header, - "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n", - name, name ); - - fprintf( header, - "static void shader_%s_link(void){\n", - name ); + vg_strcatf( c_reg, " vg_shader_register( &_shader_%s );\n", name ); + fprintf( header, "static inline void shader_%s_use(void);\n", name ); + fprintf( header, "static inline void shader_%s_use(void)\n{\n", name ); + fprintf( header, " glUseProgram(_shader_%s.id);\n}\n", name ); for( int i=0; iname, name, uf->name ); } - fprintf( header, "}\n" ); - fprintf( header, "#endif /* SHADER_%s_H */\n", name ); fclose( header ); - return 1; } diff --git a/vg_bvh.h b/vg_bvh.h index 37b100a..1adb3d8 100644 --- a/vg_bvh.h +++ b/vg_bvh.h @@ -1,4 +1,5 @@ #pragma once +#include "vg_platform.h" #include "vg_mem.h" #include "vg_m.h" #include "vg_lines.h" diff --git a/vg_engine.c b/vg_engine.c index 0d8c015..268594f 100644 --- a/vg_engine.c +++ b/vg_engine.c @@ -105,6 +105,10 @@ void async_internal_complete( void *payload, u32 size ) SDL_AtomicUnlock( &vg.sl_status ); } +#ifdef VG_CUSTOM_SHADERS +void vg_auto_shader_register(void); /* created from codegen */ +#endif + static void _vg_load_full( void *data ) { vg_preload(); @@ -121,6 +125,9 @@ static void _vg_load_full( void *data ) vg_loader_step( vg_profiler_init, NULL ); /* client */ +#ifdef VG_CUSTOM_SHADERS + vg_auto_shader_register(); +#endif vg_load(); vg_async_call( async_internal_complete, NULL, 0 ); @@ -1190,3 +1197,7 @@ int AmdPowerXpressRequestHighPerformance = 1; #include "vg_rigidbody.c" #include "vg_rigidbody_view.c" #include "vg_shader.c" + +#ifdef VG_CUSTOM_SHADERS + #include "shaders/impl.c" +#endif diff --git a/vg_imgui.c b/vg_imgui.c index 2510404..21936cc 100644 --- a/vg_imgui.c +++ b/vg_imgui.c @@ -89,7 +89,6 @@ struct vg_imgui vg_ui = { static struct vg_shader _shader_ui ={ .name = "[vg] ui - transparent", - .link = NULL, .vs = { .orig_file = NULL, .static_src = @@ -159,7 +158,6 @@ static struct vg_shader _shader_ui ={ static struct vg_shader _shader_ui_image = { .name = "[vg] ui_image", - .link = NULL, .vs = { .orig_file = NULL, @@ -204,7 +202,6 @@ static struct vg_shader _shader_ui_image = { static struct vg_shader _shader_ui_hsv = { .name = "[vg] ui_hsv", - .link = NULL, .vs = { .orig_file = NULL, .static_src = diff --git a/vg_lines.c b/vg_lines.c index 27694fc..6315482 100644 --- a/vg_lines.c +++ b/vg_lines.c @@ -14,7 +14,6 @@ struct vg_lines vg_lines; static struct vg_shader _shader_lines = { .name = "[vg] lines", - .link = NULL, .vs = { .orig_file = NULL, .static_src = diff --git a/vg_lines.h b/vg_lines.h index dbb37c5..3730b6b 100644 --- a/vg_lines.h +++ b/vg_lines.h @@ -2,6 +2,7 @@ #pragma once #include "vg_platform.h" +#include "vg_engine.h" typedef v3f line_co; diff --git a/vg_loader.c b/vg_loader.c index 86c7417..55ab081 100644 --- a/vg_loader.c +++ b/vg_loader.c @@ -1,12 +1,13 @@ +#include "vg_engine.h" #include "vg_loader.h" #include "vg_shader.h" +#include "vg_async.h" struct vg_loader vg_loader; static struct vg_shader _shader_loader = { .name = "[vg] loader", - .link = NULL, /* This is the new foreground shader */ .vs = diff --git a/vg_rigidbody_view.c b/vg_rigidbody_view.c index b14df65..962148f 100644 --- a/vg_rigidbody_view.c +++ b/vg_rigidbody_view.c @@ -8,7 +8,6 @@ static struct vg_shader _shader_rigidbody = { .name = "[vg] rigidbody", - .link = NULL, .vs = { .orig_file = NULL, .static_src = diff --git a/vg_shader.c b/vg_shader.c index 4b41c2e..c12495c 100644 --- a/vg_shader.c +++ b/vg_shader.c @@ -138,8 +138,6 @@ int vg_shader_compile( struct vg_shader *shader ) shader->id = program; shader->compiled = 1; - if( shader->link ) - shader->link(); return 1; } @@ -152,6 +150,10 @@ static void vg_free_shader( struct vg_shader *shader ) } } +#ifdef VG_CUSTOM_SHADERS +void vg_auto_shader_link(void); +#endif + void vg_shaders_compile(void) { vg_info( "Compiling shaders\n" ); @@ -162,6 +164,10 @@ void vg_shaders_compile(void) if( !vg_shader_compile( shader ) ) vg_fatal_error( "Failed to compile shader" ); } + +#ifdef VG_CUSTOM_SHADERS + vg_auto_shader_link(); +#endif } int vg_shaders_live_recompile(int argc, const char *argv[]) diff --git a/vg_shader.h b/vg_shader.h index 059ed8e..5e2ad35 100644 --- a/vg_shader.h +++ b/vg_shader.h @@ -15,8 +15,6 @@ struct vg_shaders *static_src; } vs, fs; - - void (*link)(void); int compiled; } * shaders[48]; diff --git a/vg_steam_networking.h b/vg_steam_networking.h index da933f7..5abb7b6 100644 --- a/vg_steam_networking.h +++ b/vg_steam_networking.h @@ -181,7 +181,7 @@ typedef enum ESteamNetworkingAvailability ESteamNetworkingAvailability; /* Handle used to identify a connection to a remote host. */ typedef u32 HSteamNetConnection; -HSteamNetConnection const k_HSteamNetConnection_Invalid = 0; +static HSteamNetConnection const k_HSteamNetConnection_Invalid = 0; /* * Handle used to identify a "listen socket". Unlike traditional @@ -189,7 +189,7 @@ HSteamNetConnection const k_HSteamNetConnection_Invalid = 0; * different abstractions. */ typedef u32 HSteamListenSocket; -HSteamListenSocket const k_HSteamListenSocket_Invalid = 0; +static HSteamListenSocket const k_HSteamListenSocket_Invalid = 0; typedef u32 SteamNetworkingPOPID; typedef i64 SteamNetworkingMicroseconds; @@ -391,7 +391,7 @@ typedef struct SteamNetConnectionInfo_t SteamNetConnectionInfo_t; * connections at once efficiently. */ typedef u32 HSteamNetPollGroup; -HSteamNetPollGroup const k_HSteamNetPollGroup_Invalid = 0; +static HSteamNetPollGroup const k_HSteamNetPollGroup_Invalid = 0; ISteamNetworkingSockets *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012(void); @@ -424,7 +424,7 @@ ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_SteamAPI() * Migration note: This is not exactly the same as k_EP2PSendUnreliable! You * probably want k_ESteamNetworkingSendType_UnreliableNoNagle */ -const int k_nSteamNetworkingSend_Unreliable = 0; +static const int k_nSteamNetworkingSend_Unreliable = 0; /* * Disable Nagle's algorithm. @@ -445,7 +445,7 @@ const int k_nSteamNetworkingSend_Unreliable = 0; * server simulation tick to a particular client), and you use this flag to * flush all messages. */ -const int k_nSteamNetworkingSend_NoNagle = 1; +static const int k_nSteamNetworkingSend_NoNagle = 1; /* * Send a message unreliably, bypassing Nagle's algorithm for this message and @@ -455,7 +455,7 @@ const int k_nSteamNetworkingSend_NoNagle = 1; * ISteamNetworkingMessages::FlushMessagesToUser. (But using this flag is more * efficient since you only make one API call.) */ -const int k_nSteamNetworkingSend_UnreliableNoNagle = +static const int k_nSteamNetworkingSend_UnreliableNoNagle = k_nSteamNetworkingSend_Unreliable | k_nSteamNetworkingSend_NoNagle; /* @@ -464,7 +464,7 @@ const int k_nSteamNetworkingSend_UnreliableNoNagle = * This is only applicable for unreliable messages. Using this flag on reliable * messages is invalid. */ -const int k_nSteamNetworkingSend_NoDelay = 4; +static const int k_nSteamNetworkingSend_NoDelay = 4; /* * Send an unreliable message, but if it cannot be sent relatively quickly, just @@ -482,7 +482,7 @@ const int k_nSteamNetworkingSend_NoDelay = 4; * * If a message is dropped for these reasons, k_EResultIgnored will be returned. */ -const int k_nSteamNetworkingSend_UnreliableNoDelay = +static const int k_nSteamNetworkingSend_UnreliableNoDelay = k_nSteamNetworkingSend_Unreliable | k_nSteamNetworkingSend_NoDelay | k_nSteamNetworkingSend_NoNagle; @@ -501,14 +501,14 @@ const int k_nSteamNetworkingSend_UnreliableNoDelay = * Migration note: This is NOT the same as k_EP2PSendReliable, it's more like * k_EP2PSendReliableWithBuffering */ -const int k_nSteamNetworkingSend_Reliable = 8; +static const int k_nSteamNetworkingSend_Reliable = 8; /* * Send a message reliably, but bypass Nagle's algorithm. * * Migration note: This is equivalent to k_EP2PSendReliable */ -const int k_nSteamNetworkingSend_ReliableNoNagle = +static const int k_nSteamNetworkingSend_ReliableNoNagle = k_nSteamNetworkingSend_Reliable | k_nSteamNetworkingSend_NoNagle; diff --git a/vg_steam_remote_storage.h b/vg_steam_remote_storage.h index 24aaf3b..c7980e2 100644 --- a/vg_steam_remote_storage.h +++ b/vg_steam_remote_storage.h @@ -1,7 +1,7 @@ #pragma once #include "vg_steam.h" -const u32 k_unMaxCloudFileChunkSize = 100 * 1024 * 1024; +static const u32 k_unMaxCloudFileChunkSize = 100 * 1024 * 1024; #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) @@ -22,14 +22,14 @@ typedef void ISteamRemoteStorage; typedef u64 UGCHandle_t; typedef u64 PublishedFileUpdateHandle_t; typedef u64 PublishedFileId_t; -const PublishedFileId_t k_PublishedFileIdInvalid = 0; -const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull; -const PublishedFileUpdateHandle_t +static const PublishedFileId_t k_PublishedFileIdInvalid = 0; +static const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull; +static const PublishedFileUpdateHandle_t k_PublishedFileUpdateHandleInvalid = 0xffffffffffffffffull; /* Handle for writing to Steam Cloud */ typedef u64 UGCFileWriteStreamHandle_t; -const UGCFileWriteStreamHandle_t +static const UGCFileWriteStreamHandle_t k_UGCFileStreamHandleInvalid = 0xffffffffffffffffull; enum{ k_cchPublishedDocumentTitleMax = 128 + 1 }; diff --git a/vg_steam_ugc.h b/vg_steam_ugc.h index 48594b2..d8c2776 100644 --- a/vg_steam_ugc.h +++ b/vg_steam_ugc.h @@ -13,8 +13,8 @@ typedef void ISteamUGC; typedef u64 UGCQueryHandle_t; typedef u64 UGCUpdateHandle_t; -const UGCQueryHandle_t k_UGCQueryHandleInvalid = 0xffffffffffffffffull; -const UGCUpdateHandle_t k_UGCUpdateHandleInvalid = 0xffffffffffffffffull; +static const UGCQueryHandle_t k_UGCQueryHandleInvalid = 0xffffffffffffffffull; +static const UGCUpdateHandle_t k_UGCUpdateHandleInvalid = 0xffffffffffffffffull; /* Matching UGC types for queries */ typedef enum EUGCMatchingUGCType EUGCMatchingUGCType; @@ -196,8 +196,8 @@ enum EItemPreviewType{ k_EItemPreviewType_ReservedMax = 255, }; -const u32 kNumUGCResultsPerPage = 50; -const u32 k_cchDeveloperMetadataMax = 5000; +static const u32 kNumUGCResultsPerPage = 50; +static const u32 k_cchDeveloperMetadataMax = 5000; /* Details for a single published file/UGC */ typedef struct SteamUGCDetails_t SteamUGCDetails_t; diff --git a/vg_string.c b/vg_string.c index 1a38479..1261f5b 100644 --- a/vg_string.c +++ b/vg_string.c @@ -1,6 +1,8 @@ #include "vg_string.h" #include "vg_platform.h" #include +#include +#include i32 vg_str_storage( vg_str *str ) { @@ -185,6 +187,21 @@ u32 vg_strncpy( const char *src, char *dst, u32 len, return 0; } +static void _vg_strcatf_va( vg_str *str, const char *fmt, va_list args ) +{ + char buffer[4096]; + vsnprintf( buffer, vg_list_size(buffer), fmt, args ); + vg_strcat( str, buffer ); +} + +void vg_strcatf( vg_str *str, const char *fmt, ... ) +{ + va_list args; + va_start( args, fmt ); + _vg_strcatf_va( str, fmt, args ); + va_end( args ); +} + u32 vg_strdjb2( const char *str ) { u32 hash = 5381, c; diff --git a/vg_string.h b/vg_string.h index 62d5abc..01caf7d 100644 --- a/vg_string.h +++ b/vg_string.h @@ -34,6 +34,7 @@ void vg_strfree( vg_str *str ); * Append null terminated string to vg_str */ void vg_strcat( vg_str *str, const char *append ); +void vg_strcatf( vg_str *str, const char *fmt, ... ); /* * Append character to vg_str