shader utility functions

This commit is contained in:
Brian 2008-04-09 22:27:36 -06:00
parent f9c8af31c5
commit 90caba3d76
2 changed files with 193 additions and 0 deletions

159
progs/util/shaderutil.c Normal file
View File

@ -0,0 +1,159 @@
/**
* Utilities for OpenGL shading language
*
* Brian Paul
* 9 April 2008
*/
#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;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
return GL_FALSE;
}
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) {
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();
glAttachShader_func(program, fragShader);
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();
}
}
}

34
progs/util/shaderutil.h Normal file
View File

@ -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 */