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;
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 );
}
else
{
- fprintf( header, "{\n"
+ vg_strcatf( str, "{\n"
".orig_file = \"%s\",\n"
".static_src = \n",
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) )
{
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; i<vg_shaderbuild.uniform_count; i++ )
{
struct uniform *uf = &vg_shaderbuild.uniform_buffer[i];
- fprintf( header, "static GLuint %s;\n", uf->uniform_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
}
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; i<vg_shaderbuild.uniform_count; i++ )
if( !strcmp( inf->glsl_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" );
}
}
- 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; i<vg_shaderbuild.uniform_count; i++ )
{
struct uniform *uf = &vg_shaderbuild.uniform_buffer[i];
- fprintf( header,
+ vg_strcatf( c_link,
" _uniform_%s_%s = "
"glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
name, uf->name,
name, uf->name );
}
- fprintf( header, "}\n" );
- fprintf( header, "#endif /* SHADER_%s_H */\n", name );
fclose( header );
-
return 1;
}
/* 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
* different abstractions.
*/
typedef u32 HSteamListenSocket;
-HSteamListenSocket const k_HSteamListenSocket_Invalid = 0;
+static HSteamListenSocket const k_HSteamListenSocket_Invalid = 0;
typedef u32 SteamNetworkingPOPID;
typedef i64 SteamNetworkingMicroseconds;
* 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);
* 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.
* 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
* 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;
/*
* 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
*
* 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;
* 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;