#include "shaders.h"
#include "../util/util.h"
#include <stdlib.h>
static void CompileShader(const char* source, GLuint shaderID)
{
glShaderSource(shaderID, 1, &source, 0);
glCompileShader(shaderID);
GLint error;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &error);
if(error != GL_TRUE)
{
GLint logLenth;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLenth);
GLchar buffer[logLenth];
glGetShaderInfoLog(shaderID, logLenth, &logLenth, buffer);
glDeleteShader(shaderID);
Util_FatalError(buffer);
}
}
GLuint Shader_CompileShaders(const char* vertexShader, const char* fragmentShader)
{
char* vertexShaderSource = Util_LoadFile(vertexShader);
char* fragmentShaderSource = Util_LoadFile(fragmentShader);
GLuint vs = 0, fs = 0, program;
vs = glCreateShader(GL_VERTEX_SHADER);
fs = glCreateShader(GL_FRAGMENT_SHADER);
if(vs == 0 || fs == 0)
Util_FatalError("Shaders could not be created\n");
program = glCreateProgram();
CompileShader(vertexShaderSource, vs);
CompileShader(fragmentShaderSource, fs);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
GLint error;
glGetProgramiv(program, GL_LINK_STATUS, &error);
if(error != GL_TRUE)
{
GLint logLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
GLchar buffer[logLength];
glGetProgramInfoLog(program, logLength, &logLength, buffer);
glDeleteProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
Util_FatalError(buffer);
}
glDetachShader(program, vs);
glDetachShader(program, fs);
glDeleteShader(vs);
glDeleteShader(fs);
free(vertexShaderSource);
free(fragmentShaderSource);
return program;
}
GLint Shader_GetUniformLocation( GLuint programID, const char* uniformName )
{
GLint u = glGetUniformLocation(programID, uniformName);
if(u == GL_INVALID_INDEX)
Util_FatalError("Uniform variable could not be found!");
else
return u;
return 0;
}
GLint Shader_GetAttribLocation ( GLuint programID, const char* attributeName )
{
GLint attrLocation = glGetAttribLocation(programID, attributeName);
if(attrLocation < 0)
Util_FatalError("Attribute could not be found\n");
return attrLocation;
}
void Shader_Destroy(GLuint programID)
{
glUseProgram(0);
glDeleteProgram(programID);
}
void Shader_SetUniformMat4( GLuint programID, const char* name, const float *matrix )
{
GLint location = Shader_GetUniformLocation(programID, name);
glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
}
void Shader_SetUniformFloat( GLuint programID, const char* name, const float val )
{
GLint location = Shader_GetUniformLocation(programID, name);
glUniform1f(location, val);
}
void Shader_SetUniformVec2( GLuint programID, const char* name, const float vec[2] )
{
GLint location = Shader_GetUniformLocation(programID, name);
glUniform2fv(location, 1, vec);
}
void Shader_SetUniformVec3( GLuint programID, const char* name, const float vec[3] )
{
GLint location = Shader_GetUniformLocation(programID, name);
glUniform3fv(location, 1, vec);
}
void Shader_SetUniformVec4( GLuint programID, const char* name, const float vec[4] )
{
GLint location = Shader_GetUniformLocation(programID, name);
glUniform4fv(location, 1, vec);
}
void Shader_SetUniformInt( GLuint programID, const char* name, const int val )
{
GLint location = Shader_GetUniformLocation(programID, name);
glUniform1i(location, val);
}