77ce897e4f32297706aa692b2b9ff670b10742c5
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
)
40 if( start
[i
] == '\0' )
46 strncpy( uf
->name
, start
, sizeof(uf
->name
) );
52 strncpy( uf
->name
, start
, sizeof(uf
->name
) );
59 strncpy( uf
->type
, start
, sizeof(uf
->type
) );
65 snprintf( uf
->uniform_code_id
, 64, "_uniform_%s_%s",
66 vg_shaderbuild
.current_shader_name
,
70 static int compile_subshader( FILE *header
, char *name
)
73 char *full
= stb_include_file( name
, "", vg_shaderbuild
.shader_dir
, error
);
77 fprintf( stderr
, "stb_include_file error:\n%s\n", error
);
82 fprintf( header
, "{\n"
85 char *cur
= full
, *start
= full
;
89 if( c
== '\n' || c
== '\0' )
92 fputs( "\"", header
);
93 fputs( start
, header
);
95 if( !strncmp(start
,"uniform",7) )
99 &vg_shaderbuild
.uniform_buffer
[
100 vg_shaderbuild
.uniform_count
++ ];
102 parse_uniform_name( start
, uf
);
107 fputs( "\"", header
);
111 fputs( "\\n\"\n", header
);
117 fputs( "},", header
);
124 int vg_build_shader( char *src_vert
, /* path/to/vert.vs */
125 char *src_frag
, /* path/to/frag.fs */
126 char *src_geo
, /* unused currently */
127 char *dst_h
, /* folder where .h go */
128 char *name
/* shader name */ )
132 strcpy( vg_shaderbuild
.current_shader_name
, name
);
134 strcpy( path
, dst_h
);
136 strcat( path
, name
);
137 strcat( path
, ".h" );
139 printf( "Compiling shader called '%s'\n", name
);
141 FILE *header
= fopen( path
, "w" );
144 fprintf(stderr
, "Could not open '%s'\n", path
);
148 fprintf( header
, "#ifndef SHADER_%s_H\n"
149 "#define SHADER_%s_H\n", name
, name
);
150 fprintf( header
, "static void shader_%s_link(void);\n", name
);
151 fprintf( header
, "static void shader_%s_register(void);\n", name
);
152 fprintf( header
, "static struct vg_shader _shader_%s = {\n"
154 " .link = shader_%s_link,\n"
155 " .vs = \n", name
, name
, name
);
157 vg_shaderbuild
.uniform_count
= 0;
158 if( !compile_subshader(header
,src_vert
) )
164 fprintf( header
, "\n .fs = \n" );
165 if( !compile_subshader(header
,src_frag
) )
171 fprintf( header
, "\n};\n\n" );
173 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
175 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
176 fprintf( header
, "static GLuint %s;\n", uf
->uniform_code_id
);
181 const char *glsl_type
,
187 { "float", "float f", "glUniform1f(%s,f);" },
189 { "vec2", "v2f v", "glUniform2fv(%s,1,v);" },
190 { "vec3", "v3f v", "glUniform3fv(%s,1,v);" },
191 { "vec4", "v4f v", "glUniform4fv(%s,1,v);" },
193 { "sampler2D", "int i", "glUniform1i(%s,i);" },
194 { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(float*)m);" },
195 { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(float*)m);" },
196 { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(float*)m);" },
199 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
201 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
202 if( uf
->array
) continue;
204 for( int j
=0; j
<vg_list_size(types
); j
++ )
206 struct type_info
*inf
= &types
[j
];
208 if( !strcmp( inf
->glsl_type
, uf
->type
) )
210 fprintf( header
, "static void shader_%s_%s(%s){\n",
211 name
, uf
->name
, inf
->args
);
212 fprintf( header
, " " );
213 fprintf( header
, inf
->gl_call_pattern
, uf
->uniform_code_id
);
214 fprintf( header
, "\n}\n" );
220 "static void shader_%s_register(void){\n"
221 " vg_shader_register( &_shader_%s );\n"
226 "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n",
230 "static void shader_%s_link(void){\n",
233 for( int i
=0; i
<vg_shaderbuild
.uniform_count
; i
++ )
235 struct uniform
*uf
= &vg_shaderbuild
.uniform_buffer
[i
];
238 "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
243 fprintf( header
, "}\n" );
244 fprintf( header
, "#endif /* SHADER_%s_H */\n", name
);