111 lines
3.3 KiB
C++
111 lines
3.3 KiB
C++
#include "MetaCoreRender/MetaCoreShaderProgram.h"
|
|
|
|
#include <glad/glad.h>
|
|
|
|
#include <vector>
|
|
|
|
namespace MetaCore {
|
|
|
|
namespace {
|
|
|
|
bool MetaCoreCompileShader(unsigned int shaderHandle, const std::string& source, std::string& outError) {
|
|
const char* rawSource = source.c_str();
|
|
glShaderSource(shaderHandle, 1, &rawSource, nullptr);
|
|
glCompileShader(shaderHandle);
|
|
|
|
int compileStatus = 0;
|
|
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileStatus);
|
|
if (compileStatus == GL_TRUE) {
|
|
return true;
|
|
}
|
|
|
|
int logLength = 0;
|
|
glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &logLength);
|
|
std::vector<char> logBuffer(static_cast<std::size_t>((logLength > 1) ? logLength : 1), '\0');
|
|
glGetShaderInfoLog(shaderHandle, logLength, nullptr, logBuffer.data());
|
|
outError.assign(logBuffer.data());
|
|
return false;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
MetaCoreShaderProgram::~MetaCoreShaderProgram() {
|
|
Shutdown();
|
|
}
|
|
|
|
bool MetaCoreShaderProgram::BuildFromSource(const std::string& vertexSource, const std::string& fragmentSource, std::string& outError) {
|
|
Shutdown();
|
|
|
|
const unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
const unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
if (!MetaCoreCompileShader(vertexShader, vertexSource, outError)) {
|
|
glDeleteShader(vertexShader);
|
|
glDeleteShader(fragmentShader);
|
|
return false;
|
|
}
|
|
|
|
if (!MetaCoreCompileShader(fragmentShader, fragmentSource, outError)) {
|
|
glDeleteShader(vertexShader);
|
|
glDeleteShader(fragmentShader);
|
|
return false;
|
|
}
|
|
|
|
ProgramHandle_ = glCreateProgram();
|
|
glAttachShader(ProgramHandle_, vertexShader);
|
|
glAttachShader(ProgramHandle_, fragmentShader);
|
|
glLinkProgram(ProgramHandle_);
|
|
|
|
int linkStatus = 0;
|
|
glGetProgramiv(ProgramHandle_, GL_LINK_STATUS, &linkStatus);
|
|
|
|
glDeleteShader(vertexShader);
|
|
glDeleteShader(fragmentShader);
|
|
|
|
if (linkStatus == GL_TRUE) {
|
|
return true;
|
|
}
|
|
|
|
int logLength = 0;
|
|
glGetProgramiv(ProgramHandle_, GL_INFO_LOG_LENGTH, &logLength);
|
|
std::vector<char> logBuffer(static_cast<std::size_t>((logLength > 1) ? logLength : 1), '\0');
|
|
glGetProgramInfoLog(ProgramHandle_, logLength, nullptr, logBuffer.data());
|
|
outError.assign(logBuffer.data());
|
|
|
|
glDeleteProgram(ProgramHandle_);
|
|
ProgramHandle_ = 0;
|
|
return false;
|
|
}
|
|
|
|
void MetaCoreShaderProgram::Shutdown() {
|
|
if (ProgramHandle_ != 0) {
|
|
glDeleteProgram(ProgramHandle_);
|
|
ProgramHandle_ = 0;
|
|
}
|
|
}
|
|
|
|
void MetaCoreShaderProgram::Bind() const {
|
|
glUseProgram(ProgramHandle_);
|
|
}
|
|
|
|
unsigned int MetaCoreShaderProgram::GetNativeHandle() const {
|
|
return ProgramHandle_;
|
|
}
|
|
|
|
void MetaCoreShaderProgram::SetMatrix4(const char* name, const glm::mat4& value) const {
|
|
const int location = glGetUniformLocation(ProgramHandle_, name);
|
|
glUniformMatrix4fv(location, 1, GL_FALSE, &value[0][0]);
|
|
}
|
|
|
|
void MetaCoreShaderProgram::SetVector3(const char* name, const glm::vec3& value) const {
|
|
const int location = glGetUniformLocation(ProgramHandle_, name);
|
|
glUniform3fv(location, 1, &value[0]);
|
|
}
|
|
|
|
void MetaCoreShaderProgram::SetFloat(const char* name, float value) const {
|
|
const int location = glGetUniformLocation(ProgramHandle_, name);
|
|
glUniform1f(location, value);
|
|
}
|
|
|
|
} // namespace MetaCore
|