light/modules/renderer/private/gl/shader.cpp
light7734 cd886aa8c9
Some checks reported errors
continuous-integration/drone/push Build was killed
refactor: flatten directory structure
2025-07-20 04:46:15 +03:30

112 lines
3 KiB
C++

#include <asset_parser/assets/text.hpp>
#include <glad/gl.h>
#include <renderer/gl/shader.hpp>
namespace lt {
glShader::glShader(
const Ref<Assets::TextAsset> &vertex_asset,
const Ref<Assets::TextAsset> &pixel_asset
)
: m_shader_id(glCreateProgram())
{
auto vertex_blob_metadata = vertex_asset->get_blob_metadata(Assets::BlobMetadata::Tag::text);
auto pixel_blob_metadata = pixel_asset->get_blob_metadata(Assets::BlobMetadata::Tag::text);
auto vertex_blob = Assets::Blob(vertex_blob_metadata.uncompressed_size);
auto pixel_blob = Assets::Blob(pixel_blob_metadata.uncompressed_size);
vertex_asset->unpack_blob(vertex_blob_metadata.tag, vertex_blob.data(), vertex_blob.size());
pixel_asset->unpack_blob(pixel_blob_metadata.tag, pixel_blob.data(), pixel_blob.size());
auto vertex_source = std::string {
reinterpret_cast<char *>(vertex_blob.data()),
reinterpret_cast<char *>(vertex_blob.data()) + vertex_blob.size(), // NOLINT
};
auto pixel_source = std::string {
reinterpret_cast<char *>(pixel_blob.data()),
reinterpret_cast<char *>(pixel_blob.data()) + pixel_blob.size(), // NOLINT
};
const auto vertex_shader = compile_shader(vertex_source, Shader::Stage::vertex);
const auto pixel_shader = compile_shader(pixel_source, Shader::Stage::pixel);
glAttachShader(m_shader_id, vertex_shader);
glAttachShader(m_shader_id, pixel_shader);
glLinkProgram(m_shader_id);
glDeleteShader(vertex_shader);
glDeleteShader(pixel_shader);
}
glShader::~glShader()
{
glDeleteProgram(m_shader_id);
}
void glShader::bind()
{
glUseProgram(m_shader_id);
}
void glShader::un_bind()
{
glUseProgram({});
}
auto glShader::compile_shader(const std::string &source, Shader::Stage stage) -> unsigned int
{
// &(address of) needs an lvalue
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 :
0
);
// compile
glShaderSource(shader, 1, &lvalue_source, nullptr);
glCompileShader(shader);
// check
auto isCompiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
auto logLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
auto *errorLog = (char *)alloca(logLength);
glGetShaderInfoLog(shader, logLength, &logLength, &errorLog[0]);
log_err(
"glShader::glShader: failed to compile {} shader:\n {}",
stage == Shader::Stage::vertex ? "Vertex" : "Pixel",
errorLog
);
return {};
}
#define LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
// info log
{
auto logLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength)
{
char *infoLog = (char *)alloca(logLength);
glGetShaderInfoLog(shader, logLength, &logLength, &infoLog[0]);
log_wrn("Shader info: {}", infoLog);
}
}
#endif
return shader;
}
} // namespace lt