aboutsummaryrefslogtreecommitdiff
#include "shaders.h"
#include "../util/util.h"

#include <stdlib.h>
#include <stdbool.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("Some shader failed to compile:\n%s", 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("Shader program failed to link!:\n%s", 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 \"%s\" could not be found!", uniformName);
    else
        return u;

    return 0;
}

GLint Shader_GetAttribLocation ( GLuint programID, const char* attributeName )
{
    GLint attrLocation = glGetAttribLocation(programID, attributeName);
    if(attrLocation < 0)
        Util_FatalError("Attribute \"%s\" could not be found!\n", attributeName);
    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);
}