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 ];
22 static vg_shaderbuild
;
24 static void vg_shader_set_include_dir( char *dir
)
26 strcpy( vg_shaderbuild
.shader_dir
, dir
);
29 static void parse_uniform_name( char *start
, struct uniform
*uf
)
36 if( start
[i
] == '\0' )
42 vg_strncpy( start
, uf
->name
, sizeof(uf
->name
),
43 k_strncpy_always_add_null
);
49 vg_strncpy( start
, uf
->name
, sizeof(uf
->name
),
50 k_strncpy_always_add_null
);
60 vg_strncpy( start
, uf
->type
, sizeof(uf
->type
),
61 k_strncpy_always_add_null
);
69 snprintf( uf
->uniform_code_id
, 64, "_uniform_%s_%s",
70 vg_shaderbuild
.current_shader_name
,
74 static int compile_subshader( FILE *header
, char *name
)
77 char *full
= stb_include_file( name
, "", vg_shaderbuild
.shader_dir
, error
);
81 fprintf( stderr
, "stb_include_file error:\n%s\n", error
);
86 fprintf( header
, "{\n"
87 ".orig_file = \"%s\",\n"
91 char *cur
= full
, *start
= full
;
95 if( c
== '\n' || c
== '\0' )
98 fputs( "\"", header
);
99 fputs( start
, header
);
101 if( !strncmp(start
,"uniform",7) )
105 &vg_shaderbuild
.uniform_buffer
[
106 vg_shaderbuild
.uniform_count
++ ];
108 parse_uniform_name( start
, uf
);
113 fputs( "\"", header
);
117 fputs( "\\n\"\n", header
);
123 fputs( "},", header
);
130 int vg_build_shader( char *src_vert
, /* path/to/vert.vs */
131 char *src_frag
, /* path/to/frag.fs */
132 char *src_geo
, /* unused currently */
133 char *dst_h
, /* folder where .h go */
134 char *name
/* shader name */ )
138 strcpy( vg_shaderbuild
.current_shader_name
, name
);
140 strcpy( path
, dst_h
);
142 strcat( path
, name
);
143 strcat( path
, ".h" );
145 vg_low( "Compiling shader called '%s'\r", name
);
147 FILE *header
= fopen( path
, "w" );
150 fprintf(stderr
, "Could not open '%s'\n", path
);
154 fprintf( header
, "#ifndef SHADER_%s_H\n"
155 "#define SHADER_%s_H\n", name
, name
);
156 fprintf( header
, "static void shader_%s_link(void);\n", name
);
157 fprintf( header
, "static void shader_%s_register(void);\n", name
);
158 fprintf( header
, "static struct vg_shader _shader_%s = {\n"
160 " .link = shader_%s_link,\n"
161 " .vs = \n", name
, name
, name
);
163 vg_shaderbuild
.uniform_count
= 0;
164 if( !compile_subshader(header
,src_vert
) )
170 fprintf( header
, "\n .fs = \n" );
171 if( !compile_subshader(header
,src_frag
) )
177 fprintf( header
, "\n};\n\n" );
179 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
181 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
182 fprintf( header
, "static GLuint %s;\n", uf
->uniform_code_id
);
187 const char *glsl_type
,
193 { "float", "float f", "glUniform1f(%s,f);" },
194 { "bool", "int b", "glUniform1i(%s,b);" },
196 { "vec2", "v2f v", "glUniform2fv(%s,1,v);" },
197 { "vec3", "v3f v", "glUniform3fv(%s,1,v);" },
198 { "vec4", "v4f v", "glUniform4fv(%s,1,v);" },
200 { "sampler2D", "int i", "glUniform1i(%s,i);" },
201 { "samplerCube", "int i", "glUniform1i(%s,i);" },
202 { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(float*)m);" },
203 { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(float*)m);" },
204 { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(float*)m);" },
205 { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(float*)m);" },
208 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
210 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
214 for( int j
=0; j
<vg_list_size(types
); j
++ )
216 struct type_info
*inf
= &types
[j
];
218 if( !strcmp( inf
->glsl_type
, uf
->type
) )
220 fprintf( header
, "static void shader_%s_%s(%s){\n",
221 name
, uf
->name
, inf
->args
);
222 fprintf( header
, " " );
223 fprintf( header
, inf
->gl_call_pattern
, uf
->uniform_code_id
);
224 fprintf( header
, "\n}\n" );
230 "static void shader_%s_register(void){\n"
231 " vg_shader_register( &_shader_%s );\n"
236 "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n",
240 "static void shader_%s_link(void){\n",
243 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
245 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
248 "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
253 fprintf( header
, "}\n" );
254 fprintf( header
, "#endif /* SHADER_%s_H */\n", name
);