7 #define STB_INCLUDE_IMPLEMENTATION
8 #define STB_INCLUDE_LINE_GLSL
9 #include "submodules/stb/stb_include.h"
17 char uniform_code_id
[128];
25 char shader_dir
[ 256 ];
26 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( FILE *header
, 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 fprintf( header
, "{\n"
93 ".orig_file = \"%s\",\n"
97 char *cur
= full
, *start
= full
;
101 if( c
== '\n' || c
== '\0' )
104 fputs( "\"", header
);
105 fputs( start
, header
);
107 if( !strncmp(start
,"uniform",7) )
111 &vg_shaderbuild
.uniform_buffer
[
112 vg_shaderbuild
.uniform_count
++ ];
114 parse_uniform_name( start
, uf
);
119 fputs( "\"", header
);
123 fputs( "\\n\"\n", header
);
129 fputs( "},", header
);
136 int vg_build_shader( char *src_vert
, /* path/to/vert.vs */
137 char *src_frag
, /* path/to/frag.fs */
138 char *src_geo
, /* unused currently */
139 char *dst_h
, /* folder where .h go */
140 char *name
/* shader name */ )
144 strcpy( vg_shaderbuild
.current_shader_name
, name
);
146 strcpy( path
, dst_h
);
148 strcat( path
, name
);
149 strcat( path
, ".h" );
151 vg_low( "Compiling shader called '%s'\r", name
);
153 FILE *header
= fopen( path
, "w" );
156 fprintf(stderr
, "Could not open '%s'\n", path
);
160 fprintf( header
, "#ifndef SHADER_%s_H\n"
161 "#define SHADER_%s_H\n", name
, name
);
162 fprintf( header
, "static void shader_%s_link(void);\n", name
);
163 fprintf( header
, "static void shader_%s_register(void);\n", name
);
164 fprintf( header
, "static struct vg_shader _shader_%s = {\n"
166 " .link = shader_%s_link,\n"
167 " .vs = \n", name
, name
, name
);
169 vg_shaderbuild
.uniform_count
= 0;
170 if( !compile_subshader(header
,src_vert
) )
176 fprintf( header
, "\n .fs = \n" );
177 if( !compile_subshader(header
,src_frag
) )
183 fprintf( header
, "\n};\n\n" );
185 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
187 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
188 fprintf( header
, "static GLuint %s;\n", uf
->uniform_code_id
);
193 const char *glsl_type
,
199 { "float", "float f", "glUniform1f(%s,f);" },
200 { "bool", "int b", "glUniform1i(%s,b);" },
202 { "vec2", "v2f v", "glUniform2fv(%s,1,v);" },
203 { "vec3", "v3f v", "glUniform3fv(%s,1,v);" },
204 { "vec4", "v4f v", "glUniform4fv(%s,1,v);" },
206 { "sampler2D", "int i", "glUniform1i(%s,i);" },
207 { "samplerCube", "int i", "glUniform1i(%s,i);" },
208 { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(float*)m);" },
209 { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(float*)m);" },
210 { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(float*)m);" },
211 { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(float*)m);" },
214 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
216 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
220 for( int j
=0; j
<vg_list_size(types
); j
++ )
222 struct type_info
*inf
= &types
[j
];
224 if( !strcmp( inf
->glsl_type
, uf
->type
) )
226 fprintf( header
, "static void shader_%s_%s(%s){\n",
227 name
, uf
->name
, inf
->args
);
228 fprintf( header
, " " );
229 fprintf( header
, inf
->gl_call_pattern
, uf
->uniform_code_id
);
230 fprintf( header
, "\n}\n" );
236 "static void shader_%s_register(void){\n"
237 " vg_shader_register( &_shader_%s );\n"
242 "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n",
246 "static void shader_%s_link(void){\n",
249 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
251 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
254 "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
259 fprintf( header
, "}\n" );
260 fprintf( header
, "#endif /* SHADER_%s_H */\n", name
);