diff options
Diffstat (limited to 'progs/util')
-rw-r--r-- | progs/util/SConscript | 15 | ||||
-rw-r--r-- | progs/util/extfuncs.h | 15 | ||||
-rw-r--r-- | progs/util/shaderutil.c | 168 | ||||
-rw-r--r-- | progs/util/shaderutil.h | 34 |
4 files changed, 232 insertions, 0 deletions
diff --git a/progs/util/SConscript b/progs/util/SConscript new file mode 100644 index 0000000000..8ad2466291 --- /dev/null +++ b/progs/util/SConscript @@ -0,0 +1,15 @@ +Import('env') + +env = env.Clone() + +util = env.StaticLibrary( + target = ['util'], + source = [ + 'readtex.c', + 'trackball.c', + 'showbuffer.c', + 'shaderutil.c', + ], +) + +Export('util') diff --git a/progs/util/extfuncs.h b/progs/util/extfuncs.h index cf6b29d0e3..070414e294 100644 --- a/progs/util/extfuncs.h +++ b/progs/util/extfuncs.h @@ -46,6 +46,13 @@ static PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_func = NULL; static PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_func = NULL; static PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_func = NULL; static PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_func = NULL; +static PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_func = NULL; +static PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_func = NULL; +static PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_func = NULL; +static PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_func = NULL; +static PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_func = NULL; +static PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_func = NULL; +static PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_func = NULL; /* OpenGL 2.1 */ static PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv_func = NULL; @@ -126,6 +133,14 @@ GetExtensionFuncs(void) glVertexAttrib2f_func = (PFNGLVERTEXATTRIB2FPROC) glutGetProcAddress("glVertexAttrib2f"); glVertexAttrib3f_func = (PFNGLVERTEXATTRIB3FPROC) glutGetProcAddress("glVertexAttrib3f"); glVertexAttrib4f_func = (PFNGLVERTEXATTRIB4FPROC) glutGetProcAddress("glVertexAttrib4f"); + glVertexAttrib1fv_func = (PFNGLVERTEXATTRIB1FVPROC) glutGetProcAddress("glVertexAttrib1fv"); + glVertexAttrib2fv_func = (PFNGLVERTEXATTRIB2FVPROC) glutGetProcAddress("glVertexAttrib2fv"); + glVertexAttrib3fv_func = (PFNGLVERTEXATTRIB3FVPROC) glutGetProcAddress("glVertexAttrib3fv"); + glVertexAttrib4fv_func = (PFNGLVERTEXATTRIB4FVPROC) glutGetProcAddress("glVertexAttrib4fv"); + + glVertexAttribPointer_func = (PFNGLVERTEXATTRIBPOINTERPROC) glutGetProcAddress("glVertexAttribPointer"); + glEnableVertexAttribArray_func = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress("glEnableVertexAttribArray"); + glDisableVertexAttribArray_func = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress("glDisableVertexAttribArray"); /* OpenGL 2.1 */ glUniformMatrix2x3fv_func = (PFNGLUNIFORMMATRIX2X3FVPROC) glutGetProcAddress("glUniformMatrix2x3fv"); diff --git a/progs/util/shaderutil.c b/progs/util/shaderutil.c new file mode 100644 index 0000000000..2f1c4e38b3 --- /dev/null +++ b/progs/util/shaderutil.c @@ -0,0 +1,168 @@ +/** + * Utilities for OpenGL shading language + * + * Brian Paul + * 9 April 2008 + */ + + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <GL/glut.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static void +Init(void) +{ + static GLboolean firstCall = GL_TRUE; + if (firstCall) { + GetExtensionFuncs(); + firstCall = GL_FALSE; + } +} + + +GLboolean +ShadersSupported(void) +{ + const char *version = (const char *) glGetString(GL_VERSION); + if (version[0] == '2' && version[1] == '.') { + return GL_TRUE; + } + else if (glutExtensionSupported("GL_ARB_vertex_shader") + && glutExtensionSupported("GL_ARB_fragment_shader") + && glutExtensionSupported("GL_ARB_shader_objects")) { + fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x. This may not work.\n"); + return GL_TRUE; + } + return GL_TRUE; +} + + +GLuint +CompileShaderText(GLenum shaderType, const char *text) +{ + GLuint shader; + GLint stat; + + Init(); + + shader = glCreateShader_func(shaderType); + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + glCompileShader_func(shader); + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "Error: problem compiling shader: %s\n", log); + exit(1); + } + else { + /*printf("Shader compiled OK\n");*/ + } + return shader; +} + + +/** + * Read a shader from a file. + */ +GLuint +CompileShaderFile(GLenum shaderType, const char *filename) +{ + const int max = 100*1000; + int n; + char *buffer = (char*) malloc(max); + GLuint shader; + + FILE *f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "Unable to open shader file %s\n", filename); + return 0; + } + + n = fread(buffer, 1, max, f); + /*printf("read %d bytes from shader file %s\n", n, filename);*/ + if (n > 0) { + buffer[n] = 0; + shader = CompileShaderText(shaderType, buffer); + } + else { + return 0; + } + + fclose(f); + free(buffer); + + return shader; +} + + +GLuint +LinkShaders(GLuint vertShader, GLuint fragShader) +{ + GLuint program = glCreateProgram_func(); + + assert(vertShader || fragShader); + + if (fragShader) + glAttachShader_func(program, fragShader); + if (vertShader) + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + + /* check link */ + { + GLint stat; + glGetProgramiv_func(program, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(program, 1000, &len, log); + fprintf(stderr, "Shader link error:\n%s\n", log); + return 0; + } + } + + return program; +} + + +void +InitUniforms(GLuint program, struct uniform_info uniforms[]) +{ + GLuint i; + + for (i = 0; uniforms[i].name; i++) { + uniforms[i].location + = glGetUniformLocation_func(program, uniforms[i].name); + + printf("Uniform %s location: %d\n", uniforms[i].name, + uniforms[i].location); + + switch (uniforms[i].size) { + case 1: + if (uniforms[i].type == GL_INT) + glUniform1i_func(uniforms[i].location, + (GLint) uniforms[i].value[0]); + else + glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + case 2: + glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + case 3: + glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + case 4: + glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + default: + abort(); + } + } +} diff --git a/progs/util/shaderutil.h b/progs/util/shaderutil.h new file mode 100644 index 0000000000..cfb8c1f3b0 --- /dev/null +++ b/progs/util/shaderutil.h @@ -0,0 +1,34 @@ +#ifndef SHADER_UTIL_H +#define SHADER_UTIL_H + + + +struct uniform_info +{ + const char *name; + GLuint size; + GLenum type; /**< GL_FLOAT or GL_INT */ + GLfloat value[4]; + GLint location; /**< filled in by InitUniforms() */ +}; + +#define END_OF_UNIFORMS { NULL, 0, GL_NONE, { 0, 0, 0, 0 }, -1 } + + +extern GLboolean +ShadersSupported(void); + +extern GLuint +CompileShaderText(GLenum shaderType, const char *text); + +extern GLuint +CompileShaderFile(GLenum shaderType, const char *filename); + +extern GLuint +LinkShaders(GLuint vertShader, GLuint fragShader); + +extern void +InitUniforms(GLuint program, struct uniform_info uniforms[]); + + +#endif /* SHADER_UTIL_H */ |