naev 0.12.5
shaders_c_gen.py
1#!/usr/bin/env python3
2
3num_shaders = 0
4
5class Shader:
6 def __init__(self, name, vs_path, fs_path, attributes, uniforms, subroutines={}, geom_path=None):
7 global num_shaders
8 num_shaders += 1
9 self.name = name
10 self.vs_path = vs_path
11 self.fs_path = fs_path
12 self.geom_path = geom_path
13 self.attributes = attributes
14 self.uniforms = uniforms
15 self.subroutines= subroutines
16
17 def header_chunks(self):
18 yield " struct {\n"
19 yield " GLuint program;\n"
20 for attribute in self.attributes:
21 yield f" GLuint {attribute};\n"
22 for uniform in self.uniforms:
23 yield f" GLuint {uniform};\n"
24 for subroutine, routines in self.subroutines.items():
25 yield " struct {\n"
26 yield " GLuint uniform;\n"
27 for r in routines:
28 yield f" GLuint {r};\n"
29 yield f" }} {subroutine};\n"
30 yield f" }} {self.name};\n"
31
32 def source_chunks(self):
33 if self.geom_path!=None:
34 yield f" shaders.{self.name}.program = gl_program_vert_frag_geom(\"{self.vs_path}\", \"{self.fs_path}\", \"{self.geom_path}\");\n"
35 else:
36 yield f" shaders.{self.name}.program = gl_program_vert_frag(\"{self.vs_path}\", \"{self.fs_path}\");\n"
37 for attribute in self.attributes:
38 yield f" shaders.{self.name}.{attribute} = glGetAttribLocation(shaders.{self.name}.program, \"{attribute}\");\n"
39 for uniform in self.uniforms:
40 yield f" shaders.{self.name}.{uniform} = glGetUniformLocation(shaders.{self.name}.program, \"{uniform}\");\n"
41 if len(self.subroutines) > 0:
42 yield " if (gl_has( OPENGL_SUBROUTINES )) {\n"
43 for subroutine, routines in self.subroutines.items():
44 yield f" shaders.{self.name}.{subroutine}.uniform = glGetSubroutineUniformLocation( shaders.{self.name}.program, GL_FRAGMENT_SHADER, \"{subroutine}\" );\n"
45 for r in routines:
46 yield f" shaders.{self.name}.{subroutine}.{r} = glGetSubroutineIndex( shaders.{self.name}.program, GL_FRAGMENT_SHADER, \"{r}\" );\n"
47 yield " }\n"
48
49 def __lt__( self, other ):
50 return self.name < other.name
51
52num_simpleshaders = 0
54 def __init__(self, name, fs_path):
55 super().__init__( name=name, vs_path="project_pos.vert", fs_path=fs_path, attributes=["vertex"], uniforms=["projection","colour","dimensions","dt","paramf","parami","paramv"], subroutines={} )
56 global num_simpleshaders
57 num_simpleshaders += 1
58 def header_chunks(self):
59 yield f" SimpleShader {self.name};\n"
60 def source_chunks(self):
61 yield f" shaders_loadSimple( \"{self.name}\", &shaders.{self.name}, \"{self.fs_path}\" );"
62
63SHADERS = [
64 Shader(
65 name = "solid",
66 vs_path = "project.vert",
67 fs_path = "solid.frag",
68 attributes = ["vertex"],
69 uniforms = ["projection", "colour"],
70 ),
71 Shader(
72 name = "smooth",
73 vs_path = "smooth.vert",
74 fs_path = "smooth.frag",
75 attributes = ["vertex", "vertex_colour"],
76 uniforms = ["projection"],
77 ),
78 Shader(
79 name = "texture",
80 vs_path = "texture.vert",
81 fs_path = "texture.frag",
82 attributes = ["vertex"],
83 uniforms = ["projection", "colour", "tex_mat", "sampler"],
84 ),
85 Shader(
86 name = "texture_depth",
87 vs_path = "texture.vert",
88 fs_path = "texture_depth.frag",
89 attributes = ["vertex"],
90 uniforms = ["projection", "colour", "tex_mat", "sampler", "depth"],
91 ),
92 Shader(
93 name = "texture_depth_only",
94 vs_path = "texture.vert",
95 fs_path = "texture_depth_only.frag",
96 attributes = ["vertex"],
97 uniforms = ["projection", "tex_mat", "sampler"],
98 ),
99 Shader(
100 name = "texture_bicubic",
101 vs_path = "texture.vert",
102 fs_path = "texture_bicubic.frag",
103 attributes = ["vertex"],
104 uniforms = ["projection", "tex_mat", "sampler"],
105 ),
106 Shader(
107 name = "texture_sharpen",
108 vs_path = "texture.vert",
109 fs_path = "texture_sharpen.frag",
110 attributes = ["vertex"],
111 uniforms = ["projection", "colour", "tex_mat", "sampler"],
112 ),
113 Shader(
114 name = "texture_interpolate",
115 vs_path = "texture.vert",
116 fs_path = "texture_interpolate.frag",
117 attributes = ["vertex"],
118 uniforms = ["projection", "colour", "tex_mat", "sampler1", "sampler2", "inter"],
119 ),
120 Shader(
121 name = "texturesdf",
122 vs_path = "texturesdf.vert",
123 fs_path = "texturesdf.frag",
124 attributes = ["vertex"],
125 uniforms = ["projection", "colour", "tex_mat", "sampler", "m", "outline"],
126 ),
127 Shader(
128 name = "stealthoverlay",
129 vs_path = "texture.vert",
130 fs_path = "stealthoverlay.frag",
131 attributes = ["vertex"],
132 uniforms = ["projection", "colour", "tex_mat"],
133 ),
134 Shader(
135 name = "nebula",
136 vs_path = "nebula.vert",
137 fs_path = "nebula_overlay.frag",
138 attributes = ["vertex"],
139 uniforms = ["projection", "hue", "nonuniformity", "horizon", "eddy_scale", "time", "saturation"],
140 ),
141 Shader(
142 name = "nebula_background",
143 vs_path = "nebula.vert",
144 fs_path = "nebula_background.frag",
145 attributes = ["vertex"],
146 uniforms = ["projection", "hue", "nonuniformity", "eddy_scale", "time", "volatility", "saturation"],
147 ),
148 Shader(
149 name = "nebula_puff",
150 vs_path = "project_pos.vert",
151 fs_path = "nebula_puff.frag",
152 attributes = ["vertex"],
153 uniforms = ["projection", "nebu_col", "time", "r" ],
154 ),
155 Shader(
156 name = "nebula_map",
157 vs_path = "system_map.vert",
158 fs_path = "nebula_map.frag",
159 attributes = ["vertex"],
160 uniforms = ["projection", "hue", "time", "globalpos", "alpha", "volatility"],
161 ),
162 Shader(
163 name = "points",
164 vs_path = "smooth.vert",
165 fs_path = "points.frag",
166 attributes = ["vertex", "vertex_colour"],
167 uniforms = ["projection"],
168 ),
169 Shader(
170 name = "dust",
171 vs_path = "dust.vert",
172 fs_path = "dust.frag",
173 attributes = ["vertex", "brightness"],
174 uniforms = ["projection", "offset_xy", "dims", "screen", "use_lines"],
175 geom_path = "dust.geom",
176 ),
177 Shader(
178 name = "lines",
179 vs_path = "lines.vert",
180 fs_path = "lines.frag",
181 attributes = ["vertex"],
182 uniforms = ["projection", "colour"],
183 ),
184 Shader(
185 name = "font",
186 vs_path = "font.vert",
187 fs_path = "font.frag",
188 attributes = ["vertex", "tex_coord"],
189 uniforms = ["projection", "m", "colour", "outline_colour"],
190 ),
191 Shader(
192 name = "beam",
193 vs_path = "project_pos.vert",
194 fs_path = "beam.frag",
195 attributes = ["vertex"],
196 uniforms = ["projection", "colour", "dt", "r", "dimensions" ],
197 subroutines = {
198 "beam_func" : [
199 "beam_default",
200 "beam_wave",
201 "beam_arc",
202 "beam_helix",
203 "beam_organic",
204 "beam_unstable",
205 "beam_fuzzy",
206 ]
207 }
208 ),
209 Shader(
210 name = "jump",
211 vs_path = "project_pos.vert",
212 fs_path = "jump.frag",
213 attributes = ["vertex"],
214 uniforms = ["projection", "progress", "direction", "dimensions", "brightness"],
215 subroutines = {
216 "jump_func" : [
217 "jump_default",
218 "jump_nebula",
219 "jump_organic",
220 "jump_circular",
221 "jump_wind",
222 ]
223 }
224 ),
225 Shader(
226 name = "material",
227 vs_path = "material.vert",
228 fs_path = "material.frag",
229 attributes = ["vertex", "vertex_normal", "vertex_tex"],
230 uniforms = ["projection", "model", "map_Kd", "map_Ks", "map_Ke", "map_Bump", "Ns", "Ka", "Kd", "Ks", "Ke", "Ni", "d", "bm"],
231 ),
232 Shader(
233 name = "colourblind_sim",
234 vs_path = "postprocess.vert",
235 fs_path = "colourblind_sim.frag",
236 attributes = ["VertexPosition"],
237 uniforms = ["ClipSpaceFromLocal", "MainTex", "type", "intensity" ],
238 ),
239 Shader(
240 name = "colourblind_correct",
241 vs_path = "postprocess.vert",
242 fs_path = "colourblind.frag",
243 attributes = ["VertexPosition"],
244 uniforms = ["ClipSpaceFromLocal", "MainTex", "type", "intensity"],
245 ),
246 Shader(
247 name = "shake",
248 vs_path = "postprocess.vert",
249 fs_path = "shake.frag",
250 attributes = ["VertexPosition"],
251 uniforms = ["ClipSpaceFromLocal", "MainTex", "shake_pos", "shake_vel", "shake_force"],
252 ),
253 Shader(
254 name = "damage",
255 vs_path = "postprocess.vert",
256 fs_path = "damage.frag",
257 attributes = ["VertexPosition"],
258 uniforms = ["ClipSpaceFromLocal", "MainTex", "damage_strength", "love_ScreenSize"],
259 ),
260 Shader(
261 name = "gamma_correction",
262 vs_path = "postprocess.vert",
263 fs_path = "gamma_correction.frag",
264 attributes = ["VertexPosition"],
265 uniforms = ["ClipSpaceFromLocal", "MainTex", "gamma"],
266 ),
268 name = "status",
269 fs_path = "status.frag",
270 ),
272 name = "factiondisk",
273 fs_path = "factiondisk.frag",
274 ),
276 name = "stealthaura",
277 fs_path = "stealthaura.frag",
278 ),
280 name = "spobmarker_empty",
281 fs_path = "spobmarker_empty.frag",
282 ),
284 name = "spobmarker_earth",
285 fs_path = "spobmarker_earth.frag",
286 ),
288 name = "spobmarker_rhombus",
289 fs_path = "spobmarker_rhombus.frag",
290 ),
292 name = "spobmarker_triangle",
293 fs_path = "spobmarker_triangle.frag",
294 ),
296 name = "spobmarker_wormhole",
297 fs_path = "spobmarker_wormhole.frag",
298 ),
300 name = "spobmarker_obelisk",
301 fs_path = "spobmarker_obelisk.frag",
302 ),
304 name = "jumpmarker",
305 fs_path = "jumpmarker.frag",
306 ),
308 name = "pilotmarker",
309 fs_path = "pilotmarker.frag",
310 ),
312 name = "pilotscanning",
313 fs_path = "pilotscanning.frag",
314 ),
316 name = "playermarker",
317 fs_path = "playermarker.frag",
318 ),
320 name = "blinkmarker",
321 fs_path = "blinkmarker.frag",
322 ),
324 name = "sysmarker",
325 fs_path = "sysmarker.frag",
326 ),
328 name = "notemarker",
329 fs_path = "notemarker.frag",
330 ),
332 name = "asteroidmarker",
333 fs_path = "asteroidmarker.frag",
334 ),
336 name = "targetship",
337 fs_path = "targetship.frag",
338 ),
340 name = "targetspob",
341 fs_path = "targetspob.frag",
342 ),
344 name = "jumplane",
345 fs_path = "jumplane.frag",
346 ),
348 name = "jumplanegoto",
349 fs_path = "jumplanegoto.frag",
350 ),
352 name = "safelane",
353 fs_path = "safelane.frag",
354 ),
356 name = "iflockon",
357 fs_path = "iflockon.frag",
358 ),
360 name = "gear",
361 fs_path = "gear.frag",
362 ),
364 name = "selectspob",
365 fs_path = "selectspob.frag",
366 ),
368 name = "selectposition",
369 fs_path = "selectposition.frag",
370 ),
372 name = "sdfsolid",
373 fs_path = "sdfsolid.frag",
374 ),
376 name = "circle",
377 fs_path = "circle.frag",
378 ),
380 name = "crosshairs",
381 fs_path = "crosshairs.frag",
382 ),
384 name = "astaura",
385 fs_path = "astaura.frag",
386 ),
388 name = "hilight",
389 fs_path = "hilight.frag",
390 ),
392 name = "hilight_circle",
393 fs_path = "hilight_circle.frag",
394 ),
396 name = "stealthmarker",
397 fs_path = "stealthmarker.frag",
398 ),
400 name = "healthbar",
401 fs_path = "healthbar.frag",
402 ),
404 name = "shop_bg",
405 fs_path = "shop_bg.frag",
406 ),
407]
408SHADERS.sort()
409
410def header_chunks():
411 yield f"/* FILE GENERATED BY {__file__} */"
412
413def generate_h_file():
414 yield from header_chunks()
415
416 yield f"""
417#pragma once
418
419#include <time.h>
420
421#include "glad.h"
422#include "conf.h"
423#include "log.h"
424
425#define NUM_SHADERS {num_shaders}
426#define NUM_SIMPLE_SHADERS {num_simpleshaders}
427
428typedef struct SimpleShader_ {{
429 const char *name;
430 GLuint program;
431 GLuint vertex;
432 GLuint projection;
433 GLuint colour;
434 GLuint dimensions;
435 GLuint dt;
436 GLuint parami;
437 GLuint paramf;
438 GLuint paramv;
439}} SimpleShader;
440
441typedef struct Shaders_ {{
442"""
443
444 for shader in SHADERS:
445 yield from shader.header_chunks()
446
447 yield f""" SimpleShader *simple_shaders[ NUM_SIMPLE_SHADERS ];
448}} Shaders;
449
450extern Shaders shaders;
451
452void shaders_load (void);
453void shaders_unload (void);
454const SimpleShader *shaders_getSimple( const char *name );
455"""
456
457def generate_c_file():
458 yield from header_chunks()
459
460 yield """
461#include <string.h>
462#include "SDL_timer.h"
463#include "shaders.gen.h"
464#include "opengl_shader.h"
465
466Shaders shaders;
467
468static int nsimpleshaders = 0;
469
470static int shaders_cmp( const void *p1, const void *p2 )
471{
472 const SimpleShader **s1 = (const SimpleShader**) p1;
473 const SimpleShader **s2 = (const SimpleShader**) p2;
474 return strcmp( (*s1)->name, (*s2)->name );
475}
476
477static int shaders_loadSimple( const char *name, SimpleShader *shd, const char *fs_path )
478{
479 shd->name = name;
480 shd->program = gl_program_vert_frag( "project_pos.vert", fs_path );
481 shd->vertex = glGetAttribLocation( shd->program, "vertex" );
482 shd->projection = glGetUniformLocation( shd->program, "projection" );
483 shd->colour = glGetUniformLocation( shd->program, "colour" );
484 shd->dimensions = glGetUniformLocation( shd->program, "dimensions" );
485 shd->dt = glGetUniformLocation( shd->program, "dt" );
486 shd->paramf = glGetUniformLocation( shd->program, "paramf" );
487 shd->parami = glGetUniformLocation( shd->program, "parami" );
488 shd->paramv = glGetUniformLocation( shd->program, "paramv" );
489
490 /* Add to list. */
491 shaders.simple_shaders[ nsimpleshaders++ ] = shd;
492
493 return 0;
494}
495
496const SimpleShader *shaders_getSimple( const char *name )
497{
498 const SimpleShader shd = { .name=name };
499 const SimpleShader *shdptr = &shd;
500 const SimpleShader **found = bsearch( &shdptr, shaders.simple_shaders, nsimpleshaders, sizeof(SimpleShader*), shaders_cmp );
501 if (found!=NULL)
502 return *found;
503 return NULL;
504}
505
506void shaders_load (void) {
507 Uint32 time = SDL_GetTicks();
508"""
509
510 for i, shader in enumerate(SHADERS):
511 yield from shader.source_chunks()
512 if i != len(SHADERS) - 1:
513 yield "\n"
514 yield """
515 if (conf.devmode) {
516 time = SDL_GetTicks() - time;
517 DEBUG( n_("Loaded %d Shader in %.3f s", "Loaded %d Shaders in %.3f s", NUM_SHADERS ), NUM_SHADERS, time/1000. );
518 }
519 else
520 DEBUG( n_("Loaded %d Shader", "Loaded %d Shaders", NUM_SHADERS ), NUM_SHADERS );
521}
522
523void shaders_unload (void) {
524"""
525 for shader in SHADERS:
526 yield f" glDeleteProgram(shaders.{shader.name}.program);\n"
527
528 yield """ memset(&shaders, 0, sizeof(shaders));
529 nsimpleshaders = 0;
530}"""
531
532with open("shaders.gen.h", "w") as shaders_gen_h:
533 shaders_gen_h.writelines(generate_h_file())
534
535with open("shaders.gen.c", "w") as shaders_gen_c:
536 shaders_gen_c.writelines(generate_c_file())