src/shader.c

changeset 144
43636d6a6e25
parent 140
d190fe5315bd
equal deleted inserted replaced
143:4db4f00493ad 144:43636d6a6e25
155 } 155 }
156 return prog; 156 return prog;
157 } 157 }
158 158
159 void asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) { 159 void asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) {
160 if (shader == NULL) {
161 asc_active_glctx->active_program = 0;
162 glUseProgram(0);
163 return;
164 }
165 if (asc_active_glctx->active_program == shader->gl_id) return;
166 asc_active_glctx->active_program = shader->gl_id;
160 glUseProgram(shader->gl_id); 167 glUseProgram(shader->gl_id);
161 glUniformMatrix4fv(shader->projection, 1, GL_FALSE, camera->projection); 168 glUniformMatrix4fv(shader->projection, 1, GL_FALSE, camera->projection);
162 glUniformMatrix4fv(shader->view, 1, GL_FALSE, camera->view); 169 glUniformMatrix4fv(shader->view, 1, GL_FALSE, camera->view);
163 } 170 }
164 171
193 void asc_shader_free_codes(AscShaderCodes codes) { 200 void asc_shader_free_codes(AscShaderCodes codes) {
194 cxFreeDefault(codes.vtx); 201 cxFreeDefault(codes.vtx);
195 cxFreeDefault(codes.frag); 202 cxFreeDefault(codes.frag);
196 } 203 }
197 204
198 AscShaderProgram *asc_shader_register(unsigned int id, asc_shader_create_func create_func) { 205 const void *asc_shader_register(unsigned int id, asc_shader_create_func create_func) {
199 AscGLContext *glctx = asc_active_glctx; 206 AscGLContext *glctx = asc_active_glctx;
200 AscShaderProgram *prog = NULL;
201 #ifndef NDEBUG 207 #ifndef NDEBUG
202 prog = asc_shader_lookup(id); 208 {
203 if (prog != NULL) { 209 const AscShaderProgram *prog = asc_shader_lookup(id);
204 asc_error("Shader program %u already exists. This is a bug!", id); 210 if (prog != NULL) {
205 // still return it, so that the caller does not die immediately 211 asc_error("Shader program %u already exists. This is a bug!", id);
206 return prog; 212 // still return it, so that the caller does not die immediately
213 return prog;
214 }
207 } 215 }
208 #endif 216 #endif
209 prog = create_func(); 217 AscShaderProgram *prog = create_func();
210 prog->id = id; 218 prog->id = id;
211 cxListAdd(glctx->shaders, prog); 219 cxListAdd(glctx->shaders, prog);
212 return prog; 220 return prog;
213 } 221 }
214 222
215 AscShaderProgram *asc_shader_lookup(unsigned int id) { 223 const void *asc_shader_lookup(unsigned int id) {
216 CxIterator iter = cxListIterator(asc_active_glctx->shaders); 224 CxIterator iter = cxListIterator(asc_active_glctx->shaders);
217 cx_foreach(AscShaderProgram *, prog, iter) { 225 cx_foreach(const AscShaderProgram *, prog, iter) {
218 if (prog->id == id) return prog; 226 if (prog->id == id) return prog;
219 } 227 }
220 return NULL; 228 return NULL;
221 } 229 }
222 230
223 AscShaderProgram *asc_shader_lookup_or_create(unsigned int id, asc_shader_create_func create_func) { 231 const void *asc_shader_lookup_or_create(unsigned int id, asc_shader_create_func create_func) {
224 AscShaderProgram *prog = asc_shader_lookup(id); 232 const AscShaderProgram *prog = asc_shader_lookup(id);
225 if (prog == NULL) { 233 if (prog == NULL) {
226 return asc_shader_register(id, create_func); 234 return asc_shader_register(id, create_func);
227 } 235 }
228 return prog; 236 return prog;
229 } 237 }
230 238
231 void asc_shader_clear_registry(void) { 239 void asc_shader_clear_registry(void) {
232 cxListClear(asc_active_glctx->shaders); 240 cxListClear(asc_active_glctx->shaders);
233 } 241 // also clear the active program to avoid accidental matches with newly created shaders
242 asc_shader_use(NULL, NULL);
243 }

mercurial