Created
May 11, 2015 09:04
-
-
Save datenwolf/f108f2ed4085f3840457 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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