naev 0.11.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 gshader = f"\"{self.geom_path}\"" if self.geom_path!=None else "NULL"
34 yield f" shaders.{self.name}.program = gl_program_vert_frag(\"{self.vs_path}\", \"{self.fs_path}\", {gshader});\n"
35 for attribute in self.attributes:
36 yield f" shaders.{self.name}.{attribute} = glGetAttribLocation(shaders.{self.name}.program, \"{attribute}\");\n"
37 for uniform in self.uniforms:
38 yield f" shaders.{self.name}.{uniform} = glGetUniformLocation(shaders.{self.name}.program, \"{uniform}\");\n"
39 if len(self.subroutines) > 0:
40 yield " if (gl_has( OPENGL_SUBROUTINES )) {\n"
41 for subroutine, routines in self.subroutines.items():
42 yield f" shaders.{self.name}.{subroutine}.uniform = glGetSubroutineUniformLocation( shaders.{self.name}.program, GL_FRAGMENT_SHADER, \"{subroutine}\" );\n"
43 for r in routines:
44 yield f" shaders.{self.name}.{subroutine}.{r} = glGetSubroutineIndex( shaders.{self.name}.program, GL_FRAGMENT_SHADER, \"{r}\" );\n"
45 yield " }\n"
46
47 def __lt__( self, other ):
48 return self.name < other.name
49
50num_simpleshaders = 0
52 def __init__(self, name, fs_path):
53 super().__init__( name=name, vs_path="project_pos.vert", fs_path=fs_path, attributes=["vertex"], uniforms=["projection","colour","dimensions","dt","paramf","parami","paramv"], subroutines={} )
54 global num_simpleshaders
55 num_simpleshaders += 1
56 def header_chunks(self):
57 yield f" SimpleShader {self.name};\n"
58 def source_chunks(self):
59 yield f" shaders_loadSimple( \"{self.name}\", &shaders.{self.name}, \"{self.fs_path}\" );"
60
61SHADERS = [
62 Shader(
63 name = "solid",
64 vs_path = "project.vert",
65 fs_path = "solid.frag",
66 attributes = ["vertex"],
67 uniforms = ["projection", "colour"],
68 subroutines = {},
69 ),
70 Shader(
71 name = "trail",
72 vs_path = "project_pos.vert",
73 fs_path = "trail.frag",
74 attributes = ["vertex"],
75 uniforms = ["projection", "c1", "c2", "t1", "t2", "dt", "pos1", "pos2", "r", "nebu_col" ],
76 subroutines = {
77 "trail_func" : [
78 "trail_default",
79 "trail_pulse",
80 "trail_wave",
81 "trail_flame",
82 "trail_nebula",
83 "trail_arc",
84 "trail_bubbles",
85 ]
86 }
87 ),
88 Shader(
89 name = "smooth",
90 vs_path = "smooth.vert",
91 fs_path = "smooth.frag",
92 attributes = ["vertex", "vertex_colour"],
93 uniforms = ["projection"],
94 subroutines = {},
95 ),
96 Shader(
97 name = "texture",
98 vs_path = "texture.vert",
99 fs_path = "texture.frag",
100 attributes = ["vertex"],
101 uniforms = ["projection", "colour", "tex_mat", "sampler"],
102 subroutines = {},
103 ),
104 Shader(
105 name = "texture_interpolate",
106 vs_path = "texture.vert",
107 fs_path = "texture_interpolate.frag",
108 attributes = ["vertex"],
109 uniforms = ["projection", "colour", "tex_mat", "sampler1", "sampler2", "inter"],
110 subroutines = {},
111 ),
112 Shader(
113 name = "texturesdf",
114 vs_path = "texturesdf.vert",
115 fs_path = "texturesdf.frag",
116 attributes = ["vertex"],
117 uniforms = ["projection", "colour", "tex_mat", "sampler", "m", "outline"],
118 subroutines = {},
119 ),
120 Shader(
121 name = "stealthoverlay",
122 vs_path = "texture.vert",
123 fs_path = "stealthoverlay.frag",
124 attributes = ["vertex"],
125 uniforms = ["projection", "colour", "tex_mat"],
126 subroutines = {},
127 ),
128 Shader(
129 name = "nebula",
130 vs_path = "nebula.vert",
131 fs_path = "nebula_overlay.frag",
132 attributes = ["vertex"],
133 uniforms = ["projection", "hue", "nonuniformity", "horizon", "eddy_scale", "time"],
134 subroutines = {},
135 ),
136 Shader(
137 name = "nebula_background",
138 vs_path = "nebula.vert",
139 fs_path = "nebula_background.frag",
140 attributes = ["vertex"],
141 uniforms = ["projection", "hue", "nonuniformity", "eddy_scale", "time", "volatility"],
142 subroutines = {},
143 ),
144 Shader(
145 name = "nebula_puff",
146 vs_path = "project_pos.vert",
147 fs_path = "nebula_puff.frag",
148 attributes = ["vertex"],
149 uniforms = ["projection", "nebu_col", "time", "r" ],
150 subroutines = {},
151 ),
152 Shader(
153 name = "nebula_map",
154 vs_path = "system_map.vert",
155 fs_path = "nebula_map.frag",
156 attributes = ["vertex"],
157 uniforms = ["projection", "hue", "time", "globalpos", "alpha", "volatility"],
158 subroutines = {},
159 ),
160 Shader(
161 name = "points",
162 vs_path = "smooth.vert",
163 fs_path = "points.frag",
164 attributes = ["vertex", "vertex_colour"],
165 uniforms = ["projection"],
166 subroutines = {},
167 ),
168 Shader(
169 name = "dust",
170 vs_path = "dust.vert",
171 fs_path = "dust.frag",
172 attributes = ["vertex", "brightness"],
173 uniforms = ["projection", "offset_xy", "dims", "screen", "use_lines"],
174 subroutines = {},
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 subroutines = {},
184 ),
185 Shader(
186 name = "font",
187 vs_path = "font.vert",
188 fs_path = "font.frag",
189 attributes = ["vertex", "tex_coord"],
190 uniforms = ["projection", "m", "colour", "outline_colour"],
191 subroutines = {},
192 ),
193 Shader(
194 name = "beam",
195 vs_path = "project_pos.vert",
196 fs_path = "beam.frag",
197 attributes = ["vertex"],
198 uniforms = ["projection", "colour", "dt", "r", "dimensions" ],
199 subroutines = {
200 "beam_func" : [
201 "beam_default",
202 "beam_wave",
203 "beam_arc",
204 "beam_helix",
205 "beam_organic",
206 "beam_unstable",
207 "beam_fuzzy",
208 ]
209 }
210 ),
211 Shader(
212 name = "jump",
213 vs_path = "project_pos.vert",
214 fs_path = "jump.frag",
215 attributes = ["vertex"],
216 uniforms = ["projection", "progress", "direction", "dimensions", "brightness"],
217 subroutines = {
218 "jump_func" : [
219 "jump_default",
220 "jump_nebula",
221 "jump_organic",
222 "jump_circular",
223 "jump_wind",
224 ]
225 }
226 ),
227 Shader(
228 name = "material",
229 vs_path = "material.vert",
230 fs_path = "material.frag",
231 attributes = ["vertex", "vertex_normal", "vertex_tex"],
232 uniforms = ["projection", "model", "map_Kd", "map_Ks", "map_Ke", "map_Bump", "Ns", "Ka", "Kd", "Ks", "Ke", "Ni", "d", "bm"],
233 subroutines = {},
234 ),
235 Shader(
236 name = "colourblind",
237 vs_path = "postprocess.vert",
238 fs_path = "colourblind.frag",
239 attributes = ["VertexPosition"],
240 uniforms = ["ClipSpaceFromLocal", "MainTex"],
241 subroutines = {},
242 ),
243 Shader(
244 name = "shake",
245 vs_path = "postprocess.vert",
246 fs_path = "shake.frag",
247 attributes = ["VertexPosition"],
248 uniforms = ["ClipSpaceFromLocal", "MainTex", "shake_pos", "shake_vel", "shake_force"],
249 subroutines = {},
250 ),
251 Shader(
252 name = "damage",
253 vs_path = "postprocess.vert",
254 fs_path = "damage.frag",
255 attributes = ["VertexPosition"],
256 uniforms = ["ClipSpaceFromLocal", "MainTex", "damage_strength", "love_ScreenSize"],
257 subroutines = {},
258 ),
259 Shader(
260 name = "gamma_correction",
261 vs_path = "postprocess.vert",
262 fs_path = "gamma_correction.frag",
263 attributes = ["VertexPosition"],
264 uniforms = ["ClipSpaceFromLocal", "MainTex", "gamma"],
265 subroutines = {},
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 ),
403]
404SHADERS.sort()
405
406def header_chunks():
407 yield f"/* FILE GENERATED BY {__file__} */"
408
409def generate_h_file():
410 yield from header_chunks()
411
412 yield f"""
413#pragma once
414
415#include <time.h>
416
417#include "glad.h"
418#include "conf.h"
419#include "log.h"
420
421#define NUM_SHADERS {num_shaders}
422#define NUM_SIMPLE_SHADERS {num_simpleshaders}
423
424typedef struct SimpleShader_ {{
425 const char *name;
426 GLuint program;
427 GLuint vertex;
428 GLuint projection;
429 GLuint colour;
430 GLuint dimensions;
431 GLuint dt;
432 GLuint parami;
433 GLuint paramf;
434 GLuint paramv;
435}} SimpleShader;
436
437typedef struct Shaders_ {{
438"""
439
440 for shader in SHADERS:
441 yield from shader.header_chunks()
442
443 yield f""" SimpleShader *simple_shaders[ NUM_SIMPLE_SHADERS ];
444}} Shaders;
445
446extern Shaders shaders;
447
448void shaders_load (void);
449void shaders_unload (void);
450const SimpleShader *shaders_getSimple( const char *name );
451"""
452
453def generate_c_file():
454 yield from header_chunks()
455
456 yield """
457#include <string.h>
458#include "shaders.gen.h"
459#include "opengl_shader.h"
460
461Shaders shaders;
462
463static int nsimpleshaders = 0;
464
465static int shaders_cmp( const void *p1, const void *p2 )
466{
467 const SimpleShader **s1 = (const SimpleShader**) p1;
468 const SimpleShader **s2 = (const SimpleShader**) p2;
469 return strcmp( (*s1)->name, (*s2)->name );
470}
471
472static int shaders_loadSimple( const char *name, SimpleShader *shd, const char *fs_path )
473{
474 shd->name = name;
475 shd->program = gl_program_vert_frag( "project_pos.vert", fs_path, NULL );
476 shd->vertex = glGetAttribLocation( shd->program, "vertex" );
477 shd->projection = glGetUniformLocation( shd->program, "projection" );
478 shd->colour = glGetUniformLocation( shd->program, "colour" );
479 shd->dimensions = glGetUniformLocation( shd->program, "dimensions" );
480 shd->dt = glGetUniformLocation( shd->program, "dt" );
481 shd->paramf = glGetUniformLocation( shd->program, "paramf" );
482 shd->parami = glGetUniformLocation( shd->program, "parami" );
483 shd->paramv = glGetUniformLocation( shd->program, "paramv" );
484
485 /* Add to list. */
486 shaders.simple_shaders[ nsimpleshaders++ ] = shd;
487
488 return 0;
489}
490
491const SimpleShader *shaders_getSimple( const char *name )
492{
493 const SimpleShader shd = { .name=name };
494 const SimpleShader *shdptr = &shd;
495 const SimpleShader **found = bsearch( &shdptr, shaders.simple_shaders, nsimpleshaders, sizeof(SimpleShader*), shaders_cmp );
496 if (found!=NULL)
497 return *found;
498 return NULL;
499}
500
501void shaders_load (void) {
502 Uint32 time = SDL_GetTicks();
503"""
504
505 for i, shader in enumerate(SHADERS):
506 yield from shader.source_chunks()
507 if i != len(SHADERS) - 1:
508 yield "\n"
509 yield """
510 if (conf.devmode) {
511 time = SDL_GetTicks() - time;
512 DEBUG( n_("Loaded %d Shader in %.3f s", "Loaded %d Shaders in %.3f s", NUM_SHADERS ), NUM_SHADERS, time/1000. );
513 }
514 else
515 DEBUG( n_("Loaded %d Shader", "Loaded %d Shaders", NUM_SHADERS ), NUM_SHADERS );
516}
517
518void shaders_unload (void) {
519"""
520 for shader in SHADERS:
521 yield f" glDeleteProgram(shaders.{shader.name}.program);\n"
522
523 yield """ memset(&shaders, 0, sizeof(shaders));
524 nsimpleshaders = 0;
525}"""
526
527with open("shaders.gen.h", "w") as shaders_gen_h:
528 shaders_gen_h.writelines(generate_h_file())
529
530with open("shaders.gen.c", "w") as shaders_gen_c:
531 shaders_gen_c.writelines(generate_c_file())