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