129 lines
4.4 KiB
C++
129 lines
4.4 KiB
C++
// Copyright (c) 2022 Dominic Masters
|
|
//
|
|
// This software is released under the MIT License.
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
#include "ShaderProgram.hpp"
|
|
|
|
using namespace Dawn;
|
|
|
|
void ShaderProgram::compileShader(
|
|
std::map<std::string, int32_t> attributeLocations,
|
|
std::string vertexShader,
|
|
std::string fragmentShader
|
|
) {
|
|
GLint isSuccess;
|
|
int32_t maxLength;
|
|
char error[1024];
|
|
|
|
// Load the vertex shader first
|
|
this->shaderVertex = glCreateShader(GL_VERTEX_SHADER);
|
|
auto vertShaderC = vertexShader.c_str();
|
|
glShaderSource(this->shaderVertex, 1, &vertShaderC, 0);
|
|
glCompileShader(this->shaderVertex);
|
|
|
|
// Validate
|
|
glGetShaderiv(this->shaderVertex, GL_COMPILE_STATUS, &isSuccess);
|
|
if(!isSuccess) {
|
|
glGetShaderiv(this->shaderVertex, GL_INFO_LOG_LENGTH, &maxLength);
|
|
glGetShaderInfoLog(this->shaderVertex, maxLength, &maxLength, error);
|
|
debugMessage("Error compiling vert shader");
|
|
debugMessage(error);
|
|
throw error;
|
|
}
|
|
|
|
// Now load the Frag shader
|
|
this->shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
|
|
auto fragShaderC = fragmentShader.c_str();
|
|
glShaderSource(this->shaderFrag, 1, &fragShaderC, 0);
|
|
glCompileShader(this->shaderFrag);
|
|
glGetShaderiv(this->shaderFrag, GL_COMPILE_STATUS, &isSuccess);
|
|
if(!isSuccess) {
|
|
glGetShaderiv(this->shaderFrag, GL_INFO_LOG_LENGTH, &maxLength);
|
|
glGetShaderInfoLog(this->shaderFrag, maxLength, &maxLength, error);
|
|
glDeleteShader(this->shaderVertex);
|
|
debugMessage("Error compiling frag shader");
|
|
debugMessage(error);
|
|
throw error;
|
|
}
|
|
|
|
// Now create the shader program.
|
|
this->shaderProgram = glCreateProgram();
|
|
glAttachShader(this->shaderProgram, this->shaderVertex);
|
|
glAttachShader(this->shaderProgram, this->shaderFrag);
|
|
|
|
// Now parse out the variables.
|
|
#if DAWN_OPENGL_HLSL
|
|
auto itAttr = attributeLocations.begin();
|
|
while(itAttr != attributeLocations.end()) {
|
|
this->bindAttributeLocation(itAttr->first, itAttr->second);
|
|
++itAttr;
|
|
}
|
|
#endif
|
|
|
|
//Bind, Verify & Use the shader program
|
|
glLinkProgram(this->shaderProgram);
|
|
glGetProgramiv(this->shaderProgram, GL_LINK_STATUS, &isSuccess);
|
|
if(!isSuccess) {
|
|
glGetProgramiv(this->shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
|
|
glGetProgramInfoLog(this->shaderProgram, maxLength, &maxLength, error);
|
|
glDeleteShader(this->shaderVertex);
|
|
glDeleteShader(this->shaderFrag);
|
|
debugMessage("Error compiling shader program");
|
|
debugMessage(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
void ShaderProgram::bindAttributeLocation(std::string name, int32_t location) {
|
|
if(this->shaderProgram == -1) throw "Shader has not yet been compiled";
|
|
glBindAttribLocation(this->shaderProgram, location, name.c_str());
|
|
}
|
|
|
|
void ShaderProgram::setTexture(shaderparameter_t param, textureslot_t slot) {
|
|
glUniform1i(param, slot);
|
|
}
|
|
|
|
shaderparameter_t ShaderProgram::getParameterByName(std::string name) {
|
|
return glGetUniformLocation(this->shaderProgram, name.c_str());
|
|
}
|
|
|
|
shaderbufferlocation_t ShaderProgram::getBufferLocationByName(std::string name) {
|
|
return glGetUniformBlockIndex(this->shaderProgram, name.c_str());
|
|
}
|
|
|
|
void ShaderProgram::setParameterBuffer(shaderbufferlocation_t location, shaderbufferslot_t slot) {
|
|
glUniformBlockBinding(this->shaderProgram, location, slot);
|
|
}
|
|
|
|
void ShaderProgram::setMatrix(shaderparameter_t uniform, glm::mat4 matrix) {
|
|
glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(matrix));
|
|
}
|
|
|
|
void ShaderProgram::setBoolean(shaderparameter_t uni, bool value) {
|
|
glUniform1i(uni, value);
|
|
}
|
|
|
|
void ShaderProgram::setColor(shaderparameter_t uniform, struct Color color) {
|
|
auto precise = color.precision();
|
|
glUniform4f(uniform, precise.r, precise.g, precise.b, precise.a);
|
|
}
|
|
|
|
void ShaderProgram::setVector3(shaderparameter_t uniform, glm::vec3 vector) {
|
|
glUniform3f(uniform, vector.x, vector.y, vector.z);
|
|
}
|
|
|
|
void ShaderProgram::setFloat(shaderparameter_t param, float_t value) {
|
|
glUniform1f(param, value);
|
|
}
|
|
|
|
void ShaderProgram::bind() {
|
|
if(this->shaderProgram == -1) throw "Shader has not yet been compiled";
|
|
glUseProgram(this->shaderProgram);
|
|
}
|
|
|
|
ShaderProgram::~ShaderProgram() {
|
|
if(this->shaderProgram != -1) glDeleteProgram(this->shaderProgram);
|
|
if(this->shaderVertex != -1) glDeleteShader(this->shaderVertex);
|
|
if(this->shaderFrag != -1) glDeleteShader(this->shaderFrag);
|
|
} |