diff --git a/glslUtil/glslUtil.c b/glslUtil/glslUtil.c index 8fca69d..50102c9 100644 --- a/glslUtil/glslUtil.c +++ b/glslUtil/glslUtil.c @@ -272,3 +272,60 @@ GLuint guMakeBuffer(GLenum target, GLenum usage, const void *ptr, size_t sz) glBufferData(target, sz, ptr, usage); return id; } + +GLuint guMakeProgramFromSource(const char *v_shader, const char *f_shader, + guAttribBinding *bindings) +{ + GLuint v_shader_id = guMakeShader(GL_VERTEX_SHADER, v_shader); + GLuint f_shader_id = guMakeShader(GL_FRAGMENT_SHADER, f_shader); + if (v_shader_id <= 0 || f_shader_id <= 0) + return 0; + GLuint id = guMakeProgram(v_shader_id, f_shader_id, bindings); + glDeleteShader(v_shader_id); + glDeleteShader(f_shader_id); + return id; +} + +GLuint guMakeProgramFromFiles(const char *v_shader, const char *f_shader, + guAttribBinding *bindings) +{ + GLuint v_shader_id = guMakeShaderFromFile(GL_VERTEX_SHADER, v_shader); + GLuint f_shader_id = guMakeShaderFromFile(GL_FRAGMENT_SHADER, f_shader); + if (v_shader_id <= 0 || f_shader_id <= 0) + return 0; + GLuint id = guMakeProgram(v_shader_id, f_shader_id, bindings); + glDeleteShader(v_shader_id); + glDeleteShader(f_shader_id); + return id; +} + +GLuint guMakeProgram(GLuint v_shader_id, GLuint f_shader_id, + guAttribBinding *bindings) +{ + GLuint program = glCreateProgram(); + glAttachShader(program, v_shader_id); + glAttachShader(program, f_shader_id); + + if (bindings != NULL) + { + int i; + for (i = 0; bindings[i].index > 0 && bindings[i].name != NULL; i++) + { + glBindAttribLocation(program, bindings[i].index, bindings[i].name); + } + } + + glLinkProgram(program); + + GLint link_status; + glGetProgramiv(program, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) + { + char *log = guGetProgramLog(program); + fprintf(stderr, "Program log:\n%s\n", log); + free(log); + return 0; + } + + return program; +} diff --git a/glslUtil/glslUtil.h b/glslUtil/glslUtil.h index 2fc0a70..c44fb45 100644 --- a/glslUtil/glslUtil.h +++ b/glslUtil/glslUtil.h @@ -9,6 +9,10 @@ #endif typedef GLfloat guMatrix4x4[4][4]; +typedef struct { + GLuint index; + const GLchar *name; +} guAttribBinding; #ifdef __cplusplus extern "C" { @@ -35,6 +39,12 @@ char *guGetProgramLog(GLuint id); GLuint guMakeShaderFromFile(GLenum shaderType, const char *fname); GLuint guMakeShader(GLenum shaderType, const char *source); GLuint guMakeBuffer(GLenum target, GLenum usage, const void *ptr, size_t sz); +GLuint guMakeProgramFromSource(const char *v_shader, const char *f_shader, + guAttribBinding *bindings); +GLuint guMakeProgramFromFiles(const char *v_shader, const char *f_shader, + guAttribBinding *bindings); +GLuint guMakeProgram(GLuint v_shader_id, GLuint f_shader_id, + guAttribBinding *bindings); #ifdef __cplusplus }