2025-07-10 21:51:17 +03:30
|
|
|
#include <asset_parser/assets/text.hpp>
|
2025-07-05 11:33:43 +03:30
|
|
|
#include <glad/gl.h>
|
2021-07-05 01:59:18 +04:30
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
2022-03-07 20:01:44 +03:30
|
|
|
#include <glm/matrix.hpp>
|
2025-07-10 21:51:17 +03:30
|
|
|
#include <renderer/gl/shader.hpp>
|
2021-07-05 01:59:18 +04:30
|
|
|
|
2025-07-11 00:05:48 +03:30
|
|
|
namespace lt {
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2025-07-10 21:51:17 +03:30
|
|
|
glShader::glShader(
|
|
|
|
const Ref<Assets::TextAsset> &vertex_asset,
|
|
|
|
const Ref<Assets::TextAsset> &pixel_asset
|
|
|
|
)
|
2025-07-09 21:30:17 +03:30
|
|
|
: m_shader_id(glCreateProgram())
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
2025-07-10 21:51:17 +03:30
|
|
|
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());
|
|
|
|
|
2025-07-09 21:30:17 +03:30
|
|
|
auto vertex_source = std::string {
|
2025-07-12 14:40:10 +03:30
|
|
|
reinterpret_cast<char*>(vertex_blob.data()),
|
|
|
|
reinterpret_cast<char*>(vertex_blob.data()) + vertex_blob.size(), // NOLINT
|
2025-07-09 21:30:17 +03:30
|
|
|
};
|
2022-03-04 22:40:20 +03:30
|
|
|
|
2025-07-09 21:30:17 +03:30
|
|
|
auto pixel_source = std::string {
|
2025-07-12 14:40:10 +03:30
|
|
|
reinterpret_cast<char*>(pixel_blob.data()),
|
|
|
|
reinterpret_cast<char*>(pixel_blob.data()) + pixel_blob.size(), // NOLINT
|
2025-07-09 21:30:17 +03:30
|
|
|
};
|
2022-03-04 22:40:20 +03:30
|
|
|
|
2025-07-09 21:30:17 +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
|
|
|
|
2025-07-09 21:30:17 +03:30
|
|
|
glAttachShader(m_shader_id, vertex_shader);
|
|
|
|
glAttachShader(m_shader_id, pixel_shader);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
glLinkProgram(m_shader_id);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
2025-07-09 21:30:17 +03:30
|
|
|
glDeleteShader(vertex_shader);
|
|
|
|
glDeleteShader(pixel_shader);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
glShader::~glShader()
|
|
|
|
{
|
2025-07-05 14:23:01 +03:30
|
|
|
glDeleteProgram(m_shader_id);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void glShader::bind()
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
2025-07-05 14:23:01 +03:30
|
|
|
glUseProgram(m_shader_id);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void glShader::un_bind()
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
glUseProgram(NULL);
|
|
|
|
}
|
|
|
|
|
2025-07-09 21:30:17 +03:30
|
|
|
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(
|
2025-07-09 21:30:17 +03:30
|
|
|
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)
|
2021-09-13 12:17:26 +04:30
|
|
|
{
|
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);
|
2021-07-01 19:25:46 +04:30
|
|
|
|
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]);
|
2021-09-13 12:17:26 +04:30
|
|
|
|
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 {}",
|
2025-07-09 21:30:17 +03:30
|
|
|
stage == Shader::Stage::vertex ? "Vertex" : "Pixel",
|
2025-07-06 14:02:50 +03:30
|
|
|
errorLog
|
|
|
|
);
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
return NULL;
|
2021-09-13 12:17:26 +04:30
|
|
|
}
|
2022-03-04 22:40:20 +03:30
|
|
|
#define LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
|
|
|
|
#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
|
|
|
|
// info log
|
2021-09-13 12:17:26 +04:30
|
|
|
{
|
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]);
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2025-07-06 16:30:38 +03:30
|
|
|
log_wrn("Shader info: {}", infoLog);
|
2021-08-01 11:57:51 +04:30
|
|
|
}
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
2021-08-01 11:57:51 +04:30
|
|
|
#endif
|
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
return shader;
|
|
|
|
}
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2025-07-11 00:05:48 +03:30
|
|
|
} // namespace lt
|