195 lines
4.9 KiB
C++
195 lines
4.9 KiB
C++
#include "lopenglprogram.h"
|
|
#include <iostream>
|
|
|
|
LOpenGLShader::LOpenGLShader(LOpenGLShader::ShaderType type)
|
|
: shaderType_(type), compiled_(false) {}
|
|
|
|
LOpenGLShader::~LOpenGLShader() {
|
|
if (shaderId_ != 0) {
|
|
glDeleteShader(shaderId_);
|
|
}
|
|
}
|
|
|
|
bool LOpenGLShader::compileShaderFromSource(const char *source) {
|
|
if (!source || compiled_) {
|
|
return false;
|
|
}
|
|
|
|
switch (shaderType_) {
|
|
case Vertex:
|
|
shaderId_ = glCreateShader(GL_VERTEX_SHADER);
|
|
break;
|
|
case Fragment:
|
|
shaderId_ = glCreateShader(GL_FRAGMENT_SHADER);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
glShaderSource(shaderId_, 1, &source, NULL);
|
|
glCompileShader(shaderId_);
|
|
int success = 0;
|
|
glGetShaderiv(shaderId_, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
char infoLog[512];
|
|
glGetShaderInfoLog(shaderId_, 512, NULL, infoLog);
|
|
shaderLog_ = std::string(infoLog);
|
|
return false;
|
|
}
|
|
|
|
compiled_ = true;
|
|
return true;
|
|
}
|
|
|
|
bool LOpenGLShader::compileShaderFromSource(const std::string &source) {
|
|
if (source.empty() || compiled_) {
|
|
return false;
|
|
}
|
|
|
|
switch (shaderType_) {
|
|
case Vertex:
|
|
shaderId_ = glCreateShader(GL_VERTEX_SHADER);
|
|
break;
|
|
case Fragment:
|
|
shaderId_ = glCreateShader(GL_FRAGMENT_SHADER);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
auto source_ch = source.c_str();
|
|
glShaderSource(shaderId_, 1, &source_ch, nullptr);
|
|
glCompileShader(shaderId_);
|
|
int success = 0;
|
|
glGetShaderiv(shaderId_, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
char infoLog[512];
|
|
glGetShaderInfoLog(shaderId_, 512, nullptr, infoLog);
|
|
shaderLog_ = std::string(infoLog);
|
|
return false;
|
|
}
|
|
|
|
compiled_ = true;
|
|
return true;
|
|
}
|
|
|
|
bool LOpenGLShader::compileShaderFromFile(const std::string &path) {
|
|
std::string shaderCode;
|
|
std::fstream shaderFile;
|
|
std::stringstream shaderStream;
|
|
|
|
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
|
|
|
try {
|
|
shaderFile.open(path);
|
|
shaderStream << shaderFile.rdbuf();
|
|
shaderFile.close();
|
|
shaderCode = shaderStream.str();
|
|
} catch (std::ifstream::failure e) {
|
|
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
|
|
}
|
|
|
|
if (shaderCode.empty() || compiled_) {
|
|
return false;
|
|
}
|
|
|
|
switch (shaderType_) {
|
|
case Vertex:
|
|
shaderId_ = glCreateShader(GL_VERTEX_SHADER);
|
|
break;
|
|
case Fragment:
|
|
shaderId_ = glCreateShader(GL_FRAGMENT_SHADER);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
auto source_ch = shaderCode.c_str();
|
|
glShaderSource(shaderId_, 1, &source_ch, NULL);
|
|
glCompileShader(shaderId_);
|
|
int success = 0;
|
|
glGetShaderiv(shaderId_, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
char infoLog[512];
|
|
glGetShaderInfoLog(shaderId_, 512, NULL, infoLog);
|
|
shaderLog_ = std::string(infoLog);
|
|
return false;
|
|
}
|
|
|
|
compiled_ = true;
|
|
return true;
|
|
}
|
|
|
|
LOpenGLProgram::LOpenGLProgram() : linked_(false) {
|
|
Create();
|
|
}
|
|
|
|
LOpenGLProgram::~LOpenGLProgram() {
|
|
glDeleteProgram(programId_);
|
|
}
|
|
|
|
void LOpenGLProgram::Create() { programId_ = glCreateProgram(); }
|
|
|
|
bool LOpenGLProgram::Link() const {
|
|
if (!created_ || linked_ || shaderList_.empty()) {
|
|
return false;
|
|
}
|
|
glLinkProgram(programId_);
|
|
return true;
|
|
}
|
|
|
|
void LOpenGLProgram::Use() const {
|
|
if (!linked_)
|
|
return;
|
|
glUseProgram(programId_);
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, float value) const {
|
|
glUniform1f(glGetUniformLocation(programId_, name.c_str()), value);
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, int value) const {
|
|
glUniform1i(glGetUniformLocation(programId_, name.c_str()), value);
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, bool value) const {
|
|
glUniform1i(glGetUniformLocation(programId_, name.c_str()), static_cast<int>(value));
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, glm::vec3 value) const {
|
|
glUniform3fv(glGetUniformLocation(programId_, name.c_str()), 1, &value[0]);
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, float x, float y, float z) const {
|
|
glUniform3f(glGetUniformLocation(programId_, name.c_str()), x, y, z);
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, glm::mat4 value) const {
|
|
glUniform4fv(glGetUniformLocation(programId_, name.c_str()), 1, &value[0][0]);
|
|
}
|
|
|
|
bool LOpenGLProgram::addShader(std::unique_ptr<LOpenGLShader> shader) {
|
|
if (!shader || !shader->Compiled()) {
|
|
return false;
|
|
}
|
|
if (!created_) {
|
|
return false;
|
|
}
|
|
glAttachShader(programId_, shader->shaderId_);
|
|
shaderList_.push_back(std::move(shader));
|
|
return true;
|
|
}
|
|
|
|
void LOpenGLProgram::setUniformValue(const std::string &name, glm::vec2 value) const {
|
|
glUniform2fv(glGetUniformLocation(programId_, name.c_str()), 1, &value[0]);
|
|
}
|
|
|
|
void LOpenGLProgram::removeShader(GLuint id) {
|
|
for (auto ite = shaderList_.begin(); ite != shaderList_.end(); ++ite) {
|
|
if ((*ite)->shaderId_ == id) {
|
|
glDetachShader(programId_, id);
|
|
shaderList_.erase(ite);
|
|
}
|
|
}
|
|
}
|