152 program->destr_func(program); |
152 program->destr_func(program); |
153 } |
153 } |
154 cxFreeDefault(program); |
154 cxFreeDefault(program); |
155 } |
155 } |
156 |
156 |
157 bool asc_shader_invalid(const AscShaderProgram *program) { |
157 static 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 AscShaderProgram *asc_shader_create(AscShaderCodes codes, size_t mem_size) { |
161 AscShaderProgram *asc_shader_create(AscShaderCodeInfo code_info, size_t mem_size, asc_shader_init_func init_func, int flags) { |
162 AscShaderProgram *prog = cxZallocDefault(mem_size); |
162 AscShaderCodes codes; |
163 unsigned shader[2]; |
163 if (asc_shader_load_code_files(code_info, &codes)) { |
164 unsigned n = 0; |
164 asc_error("Loading shader failed."); |
165 // TODO: clean up this pp mess by introducing proper nested structs |
165 return NULL; |
166 if (codes.vtx) { |
166 } |
167 shader[n++] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx, codes.vtx_pp, codes.vtx_pp_list, codes.vtx_pp_list_select); |
167 AscShaderProgram *shader_program = cxZallocDefault(mem_size); |
168 } |
168 { |
169 if (codes.frag) { |
169 unsigned shader[2]; |
170 shader[n++] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag, codes.frag_pp, codes.frag_pp_list, codes.frag_pp_list_select); |
170 unsigned n = 0; |
171 } |
171 // TODO: clean up this pp mess by introducing proper nested structs |
172 asc_shader_link(shader, n, prog); |
172 if (codes.vtx) { |
173 return prog; |
173 shader[n++] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx, codes.vtx_pp, codes.vtx_pp_list, codes.vtx_pp_list_select); |
174 } |
174 } |
|
175 if (codes.frag) { |
|
176 shader[n++] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag, codes.frag_pp, codes.frag_pp_list, codes.frag_pp_list_select); |
|
177 } |
|
178 asc_shader_link(shader, n, shader_program); |
|
179 } |
|
180 asc_shader_free_codes(codes); |
|
181 if (asc_error_catch_gl("Compile and link shader") || asc_shader_invalid(shader_program)) { |
|
182 asc_shader_free(shader_program); |
|
183 return NULL; |
|
184 } |
|
185 |
|
186 init_func(shader_program, flags); |
|
187 |
|
188 if (asc_error_catch_gl("Initializing shader")) { |
|
189 asc_shader_free(shader_program); |
|
190 return NULL; |
|
191 } |
|
192 |
|
193 return shader_program; |
|
194 } |
|
195 |
175 |
196 |
176 int asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) { |
197 int asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) { |
177 if (shader == NULL) { |
198 if (asc_shader_invalid(shader)) { |
178 asc_active_glctx->active_program = 0; |
199 asc_active_glctx->active_program = 0; |
179 glUseProgram(0); |
200 glUseProgram(0); |
180 return 0; |
201 return 0; |
181 } |
202 } |
182 if (asc_active_glctx->active_program == shader->gl_id) return 0; |
203 if (asc_active_glctx->active_program == shader->gl_id) return 0; |
268 |
289 |
269 asc_uniform_loc asc_shader_get_uniform_loc(const AscShaderProgram *shader, const char *name) { |
290 asc_uniform_loc asc_shader_get_uniform_loc(const AscShaderProgram *shader, const char *name) { |
270 return glGetUniformLocation(shader->gl_id, name); |
291 return glGetUniformLocation(shader->gl_id, name); |
271 } |
292 } |
272 |
293 |
|
294 void asc_shader_init_uniform_loc(AscShaderProgram *shader, off_t mem_offset, const char *name) { |
|
295 *((asc_uniform_loc*)((char *) shader + mem_offset)) = glGetUniformLocation(shader->gl_id, name); |
|
296 } |
|
297 |
273 void asc_shader_upload_model_matrix(const AscShaderProgram *shader, const AscSceneNode *node) { |
298 void asc_shader_upload_model_matrix(const AscShaderProgram *shader, const AscSceneNode *node) { |
274 glUniformMatrix4fv(shader->model, 1,GL_FALSE, node->world_transform); |
299 glUniformMatrix4fv(shader->model, 1,GL_FALSE, node->world_transform); |
275 } |
300 } |
276 |
301 |
277 void asc_shader_upload_col4f(int uniform_id, asc_col4f color) { |
302 void asc_shader_upload_col4f(int uniform_id, asc_col4f color) { |