src/shader.c

changeset 222
2cb9a71df7a6
parent 221
14eddd43b3f7
child 223
4f32c7755138
equal deleted inserted replaced
221:14eddd43b3f7 222:2cb9a71df7a6
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) {

mercurial