156 |
156 |
157 bool asc_shader_invalid(const AscShaderProgram *program) { |
157 bool asc_shader_invalid(const AscShaderProgram *program) { |
158 return program == NULL || program->gl_id == 0; |
158 return program == NULL || program->gl_id == 0; |
159 } |
159 } |
160 |
160 |
161 void *asc_shader_create(AscShaderCodes codes, size_t mem_size) { |
161 AscShaderProgram *asc_shader_create(AscShaderCodes codes, size_t mem_size) { |
162 AscShaderProgram *prog = cxZallocDefault(mem_size); |
162 AscShaderProgram *prog = cxZallocDefault(mem_size); |
163 unsigned shader[2]; |
163 unsigned shader[2]; |
164 unsigned n = 0; |
164 unsigned n = 0; |
165 // TODO: clean up this pp mess by introducing proper nested structs |
165 // TODO: clean up this pp mess by introducing proper nested structs |
166 if (codes.vtx) { |
166 if (codes.vtx) { |
171 } |
171 } |
172 asc_shader_link(shader, n, prog); |
172 asc_shader_link(shader, n, prog); |
173 return prog; |
173 return prog; |
174 } |
174 } |
175 |
175 |
176 void asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) { |
176 int asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) { |
177 if (shader == NULL) { |
177 if (shader == NULL) { |
178 asc_active_glctx->active_program = 0; |
178 asc_active_glctx->active_program = 0; |
179 glUseProgram(0); |
179 glUseProgram(0); |
180 return; |
180 return 0; |
181 } |
181 } |
182 if (asc_active_glctx->active_program == shader->gl_id) return; |
182 if (asc_active_glctx->active_program == shader->gl_id) return 0; |
|
183 if (asc_shader_invalid(shader)) return -1; |
183 asc_active_glctx->active_program = shader->gl_id; |
184 asc_active_glctx->active_program = shader->gl_id; |
184 glUseProgram(shader->gl_id); |
185 glUseProgram(shader->gl_id); |
185 glUniformMatrix4fv(shader->projection, 1, GL_FALSE, camera->projection); |
186 glUniformMatrix4fv(shader->projection, 1, GL_FALSE, camera->projection); |
186 glUniformMatrix4fv(shader->view, 1, GL_FALSE, camera->view); |
187 glUniformMatrix4fv(shader->view, 1, GL_FALSE, camera->view); |
|
188 return asc_error_catch_all_gl(); |
187 } |
189 } |
188 |
190 |
189 static int asc_shader_load_code_file(const char *filename, char **code) { |
191 static int asc_shader_load_code_file(const char *filename, char **code) { |
190 if (filename == NULL) { |
192 if (filename == NULL) { |
191 *code = NULL; |
193 *code = NULL; |
221 void asc_shader_free_codes(AscShaderCodes codes) { |
223 void asc_shader_free_codes(AscShaderCodes codes) { |
222 cxFreeDefault(codes.vtx); |
224 cxFreeDefault(codes.vtx); |
223 cxFreeDefault(codes.frag); |
225 cxFreeDefault(codes.frag); |
224 } |
226 } |
225 |
227 |
226 const void *asc_shader_register(unsigned int id, asc_shader_create_func create_func, int create_flags) { |
228 const AscShaderProgram *asc_shader_register(unsigned int id, asc_shader_create_func create_func, int create_flags) { |
227 AscGLContext *glctx = asc_active_glctx; |
229 AscGLContext *glctx = asc_active_glctx; |
228 #ifndef NDEBUG |
230 #ifndef NDEBUG |
229 { |
231 { |
230 const AscShaderProgram *prog = asc_shader_lookup(id); |
232 const AscShaderProgram *prog = asc_shader_lookup(id); |
231 if (prog != NULL) { |
233 if (prog != NULL) { |
240 prog->id = id; |
242 prog->id = id; |
241 cxListAdd(glctx->shaders, prog); |
243 cxListAdd(glctx->shaders, prog); |
242 return prog; |
244 return prog; |
243 } |
245 } |
244 |
246 |
245 const void *asc_shader_lookup(unsigned int id) { |
247 const AscShaderProgram *asc_shader_lookup(unsigned int id) { |
246 CxIterator iter = cxListIterator(asc_active_glctx->shaders); |
248 CxIterator iter = cxListIterator(asc_active_glctx->shaders); |
247 cx_foreach(const AscShaderProgram *, prog, iter) { |
249 cx_foreach(const AscShaderProgram *, prog, iter) { |
248 if (prog->id == id) return prog; |
250 if (prog->id == id) return prog; |
249 } |
251 } |
250 return NULL; |
252 return NULL; |
251 } |
253 } |
252 |
254 |
253 const void *asc_shader_lookup_or_create(unsigned int id, asc_shader_create_func create_func, int create_flags) { |
255 const AscShaderProgram *asc_shader_lookup_or_create(unsigned int id, asc_shader_create_func create_func, int create_flags) { |
254 const AscShaderProgram *prog = asc_shader_lookup(id); |
256 const AscShaderProgram *prog = asc_shader_lookup(id); |
255 if (prog == NULL) { |
257 if (prog == NULL) { |
256 return asc_shader_register(id, create_func, create_flags); |
258 return asc_shader_register(id, create_func, create_flags); |
257 } |
259 } |
258 return prog; |
260 return prog; |