2025-07-05 13:28:41 +03:30
|
|
|
#include <engine/platform/graphics/opengl/shader.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>
|
2021-07-05 01:59:18 +04:30
|
|
|
|
2021-05-27 19:54:05 +04:30
|
|
|
namespace Light {
|
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
glShader::glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile): m_shader_id(0u)
|
2022-03-04 22:40:20 +03:30
|
|
|
{
|
|
|
|
// create
|
2025-07-05 14:23:01 +03:30
|
|
|
m_shader_id = glCreateProgram();
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
std::string vertexSource(vertexFile.GetData(), vertexFile.GetData() + vertexFile.GetSize());
|
|
|
|
std::string pixelSource(pixelFile.GetData(), pixelFile.GetData() + pixelFile.GetSize());
|
|
|
|
|
|
|
|
unsigned int vertexShader = CompileShader(vertexSource, Shader::Stage::VERTEX);
|
2025-07-05 13:28:41 +03:30
|
|
|
unsigned int pixelShader = CompileShader(pixelSource, Shader::Stage::PIXEL);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// attach shaders
|
2025-07-05 14:23:01 +03:30
|
|
|
glAttachShader(m_shader_id, vertexShader);
|
|
|
|
glAttachShader(m_shader_id, pixelShader);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// link shader program
|
2025-07-05 14:23:01 +03:30
|
|
|
glLinkProgram(m_shader_id);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// delete shaders (free memory)
|
|
|
|
glDeleteShader(vertexShader);
|
|
|
|
glDeleteShader(pixelShader);
|
|
|
|
}
|
|
|
|
|
|
|
|
glShader::~glShader()
|
|
|
|
{
|
2025-07-05 14:23:01 +03:30
|
|
|
glDeleteProgram(m_shader_id);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
void glShader::Bind()
|
|
|
|
{
|
2025-07-05 14:23:01 +03:30
|
|
|
glUseProgram(m_shader_id);
|
2022-03-04 22:40:20 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
void glShader::UnBind()
|
|
|
|
{
|
|
|
|
glUseProgram(NULL);
|
|
|
|
}
|
|
|
|
|
2025-07-05 11:33:43 +03:30
|
|
|
// shaderc::SpvCompilationResult glShader::CompileGLSL(BasicFileHandle file, Shader::Stage stage)
|
|
|
|
// {
|
|
|
|
// // compile options
|
|
|
|
// shaderc::CompileOptions options;
|
|
|
|
// options.SetTargetEnvironment(shaderc_target_env_opengl, shaderc_env_version_opengl_4_5);
|
|
|
|
// options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
|
|
|
//
|
|
|
|
// // compile
|
|
|
|
// shaderc::Compiler compiler;
|
2025-07-05 13:28:41 +03:30
|
|
|
// shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(reinterpret_cast<const
|
|
|
|
// char*>(file.GetData()), stage == Shader::Stage::VERTEX ?
|
|
|
|
// shaderc_shader_kind::shaderc_vertex_shader : shaderc_shader_kind::shaderc_fragment_shader,
|
|
|
|
// file.GetName().c_str(), options);
|
2025-07-05 11:33:43 +03:30
|
|
|
//
|
|
|
|
// // log error
|
|
|
|
// if (result.GetCompilationStatus() != shaderc_compilation_status_success)
|
|
|
|
// {
|
2025-07-05 13:28:41 +03:30
|
|
|
// LOG(err, "Failed to compile {} shader at {}...", stage == Shader::Stage::VERTEX ? "vertex" :
|
|
|
|
// "pixel", file.GetPath()); LOG(err, " {}", result.GetErrorMessage());
|
2025-07-05 11:33:43 +03:30
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return result;
|
|
|
|
// }
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
unsigned int glShader::CompileShader(std::string source, Shader::Stage stage)
|
|
|
|
{
|
|
|
|
// &(address of) needs an lvalue
|
2025-07-05 13:28:41 +03:30
|
|
|
const char *lvalue_source = source.c_str();
|
|
|
|
unsigned int shader = glCreateShader(
|
|
|
|
stage == Shader::Stage::VERTEX ? GL_VERTEX_SHADER :
|
|
|
|
stage == Shader::Stage::PIXEL ? GL_FRAGMENT_SHADER :
|
|
|
|
stage == Shader::Stage::GEOMETRY ? GL_GEOMETRY_SHADER :
|
|
|
|
NULL
|
|
|
|
);
|
2022-03-04 22:40:20 +03:30
|
|
|
|
|
|
|
// compile
|
|
|
|
glShaderSource(shader, 1, &lvalue_source, NULL);
|
|
|
|
glCompileShader(shader);
|
|
|
|
|
|
|
|
// check
|
|
|
|
int isCompiled = 0;
|
|
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
|
|
|
|
if (isCompiled == GL_FALSE)
|
2021-09-13 12:17:26 +04:30
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
int logLength = 0;
|
|
|
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2025-07-05 13:28:41 +03:30
|
|
|
char *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-05 13:28:41 +03:30
|
|
|
LOG(err,
|
|
|
|
"glShader::glShader: failed to compile {} shader:\n {}",
|
|
|
|
stage == Shader::Stage::VERTEX ? "Vertex" : "Pixel",
|
|
|
|
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
|
|
|
{
|
2022-03-04 22:40:20 +03:30
|
|
|
int logLength = 0;
|
|
|
|
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
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
LOG(warn, 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
|
|
|
|
2022-03-04 22:40:20 +03:30
|
|
|
} // namespace Light
|