1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00
CLK/Outputs/CRT/Internals/Shaders/Shader.cpp

115 lines
2.5 KiB
C++
Raw Normal View History

//
// 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;
namespace {
Shader *bound_shader = nullptr;
}
2016-02-08 00:21:22 +00:00
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);
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);
}
throw (type == GL_VERTEX_SHADER) ? VertexShaderCompilationError : FragmentShaderCompilationError;
2016-02-08 00:21:22 +00:00
}
#endif
return shader;
}
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);
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);
#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);
if(logLength > 0) {
GLchar *log = (GLchar *)malloc((size_t)logLength);
glGetProgramInfoLog(_shader_program, logLength, &logLength, log);
printf("Link log:\n%s\n", log);
free(log);
}
throw ProgramLinkageError;
}
#endif
2016-02-08 00:21:22 +00:00
}
Shader::~Shader()
{
if(bound_shader == this) Shader::unbind();
glDeleteProgram(_shader_program);
2016-02-08 00:21:22 +00:00
}
void Shader::bind()
{
if(bound_shader != this)
{
glUseProgram(_shader_program);
bound_shader = this;
}
}
void Shader::unbind()
{
bound_shader = nullptr;
glUseProgram(0);
2016-02-08 00:21:22 +00:00
}
GLint Shader::get_attrib_location(const GLchar *name)
2016-02-08 00:21:22 +00:00
{
return glGetAttribLocation(_shader_program, name);
}
GLint Shader::get_uniform_location(const GLchar *name)
2016-02-08 00:21:22 +00:00
{
return glGetUniformLocation(_shader_program, name);
}