1c81c41822dd0532a4273c14bebdae3d97a3ea54
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 strncpy( uf
->name
, start
, sizeof(uf
->name
) );
54 strncpy( uf
->name
, start
, sizeof(uf
->name
) );
64 strncpy( uf
->type
, start
, sizeof(uf
->type
) );
72 snprintf( uf
->uniform_code_id
, 64, "_uniform_%s_%s",
73 vg_shaderbuild
.current_shader_name
,
77 static int compile_subshader( FILE *header
, char *name
)
80 char *full
= stb_include_file( name
, "", vg_shaderbuild
.shader_dir
, error
);
84 fprintf( stderr
, "stb_include_file error:\n%s\n", error
);
89 fprintf( header
, "{\n"
90 ".orig_file = \"%s\",\n"
94 char *cur
= full
, *start
= full
;
98 if( c
== '\n' || c
== '\0' )
101 fputs( "\"", header
);
102 fputs( start
, header
);
104 if( !strncmp(start
,"uniform",7) )
108 &vg_shaderbuild
.uniform_buffer
[
109 vg_shaderbuild
.uniform_count
++ ];
111 parse_uniform_name( start
, uf
);
116 fputs( "\"", header
);
120 fputs( "\\n\"\n", header
);
126 fputs( "},", header
);
133 int vg_build_shader( char *src_vert
, /* path/to/vert.vs */
134 char *src_frag
, /* path/to/frag.fs */
135 char *src_geo
, /* unused currently */
136 char *dst_h
, /* folder where .h go */
137 char *name
/* shader name */ )
141 strcpy( vg_shaderbuild
.current_shader_name
, name
);
143 strcpy( path
, dst_h
);
145 strcat( path
, name
);
146 strcat( path
, ".h" );
148 printf( "Compiling shader called '%s'\n", name
);
150 FILE *header
= fopen( path
, "w" );
153 fprintf(stderr
, "Could not open '%s'\n", path
);
157 fprintf( header
, "#ifndef SHADER_%s_H\n"
158 "#define SHADER_%s_H\n", name
, name
);
159 fprintf( header
, "static void shader_%s_link(void);\n", name
);
160 fprintf( header
, "static void shader_%s_register(void);\n", name
);
161 fprintf( header
, "static struct vg_shader _shader_%s = {\n"
163 " .link = shader_%s_link,\n"
164 " .vs = \n", name
, name
, name
);
166 vg_shaderbuild
.uniform_count
= 0;
167 if( !compile_subshader(header
,src_vert
) )
173 fprintf( header
, "\n .fs = \n" );
174 if( !compile_subshader(header
,src_frag
) )
180 fprintf( header
, "\n};\n\n" );
182 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
184 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
185 fprintf( header
, "static GLuint %s;\n", uf
->uniform_code_id
);
190 const char *glsl_type
,
196 { "float", "float f", "glUniform1f(%s,f);" },
198 { "vec2", "v2f v", "glUniform2fv(%s,1,v);" },
199 { "vec3", "v3f v", "glUniform3fv(%s,1,v);" },
200 { "vec4", "v4f v", "glUniform4fv(%s,1,v);" },
202 { "sampler2D", "int i", "glUniform1i(%s,i);" },
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
);