1 #define STB_INCLUDE_IMPLEMENTATION
2 #define STB_INCLUDE_LINE_GLSL
3 #include "submodules/stb/stb_include.h"
11 char uniform_code_id
[128];
19 char shader_dir
[ 256 ];
20 char current_shader_name
[ 128 ];
28 static vg_shaderbuild
;
30 static void vg_shader_set_include_dir( char *dir
)
32 strcpy( vg_shaderbuild
.shader_dir
, dir
);
35 static void parse_uniform_name( char *start
, struct uniform
*uf
)
42 if( start
[i
] == '\0' )
48 vg_strncpy( start
, uf
->name
, sizeof(uf
->name
),
49 k_strncpy_always_add_null
);
55 vg_strncpy( start
, uf
->name
, sizeof(uf
->name
),
56 k_strncpy_always_add_null
);
66 vg_strncpy( start
, uf
->type
, sizeof(uf
->type
),
67 k_strncpy_always_add_null
);
75 snprintf( uf
->uniform_code_id
, 64, "_uniform_%s_%s",
76 vg_shaderbuild
.current_shader_name
,
80 static int compile_subshader( vg_str
*str
, char *name
)
83 char *full
= stb_include_file( name
, "", vg_shaderbuild
.shader_dir
, error
);
87 fprintf( stderr
, "stb_include_file error:\n%s\n", error
);
92 vg_strcatf( str
, "{\n"
93 ".orig_file = \"%s\",\n"
97 char *cur
= full
, *start
= full
;
101 if( c
== '\n' || c
== '\0' )
104 vg_strcatf( str
, "\"" );
105 vg_strcatf( str
, start
);
107 if( !strncmp(start
,"uniform",7) )
111 &vg_shaderbuild
.uniform_buffer
[
112 vg_shaderbuild
.uniform_count
++ ];
114 parse_uniform_name( start
, uf
);
119 vg_strcatf( str
, "\"" );
123 vg_strcatf( str
, "\\n\"\n" );
129 vg_strcatf( str
, "}," );
136 void vg_build_shader_impl( char *path
)
138 FILE *fp
= fopen( path
, "w" );
139 fputs( vg_shaderbuild
.code_function_body
.buffer
, fp
);
142 fputs( "void vg_auto_shader_link(void)\n{\n", fp
);
143 fputs( vg_shaderbuild
.code_link
.buffer
, fp
);
144 fputs( "}\n\n", fp
);
146 fputs( "void vg_auto_shader_register(void)\n{\n", fp
);
147 fputs( vg_shaderbuild
.code_register
.buffer
, fp
);
148 fputs( "}\n\n", fp
);
153 int vg_build_shader( char *src_vert
, /* path/to/vert.vs */
154 char *src_frag
, /* path/to/frag.fs */
155 char *src_geo
, /* unused currently */
156 char *dst_h
, /* folder where .h go */
157 char *name
/* shader name */ )
159 if( !vg_shaderbuild
.init
)
161 vg_strnull( &vg_shaderbuild
.code_link
, NULL
, -1 );
162 vg_strnull( &vg_shaderbuild
.code_register
, NULL
, -1 );
163 vg_strnull( &vg_shaderbuild
.code_function_body
, NULL
, -1 );
164 vg_shaderbuild
.init
= 1;
167 vg_str
*c_link
= &vg_shaderbuild
.code_link
,
168 *c_reg
= &vg_shaderbuild
.code_register
,
169 *c_body
= &vg_shaderbuild
.code_function_body
;
171 char path_header
[260];
173 strcpy( vg_shaderbuild
.current_shader_name
, name
);
174 strcpy( path_header
, dst_h
);
175 strcat( path_header
, "/" );
176 strcat( path_header
, name
);
177 strcat( path_header
, ".h" );
179 vg_low( "Compiling shader called '%s'\r", name
);
181 FILE *header
= fopen( path_header
, "w" );
184 fprintf(stderr
, "Could not open '%s'\n", path_header
);
188 fprintf( header
, "#pragma once\n" );
189 fprintf( header
, "#include \"vg/vg_engine.h\"\n" );
190 vg_strcatf( c_body
, "#include \"%s\"\n", path_header
);
191 fprintf( header
, "extern struct vg_shader _shader_%s;\n", name
);
192 vg_strcatf( c_body
, "struct vg_shader _shader_%s = {\n"
194 " .vs = \n", name
, name
, name
);
196 vg_shaderbuild
.uniform_count
= 0;
197 if( !compile_subshader( c_body
, src_vert
) )
203 vg_strcatf( c_body
, "\n .fs = \n" );
204 if( !compile_subshader( c_body
, src_frag
) )
210 vg_strcatf( c_body
, "\n};\n\n" );
212 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
214 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
215 fprintf( header
, "extern GLuint %s;\n", uf
->uniform_code_id
);
216 vg_strcatf( c_body
, "GLuint %s;\n", uf
->uniform_code_id
);
221 const char *glsl_type
,
227 { "float", "f32 f", "glUniform1f(%s,f);" },
228 { "bool", "int b", "glUniform1i(%s,b);" },
229 { "vec2", "v2f v", "glUniform2fv(%s,1,v);" },
230 { "vec3", "v3f v", "glUniform3fv(%s,1,v);" },
231 { "vec4", "v4f v", "glUniform4fv(%s,1,v);" },
232 { "sampler2D", "int i", "glUniform1i(%s,i);" },
233 { "samplerCube", "int i", "glUniform1i(%s,i);" },
234 { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(f32*)m);" },
235 { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(f32*)m);" },
236 { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(f32*)m);" },
237 { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(f32*)m);" },
240 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
242 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
246 for( int j
=0; j
<vg_list_size(types
); j
++ )
248 struct type_info
*inf
= &types
[j
];
250 if( !strcmp( inf
->glsl_type
, uf
->type
) )
252 fprintf( header
, "static inline void shader_%s_%s(%s)\n{\n",
253 name
, uf
->name
, inf
->args
);
254 fprintf( header
, " " );
255 fprintf( header
, inf
->gl_call_pattern
, uf
->uniform_code_id
);
256 fprintf( header
, "\n}\n" );
261 vg_strcatf( c_reg
, " vg_shader_register( &_shader_%s );\n", name
);
262 fprintf( header
, "static inline void shader_%s_use(void);\n", name
);
263 fprintf( header
, "static inline void shader_%s_use(void)\n{\n", name
);
264 fprintf( header
, " glUseProgram(_shader_%s.id);\n}\n", name
);
266 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
268 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
271 "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",