Files
demo/src/shader.cpp
T
2022-04-24 09:00:55 +03:00

183 lines
5.8 KiB
C++

#include "shader.h"
#include <iostream>
BEGIN_NAMESPACE
void check_compile_error(GLuint shader_id) {
GLint isCompiled = 0;
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &isCompiled);
if (!isCompiled) {
GLint maxLength = 0;
glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
char errorLog[maxLength];
glGetShaderInfoLog(shader_id, maxLength, &maxLength, &errorLog[0]);
LOG(ERROR) << "Shader compile error: " << "(id: " << shader_id << ", code: " << isCompiled << ", bytes: "
<< maxLength << ") - " << std::string(errorLog, maxLength);
//Provide the infolog in whatever manor you deem best.
//Exit with failure.
glDeleteShader(shader_id); //Don't leak the shader.
} else {
LOG(INFO) << "Shader " << shader_id << " successfully compiled";
}
}
void check_link_error(GLuint program_id) {
GLint is_linked = 0;
glGetShaderiv(program_id, GL_LINK_STATUS, &is_linked);
if (!is_linked) {
GLint maxLength = 0;
glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
char errorLog[maxLength];
glGetShaderInfoLog(program_id, maxLength, &maxLength, &errorLog[0]);
LOG(ERROR) << "Shader program link error: " << "(id: " << program_id << ", code: " << is_linked << ", bytes: "
<< maxLength << ") - " << std::string(errorLog, maxLength);
//Provide the info log in whatever manner you deem best.
//Exit with failure.
glDeleteShader(program_id); //Don't leak the program shader.
} else {
LOG(INFO) << "Shader program " << program_id << " successfully linked";
}
}
shader::shader(const char *vs_content, const char *ps_content)
: shader_ids{0, 0},
program_id{0} {
shader_ids[0] = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader_ids[0], 1, &vs_content, NULL);
glCompileShader(shader_ids[0]);
int success;
char infoLog[512];
glGetShaderiv(shader_ids[0], GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(shader_ids[0], 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
shader_ids[1] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(shader_ids[1], 1, &ps_content, NULL);
glCompileShader(shader_ids[1]);
glGetShaderiv(shader_ids[1], GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(shader_ids[1], 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
program_id = glCreateProgram();
glAttachShader(program_id, shader_ids[0]);
glAttachShader(program_id, shader_ids[1]);
glBindAttribLocation(program_id, 0, "position");
glBindAttribLocation(program_id, 1, "normal");
glBindAttribLocation(program_id, 2, "texCoords");
glLinkProgram(program_id);
glGetProgramiv(program_id, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program_id, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glUseProgram(program_id);
// glDeleteShader(shader_ids[0]);
// glDeleteShader(shader_ids[1]);
// shader_ids[0] = glCreateShader(GL_VERTEX_SHADER);
// glShaderSource(shader_ids[0], 1, &vs_content, nullptr);
// glCompileShader(shader_ids[0]);
// check_compile_error(shader_ids[0]);
//
// shader_ids[1] = glCreateShader(GL_FRAGMENT_SHADER);
// glShaderSource(shader_ids[1], 1, &ps_content, nullptr);
// glCompileShader(shader_ids[1]);
// check_compile_error(shader_ids[1]);
//
// program_id = glCreateProgram();
// glAttachShader(program_id, shader_ids[0]);
// glAttachShader(program_id, shader_ids[1]);
// TODO Adrian: these should come from an external enumeration
// glBindAttribLocation(program_id, 0, "position");
// glBindAttribLocation(program_id, 1, "normal");
// glBindAttribLocation(program_id, 2, "texCoords");
// glLinkProgram(program_id);
// check_link_error(program_id);
// glUseProgram(program_id);
}
shader::~shader() {
glDetachShader(program_id, shader_ids[0]);
glDetachShader(program_id, shader_ids[1]);
glDeleteShader(shader_ids[0]);
glDeleteShader(shader_ids[1]);
glDeleteProgram(program_id);
}
void shader::use() const {
glUseProgram(program_id);
}
void shader::unuse() const {
glUseProgram(0);
}
int shader::getUniform(const char *uniformName) {
if (uniform_cache.count(uniformName) == 0) {
uniform_cache[uniformName] = glGetUniformLocation(program_id, uniformName);
}
return uniform_cache[uniformName];
}
void shader::setMatrix3Uniform(float *matrix, const char *uniformName) {
GLint location = getUniform(uniformName);
if (location != -1)
glUniformMatrix3fv(location, 1, false, matrix);
}
void shader::setMatrix4Uniform(float *matrix, const char *uniformName) {
GLint location = getUniform(uniformName);
if (location != -1)
glUniformMatrix4fv(location, 1, false, matrix);
}
void shader::setVec3Uniform(float *value, const char *uniformName) {
GLint location = getUniform(uniformName);
if (location != -1)
glUniform3fv(location, 1, value);
}
void shader::setVec4Uniform(float *value, const char *uniformName) {
GLint location = getUniform(uniformName);
if (location != -1)
glUniform4fv(location, 1, value);
}
void shader::setIntUniform(int value, const char *uniformName) {
GLint location = getUniform(uniformName);
if (location != -1)
glUniform1i(location, value);
}
void shader::setFloatUniform(float value, const char *uniformName) {
GLint location = getUniform(uniformName);
if (location != -1)
glUniform1f(location, value);
}
END_NAMESPACE