22 static const char *macros[] = {
23 "#define USE_LIGHT0\n",
24 "#define USE_LIGHT1\n",
25 "#define USE_LIGHT2\n",
26 "#define USE_LIGHT3\n",
27 "#define USE_TEXMAP\n",
28 "#define USE_CUBEMAP\n",
29 "#define USE_SPHMAP\n",
30 "#define USE_SHADOWMAP\n",
39 static unsigned int mkshader(unsigned int type);
41 static char *vs_fname, *ps_fname;
42 static unsigned int state;
44 #define CACHE_SIZE (1 << MAX_STATE_BITS)
45 static struct sdrcache cache[CACHE_SIZE];
47 int uber_init(const char *vsname, const char *psname)
50 memset(cache, 0, sizeof cache);
52 vs_fname = strdup(vsname);
53 ps_fname = strdup(psname);
54 if(!vs_fname || !ps_fname) {
61 void uber_destroy(void)
65 for(i=0; i<CACHE_SIZE; i++) {
67 free_shader(cache[i].vs);
69 free_shader(cache[i].ps);
71 free_program(cache[i].prog);
82 void uber_enable_light(int idx)
84 if(idx >= 0 && idx < MAX_LIGHTS) {
85 state |= (1 << (UBER_LIGHT0 + idx));
89 void uber_disable_light(int idx)
91 if(idx >= 0 && idx < MAX_LIGHTS) {
92 state &= ~(1 << (UBER_LIGHT0 + idx));
96 void uber_enable_texmap(void)
98 state |= (1 << UBER_TEXMAP);
101 void uber_disable_texmap(void)
103 state &= ~(1 << UBER_TEXMAP);
106 void uber_enable_cubemap(void)
108 state |= (1 << UBER_CUBEMAP);
111 void uber_disable_cubemap(void)
113 state &= ~(1 << UBER_CUBEMAP);
116 void uber_enable_sphmap(void)
118 state |= (1 << UBER_SPHMAP);
121 void uber_disable_sphmap(void)
123 state &= ~(1 << UBER_SPHMAP);
126 void uber_enable_shadows(void)
128 state |= (1 << UBER_SHADOWS);
131 void uber_disable_shadows(void)
133 state &= ~(1 << UBER_SHADOWS);
136 unsigned int uber_vertex_shader(void)
138 if(!cache[state].vs) {
139 cache[state].vs = mkshader(GL_VERTEX_SHADER);
141 return cache[state].vs;
144 unsigned int uber_pixel_shader(void)
146 if(!cache[state].ps) {
147 cache[state].ps = mkshader(GL_FRAGMENT_SHADER);
149 return cache[state].ps;
152 static unsigned int mkshader(unsigned int type)
156 clear_shader_header(type);
158 debug_log("mkshader(%s): %x\n", type == GL_VERTEX_SHADER ? "vertex" : "pixel");
160 for(i=0; i<MAX_STATE_BITS; i++) {
161 if(state & (1 << i)) {
162 add_shader_header(type, macros[i]);
163 debug_log(" - header: %s\n", macros[i]);
166 res = load_shader(type == GL_VERTEX_SHADER ? vs_fname : ps_fname, type);
167 clear_shader_header(type);
171 unsigned int uber_program(void)
173 if(!cache[state].prog) {
175 if(!(vs = uber_vertex_shader()) || !(ps = uber_pixel_shader())) {
176 error_log("uber_program failed to make shaders for state: %x\n", state);
179 if(!(cache[state].prog = create_program_link(vs, ps, 0))) {
180 error_log("uber_program failed to link program for state: %x\n", state);
184 return cache[state].prog;