2016-02-07 22:32:38 +00:00
|
|
|
//
|
|
|
|
// Shader.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 07/02/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "Shader.hpp"
|
2016-02-08 00:21:22 +00:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
using namespace OpenGL;
|
|
|
|
|
|
|
|
GLuint Shader::compile_shader(const char *source, GLenum type)
|
|
|
|
{
|
|
|
|
GLuint shader = glCreateShader(type);
|
|
|
|
glShaderSource(shader, 1, &source, NULL);
|
|
|
|
glCompileShader(shader);
|
|
|
|
|
|
|
|
#if defined(DEBUG)
|
|
|
|
GLint isCompiled = 0;
|
|
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
|
|
|
|
if(isCompiled == GL_FALSE)
|
|
|
|
{
|
|
|
|
GLint logLength;
|
|
|
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
2016-04-19 12:05:43 +00:00
|
|
|
if(logLength > 0) {
|
2016-02-08 00:21:22 +00:00
|
|
|
GLchar *log = (GLchar *)malloc((size_t)logLength);
|
|
|
|
glGetShaderInfoLog(shader, logLength, &logLength, log);
|
|
|
|
printf("Compile log:\n%s\n", log);
|
|
|
|
free(log);
|
|
|
|
}
|
2016-04-19 12:05:43 +00:00
|
|
|
|
|
|
|
throw (type == GL_VERTEX_SHADER) ? VertexShaderCompilationError : FragmentShaderCompilationError;
|
2016-02-08 00:21:22 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return shader;
|
|
|
|
}
|
|
|
|
|
2016-04-19 11:23:15 +00:00
|
|
|
Shader::Shader(const char *vertex_shader, const char *fragment_shader, const AttributeBinding *attribute_bindings)
|
2016-02-08 00:21:22 +00:00
|
|
|
{
|
|
|
|
_shader_program = glCreateProgram();
|
|
|
|
GLuint vertex = compile_shader(vertex_shader, GL_VERTEX_SHADER);
|
|
|
|
GLuint fragment = compile_shader(fragment_shader, GL_FRAGMENT_SHADER);
|
|
|
|
|
|
|
|
glAttachShader(_shader_program, vertex);
|
|
|
|
glAttachShader(_shader_program, fragment);
|
2016-04-19 11:23:15 +00:00
|
|
|
|
|
|
|
if(attribute_bindings)
|
|
|
|
{
|
|
|
|
while(attribute_bindings->name)
|
|
|
|
{
|
|
|
|
glBindAttribLocation(_shader_program, attribute_bindings->index, attribute_bindings->name);
|
|
|
|
attribute_bindings++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-08 00:21:22 +00:00
|
|
|
glLinkProgram(_shader_program);
|
2016-04-19 01:32:48 +00:00
|
|
|
|
|
|
|
#if defined(DEBUG)
|
|
|
|
GLint didLink = 0;
|
|
|
|
glGetProgramiv(_shader_program, GL_LINK_STATUS, &didLink);
|
|
|
|
if(didLink == GL_FALSE)
|
|
|
|
{
|
|
|
|
GLint logLength;
|
|
|
|
glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &logLength);
|
2016-04-25 02:32:24 +00:00
|
|
|
if(logLength > 0) {
|
2016-04-19 01:32:48 +00:00
|
|
|
GLchar *log = (GLchar *)malloc((size_t)logLength);
|
|
|
|
glGetProgramInfoLog(_shader_program, logLength, &logLength, log);
|
|
|
|
printf("Link log:\n%s\n", log);
|
|
|
|
free(log);
|
|
|
|
}
|
2016-04-19 12:05:43 +00:00
|
|
|
throw ProgramLinkageError;
|
2016-04-19 01:32:48 +00:00
|
|
|
}
|
|
|
|
#endif
|
2016-02-08 00:21:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Shader::~Shader()
|
|
|
|
{
|
2016-04-25 00:34:25 +00:00
|
|
|
glDeleteProgram(_shader_program);
|
2016-02-08 00:21:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Shader::bind()
|
|
|
|
{
|
|
|
|
glUseProgram(_shader_program);
|
|
|
|
}
|
|
|
|
|
2016-04-19 11:23:15 +00:00
|
|
|
GLint Shader::get_attrib_location(const GLchar *name)
|
2016-02-08 00:21:22 +00:00
|
|
|
{
|
|
|
|
return glGetAttribLocation(_shader_program, name);
|
|
|
|
}
|
|
|
|
|
2016-04-19 11:23:15 +00:00
|
|
|
GLint Shader::get_uniform_location(const GLchar *name)
|
2016-02-08 00:21:22 +00:00
|
|
|
{
|
|
|
|
return glGetUniformLocation(_shader_program, name);
|
|
|
|
}
|