void shader_make_program(struct Shader* p, uint32_t set_i, const char* name) { size_t name_length = strlen(name); log_assert( name_length > 0 ); log_assert( name_length < 256 ); p->name[0] = '\0'; strncat(p->name, name, name_length); if( p->num_objects == 0 ) { log_warn(__FILE__, __LINE__, "no objects for linking in \"%s\", using defaults\n", name); shader_attach(p, GL_VERTEX_SHADER, "prefix.vert", 1, "no_shading.vert"); shader_attach(p, GL_FRAGMENT_SHADER, "prefix.frag", 1, "no_shading.frag"); log_assert( p->num_objects > 0 ); } p->program = glsl_create_program(p->num_objects, p->objects); p->attribute_set = set_i; for( uint32_t attribute_i = 0; attribute_i < MAX_SHADER_ATTRIBUTES; attribute_i++ ) { glBindAttribLocation(p->program, attribute_i, global_shader_attribute_names[set_i][attribute_i]); } p->program = glsl_link_program(p->program); log_assert( p->program > 0 ); p->verified = false; shader_setup_locations(p); }
static gboolean glsl_load_shaders() { gl_shader_t shader_array[GLSL_NUM_SHADERS]; gboolean ok = TRUE; unsigned i, j; for( i=0; i<GLSL_NUM_SHADERS; i++ ) shader_array[i] = INVALID_SHADER; for( i=0; i<GLSL_NUM_PROGRAMS; i++ ) program_array[i] = INVALID_PROGRAM; /* Compile the shader fragments */ for( i=0; shader_source[i].type != GLSL_NO_SHADER; i++ ) { gl_shader_t shader = INVALID_SHADER; switch(shader_source[i].type) { case GLSL_VERTEX_SHADER: shader = glsl_create_vertex_shader(shader_source[i].source); break; case GLSL_FRAGMENT_SHADER: shader = glsl_create_fragment_shader(shader_source[i].source); break; } if( shader == INVALID_SHADER ) { ok = FALSE; break; } else { shader_array[i] = shader; } } /* Link the programs */ if(ok) for( i=0; program_list[i][0] != GLSL_NO_SHADER; i++ ) { gl_shader_t shaderv[GLSL_NUM_SHADERS+1]; for( j=0; program_list[i][j] != GLSL_NO_SHADER; j++ ) { shaderv[j] = shader_array[program_list[i][j]]; } shaderv[j] = INVALID_SHADER; gl_program_t program = glsl_create_program(shaderv); if( program == INVALID_PROGRAM ) { ok = FALSE; break; } else { /* Check that we can actually use the program (can this really fail?) */ glsl_use_program(program); if( !glsl_check_program_error( "Failed to activate shader program", program ) ) { ok = FALSE; } program_array[i] = program; } } /** * Destroy the compiled fragments (the linked programs don't need them * anymore) */ for( i=0; i<GLSL_NUM_SHADERS; i++ ) { if( shader_array[i] != INVALID_SHADER ) glsl_destroy_shader(shader_array[i]); } /** * If we errored, delete the programs. It's all or nothing. */ if( !ok ) { glsl_unload_shaders(); return FALSE; } glsl_init_programs(program_array); glsl_use_program(0); return TRUE; }