Skip to content

Instantly share code, notes, and snippets.

@datenwolf
Created May 11, 2015 09:04
Show Gist options
  • Save datenwolf/f108f2ed4085f3840457 to your computer and use it in GitHub Desktop.
Save datenwolf/f108f2ed4085f3840457 to your computer and use it in GitHub Desktop.
GLuint load_gl_shader_from_sources(
GLenum shader_unit,
char const * const * const sources )
{
GLuint shader = glCreateShader(shader_unit);
if( !shader ) {
goto failed_shader;
}
size_t n_sources = 0;
for(; sources[n_sources]; n_sources++);
GLint * const lengths = alloca(sizeof(GLint)*(n_sources+1));
if( !lengths ) {
goto failed_lengths;
}
lengths[n_sources] = 0;
for(size_t i = 0; i < n_sources; i++) {
lengths[i] = strlen(sources[i]);
}
glShaderSource(shader, n_sources, sources, lengths);
glCompileShader(shader);
GLint shader_status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_status);
if( shader_status == GL_FALSE ) {
GLint log_length, returned_length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
char *shader_infolog = alloca(log_length);
if(shader_infolog) {
glGetShaderInfoLog(
shader,
log_length,
&returned_length,
shader_infolog );
char const * shader_unit_str = NULL;
switch(shader_unit) {
case GL_VERTEX_SHADER: shader_unit_str = "vertex"; break;
case GL_FRAGMENT_SHADER: shader_unit_str = "fragment"; break;
}
fprintf(stderr,
"\n %s shader compilation failed;\n%*s",
shader_unit_str,
returned_length, shader_infolog );
}
goto failed_compile;
}
return shader;
failed_compile:
failed_lengths:
glDeleteShader(shader);
failed_shader:
return 0;
}
GLuint load_gl_program_from_sources(
char const * const * const sources_vs,
char const * const * const sources_fs )
{
GLuint program = glCreateProgram();
if( !program ) {
goto failed_program;
}
GLuint vert_shader = 0;
if( sources_vs ) {
vert_shader = load_gl_shader_from_sources(
GL_VERTEX_SHADER,
sources_vs );
if( !vert_shader ) {
goto failed_vert_shader;
}
}
GLuint frag_shader = 0;
if( sources_fs ) {
frag_shader = load_gl_shader_from_sources(
GL_FRAGMENT_SHADER,
sources_fs );
if( !frag_shader ) {
goto failed_frag_shader;
}
}
glAttachShader(program, vert_shader);
glAttachShader(program, frag_shader);
glLinkProgram(program);
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if( GL_FALSE == linkStatus ) {
GLint log_length, returned_length;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
char *program_infolog= alloca(log_length);
if(program_infolog) {
glGetProgramInfoLog(
program,
log_length,
&returned_length,
program_infolog );
fwrite(program_infolog, returned_length, 1, stderr);
}
goto failed_link;
}
/* shaders will get actually deleted only after the rogram gets deleted */
glDeleteShader(vert_shader);
glDeleteShader(frag_shader);
return program;
failed_link:
if(frag_shader)
glDeleteShader(frag_shader);
failed_frag_shader:
if(vert_shader)
glDeleteShader(vert_shader);
failed_vert_shader:
glDeleteProgram(program);
failed_program:
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment