Dawn/src/dawnopengl/display/shader/ShaderProgram.cpp

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);
}