light/modules/renderer/src/gl/shader.cpp

103 lines
2.4 KiB
C++
Raw Normal View History

#include <renderer/gl/shader.hpp>
#include <glad/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/matrix.hpp>
2021-05-27 19:54:05 +04:30
namespace Light {
glShader::glShader(Assets::Blob vertex_blob, Assets::Blob pixel_blob)
: m_shader_id(glCreateProgram())
2022-03-04 22:40:20 +03:30
{
auto vertex_source = std::string {
vertex_blob.data(),
vertex_blob.data() + vertex_blob.size(), // NOLINT
};
2022-03-04 22:40:20 +03:30
auto pixel_source = std::string {
pixel_blob.data(),
pixel_blob.data() + pixel_blob.size(), // NOLINT
};
2022-03-04 22:40:20 +03:30
const auto vertex_shader = compile_shader(vertex_source, Shader::Stage::vertex);
const auto pixel_shader = compile_shader(pixel_source, Shader::Stage::pixel);
2022-03-04 22:40:20 +03:30
glAttachShader(m_shader_id, vertex_shader);
glAttachShader(m_shader_id, pixel_shader);
2022-03-04 22:40:20 +03:30
glLinkProgram(m_shader_id);
2022-03-04 22:40:20 +03:30
glDeleteShader(vertex_shader);
glDeleteShader(pixel_shader);
2022-03-04 22:40:20 +03:30
}
glShader::~glShader()
{
glDeleteProgram(m_shader_id);
2022-03-04 22:40:20 +03:30
}
void glShader::bind()
2022-03-04 22:40:20 +03:30
{
glUseProgram(m_shader_id);
2022-03-04 22:40:20 +03:30
}
void glShader::un_bind()
2022-03-04 22:40:20 +03:30
{
glUseProgram(NULL);
}
auto glShader::compile_shader(const std::string &source, Shader::Stage stage) -> unsigned int
2022-03-04 22:40:20 +03:30
{
// &(address of) needs an lvalue
2025-07-06 14:02:50 +03:30
const auto *lvalue_source = source.c_str();
auto shader = glCreateShader(
stage == Shader::Stage::vertex ? GL_VERTEX_SHADER :
stage == Shader::Stage::pixel ? GL_FRAGMENT_SHADER :
stage == Shader::Stage::geometry ? GL_GEOMETRY_SHADER :
2025-07-05 13:28:41 +03:30
NULL
);
2022-03-04 22:40:20 +03:30
// compile
2025-07-06 16:52:50 +03:30
glShaderSource(shader, 1, &lvalue_source, nullptr);
2022-03-04 22:40:20 +03:30
glCompileShader(shader);
// check
2025-07-06 14:02:50 +03:30
auto isCompiled = 0;
2022-03-04 22:40:20 +03:30
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
2025-07-06 14:02:50 +03:30
auto logLength = 0;
2022-03-04 22:40:20 +03:30
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
2025-07-06 14:02:50 +03:30
auto *errorLog = (char *)alloca(logLength);
2022-03-04 22:40:20 +03:30
glGetShaderInfoLog(shader, logLength, &logLength, &errorLog[0]);
2025-07-06 16:30:38 +03:30
log_err(
2025-07-05 13:28:41 +03:30
"glShader::glShader: failed to compile {} shader:\n {}",
stage == Shader::Stage::vertex ? "Vertex" : "Pixel",
2025-07-06 14:02:50 +03:30
errorLog
);
2022-03-04 22:40:20 +03:30
return NULL;
}
2022-03-04 22:40:20 +03:30
#define LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
// info log
{
2025-07-06 14:02:50 +03:30
auto logLength = 0;
2022-03-04 22:40:20 +03:30
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength)
2021-05-27 19:54:05 +04:30
{
2025-07-05 13:28:41 +03:30
char *infoLog = (char *)alloca(logLength);
2022-03-04 22:40:20 +03:30
glGetShaderInfoLog(shader, logLength, &logLength, &infoLog[0]);
2025-07-06 16:30:38 +03:30
log_wrn("Shader info: {}", infoLog);
}
2022-03-04 22:40:20 +03:30
}
#endif
2022-03-04 22:40:20 +03:30
return shader;
}
2021-05-27 19:54:05 +04:30
2022-03-04 22:40:20 +03:30
} // namespace Light