audio rework pt 1
[vg.git] / src / shader.c
1 #define STB_INCLUDE_IMPLEMENTATION
2 #define STB_INCLUDE_LINE_GLSL
3 #include "../dep/stb/stb_include.h"
4 #define VG_TOOLS
5 #include "vg/vg.h"
6
7 struct uniform
8 {
9 char name[30];
10 char type[20];
11
12 int array;
13 }
14 uniform_buffer[100];
15 static int uniform_count;
16
17 static int compile_subshader( FILE *header, char *name )
18 {
19 char error[256];
20 char *full = stb_include_file( name, "", ".", error );
21
22 if( !full )
23 {
24 fprintf( stderr, "stb_include_file error:\n%s\n", error );
25 return 0;
26 }
27 else
28 {
29 /* VG */
30
31 fprintf( header, "{\n"
32 ".orig_file = \"../../shaders/%s\",\n"
33 ".static_src = \n", name );
34
35 char *cur = full, *start = full;
36 while( 1 )
37 {
38 char c = *cur;
39 if( c == '\n' || c == '\0' )
40 {
41 *cur = '\0';
42 fputs( "\"", header );
43 fputs( start, header );
44
45 if( !strncmp(start,"uniform",7) )
46 {
47 start += 8;
48 struct uniform *uf = &uniform_buffer[ uniform_count ++ ];
49 for( int i=0;; i++ )
50 {
51 if( start[i] == '\0' )
52 break;
53
54 if( start[i] == ';' )
55 {
56 start[i] = '\0';
57 strncpy( uf->name, start, sizeof(uf->name) );
58 }
59
60 if( start[i] == '[' )
61 {
62 start[i] = '\0';
63 strncpy( uf->name, start, sizeof(uf->name) );
64 uf->array = 1;
65 }
66
67 if( start[i] == ' ' )
68 {
69 start[i] = '\0';
70 strncpy( uf->type, start, sizeof(uf->type) );
71 start = start+i+1;
72 i=0;
73 }
74 }
75 }
76
77 if( c == '\0' )
78 {
79 fputs( "\"", header );
80 break;
81 }
82
83 fputs( "\\n\"\n", header );
84 start = cur+1;
85 }
86 cur ++;
87 }
88
89 fputs( "},", header );
90 }
91
92 free( full );
93 return 1;
94 }
95
96 int main( int argc, char *argv[] )
97 {
98 if( argc < 2 || (argc-1)%3 != 0 )
99 {
100 fprintf( stderr, "invalid\n" );
101 return 0;
102 }
103
104 char path[260];
105 int shader_count = (argc-1)/3;
106 for( int i=0; i<shader_count; i++ )
107 {
108 char **args = &argv[1+i*3];
109 strcpy( path, args[0] );
110 strcat( path, ".h" );
111
112 printf( "Compiling shader called '%s'\n", args[0] );
113
114 FILE *header = fopen( path, "w" );
115 if( !header )
116 {
117 fprintf(stderr, "Could not open '%s'\n", path );
118 continue;
119 }
120
121 fprintf( header, "#ifndef SHADER_%s_H\n"
122 "#define SHADER_%s_H\n", args[0], args[0] );
123 fprintf( header, "static void shader_%s_link(void);\n", args[0] );
124 fprintf( header, "static void shader_%s_register(void);\n", args[0] );
125 fprintf( header, "static struct vg_shader _shader_%s = {\n"
126 " .name = \"%s\",\n"
127 " .link = shader_%s_link,\n"
128 " .vs = \n", args[0], args[0], args[0] );
129
130 uniform_count = 0;
131 if( !compile_subshader(header,args[1]) )
132 {
133 fclose( header );
134 continue;
135 }
136
137 fprintf( header, "\n .fs = \n" );
138 if( !compile_subshader(header,args[2]) )
139 {
140 fclose( header );
141 continue;
142 }
143
144 fprintf( header, "\n};\n\n" );
145
146 for( int i=0; i<uniform_count; i++ )
147 {
148 struct uniform *uf = &uniform_buffer[i];
149 fprintf( header, "static GLuint _uniform_%s_%s;\n", args[0], uf->name);
150 }
151
152 for( int i=0; i<uniform_count; i++ )
153 {
154 struct uniform *uf = &uniform_buffer[i];
155 if( uf->array ) continue;
156
157 if( !strcmp(uf->type,"vec2") )
158 {
159 fprintf( header, "static void shader_%s_%s(v2f v){\n"
160 " glUniform2fv( _uniform_%s_%s, 1, v );\n"
161 "}\n", args[0], uf->name, args[0], uf->name );
162 }
163 if( !strcmp(uf->type,"vec3") )
164 {
165 fprintf( header, "static void shader_%s_%s(v3f v){\n"
166 " glUniform3fv( _uniform_%s_%s, 1, v );\n"
167 "}\n", args[0], uf->name, args[0], uf->name );
168 }
169 if( !strcmp(uf->type,"vec4") )
170 {
171 fprintf( header, "static void shader_%s_%s(v4f v){\n"
172 " glUniform4fv( _uniform_%s_%s, 1, v );\n"
173 "}\n", args[0], uf->name, args[0], uf->name );
174 }
175 if( !strcmp(uf->type,"sampler2D") )
176 {
177 fprintf( header, "static void shader_%s_%s(int i){\n"
178 " glUniform1i( _uniform_%s_%s, i );\n"
179 "}\n", args[0], uf->name, args[0], uf->name );
180 }
181 if( !strcmp(uf->type,"float") )
182 {
183 fprintf( header, "static void shader_%s_%s(float f){\n"
184 " glUniform1f( _uniform_%s_%s, f );\n"
185 "}\n", args[0], uf->name, args[0], uf->name );
186 }
187 if( !strcmp(uf->type,"mat4x3") )
188 {
189 fprintf( header,
190 "static void shader_%s_%s(m4x3f m){\n"
191 " glUniformMatrix4x3fv"
192 "( _uniform_%s_%s, 1, GL_FALSE, (float *)m );\n"
193 "}\n", args[0], uf->name, args[0], uf->name );
194 }
195 if( !strcmp(uf->type,"mat3") )
196 {
197 fprintf( header,
198 "static void shader_%s_%s(m3x3f m){\n"
199 " glUniformMatrix3fv"
200 "( _uniform_%s_%s, 1, GL_FALSE, (float *)m );\n"
201 "}\n", args[0], uf->name, args[0], uf->name );
202 }
203 if( !strcmp(uf->type,"mat4") )
204 {
205 fprintf( header,
206 "static void shader_%s_%s(m4x4f m){\n"
207 " glUniformMatrix4fv"
208 "( _uniform_%s_%s, 1, GL_FALSE, (float *)m );\n"
209 "}\n", args[0], uf->name, args[0], uf->name );
210 }
211 }
212
213 fprintf( header,
214 "static void shader_%s_register(void){\n"
215 " vg_shader_register( &_shader_%s );\n"
216 "}\n",
217 args[0],args[0] );
218
219 fprintf( header,
220 "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n",
221 args[0], args[0] );
222
223 fprintf( header,
224 "static void shader_%s_link(void){\n",
225 args[0] );
226
227 for( int i=0; i<uniform_count; i++ )
228 {
229 struct uniform *uf = &uniform_buffer[i];
230 fprintf( header,
231 " _uniform_%s_%s = "
232 "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
233 args[0], uf->name,
234 args[0], uf->name );
235 }
236
237 fprintf( header, "}\n" );
238 fprintf( header, "#endif /* SHADER_%s_H */\n", args[0] );
239 fclose( header );
240 }
241 }