2021-05-27 19:54:05 +04:30
|
|
|
#include "ltpch.h"
|
|
|
|
#include "glShader.h"
|
|
|
|
|
2021-05-30 16:45:54 +04:30
|
|
|
#include <glad/glad.h>
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-07-05 01:59:18 +04:30
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <glm/matrix.hpp>
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
|
2021-05-27 19:54:05 +04:30
|
|
|
namespace Light {
|
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
glShader::glShader(const std::vector<uint8_t>& vertexBlob, const std::vector<uint8_t>& pixelBlob, const std::string& vertexFileName, const std::string& pixelFileName)
|
2021-07-29 17:12:13 +04:30
|
|
|
: m_ShaderID(NULL)
|
2021-05-27 19:54:05 +04:30
|
|
|
{
|
2021-09-13 12:17:26 +04:30
|
|
|
// create
|
2021-05-27 19:54:05 +04:30
|
|
|
m_ShaderID = glCreateProgram();
|
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
// compile hlsl to glsl
|
|
|
|
ShaderConductor::Compiler::ResultDesc vertexResult = CompileHLSL(vertexBlob, vertexFileName, Shader::Stage::VERTEX);
|
|
|
|
ShaderConductor::Compiler::ResultDesc pixelResult = CompileHLSL(pixelBlob, pixelFileName, Shader::Stage::PIXEL);
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
LT_ENGINE_ASSERT(!vertexResult.hasError, "glShader::glShader: failed to compile hlsl vertex shader: {}", vertexFileName);
|
|
|
|
LT_ENGINE_ASSERT(!pixelResult.hasError, "glShader::glShader: failed to compile hlsl pixel shader: {}", pixelFileName);
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
// extract glsl source
|
|
|
|
std::string vertexSource = std::string(reinterpret_cast<const char*>(vertexResult.target.Data()));
|
|
|
|
vertexSource.resize(vertexResult.target.Size());
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
std::string pixelSource = std::string(reinterpret_cast<const char*>(pixelResult.target.Data()));
|
|
|
|
pixelSource.resize(pixelResult.target.Size());
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
// compile glsl
|
|
|
|
unsigned int vertexShader = CompileShader(vertexSource, Shader::Stage::VERTEX);
|
|
|
|
unsigned int pixelShader = CompileShader(pixelSource, Shader::Stage::PIXEL);
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
// attach shaders
|
|
|
|
glAttachShader(m_ShaderID, vertexShader);
|
|
|
|
glAttachShader(m_ShaderID, pixelShader);
|
|
|
|
|
|
|
|
// link shader program
|
|
|
|
glLinkProgram(m_ShaderID);
|
|
|
|
|
|
|
|
// delete shaders (free memory)
|
|
|
|
glDeleteShader(vertexShader);
|
|
|
|
glDeleteShader(pixelShader);
|
|
|
|
}
|
2021-06-26 13:09:11 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
glShader::~glShader()
|
|
|
|
{
|
|
|
|
glDeleteProgram(m_ShaderID);
|
|
|
|
}
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
void glShader::Bind()
|
|
|
|
{
|
|
|
|
glUseProgram(m_ShaderID);
|
|
|
|
}
|
|
|
|
|
|
|
|
void glShader::UnBind()
|
|
|
|
{
|
|
|
|
glUseProgram(NULL);
|
|
|
|
}
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
ShaderConductor::Compiler::ResultDesc glShader::CompileHLSL(std::vector<uint8_t> blob, std::string fileName, Shader::Stage stage)
|
|
|
|
{
|
|
|
|
// check
|
|
|
|
LT_ENGINE_ASSERT(!blob.empty(), "glShader::CompileHLSL: 'blob' is empty");
|
|
|
|
LT_ENGINE_ASSERT(!fileName.empty(), "glShader::CompileHLSL: 'fileName' is empty");
|
|
|
|
LT_ENGINE_ASSERT(stage, "glShader::CompileHLSL: 'stage' is invalid: None");
|
|
|
|
|
|
|
|
// compiler options
|
|
|
|
ShaderConductor::Compiler::Options options = {};
|
|
|
|
options.packMatricesInRowMajor = true;
|
|
|
|
options.enableDebugInfo = true;
|
|
|
|
options.disableOptimizations = true;
|
|
|
|
options.inheritCombinedSamplerBindings = true;
|
|
|
|
options.shaderModel = { 4, 5 };
|
|
|
|
|
|
|
|
// compiler target descriptor
|
|
|
|
ShaderConductor::Compiler::TargetDesc targetDesc = {};
|
|
|
|
targetDesc.language = ShaderConductor::ShadingLanguage::Glsl;
|
|
|
|
targetDesc.version = "440 core";
|
|
|
|
targetDesc.asModule = false;
|
|
|
|
|
|
|
|
// compiler source descriptor
|
|
|
|
ShaderConductor::Compiler::SourceDesc sourceDesc = {};
|
|
|
|
std::string source = std::string(reinterpret_cast<char*>(blob.data()), blob.size());
|
|
|
|
sourceDesc.source = source.c_str();
|
|
|
|
sourceDesc.fileName = fileName.c_str();
|
|
|
|
sourceDesc.entryPoint = "main";
|
|
|
|
sourceDesc.stage = stage == Shader::Stage::VERTEX ? ShaderConductor::ShaderStage::VertexShader :
|
|
|
|
stage == Shader::Stage::PIXEL ? ShaderConductor::ShaderStage::PixelShader :
|
|
|
|
ShaderConductor::ShaderStage::GeometryShader;
|
|
|
|
sourceDesc.defines = nullptr;
|
|
|
|
sourceDesc.numDefines = 0u;
|
|
|
|
sourceDesc.loadIncludeCallback = nullptr;
|
|
|
|
|
|
|
|
// compilation result
|
|
|
|
ShaderConductor::Compiler::ResultDesc result = ShaderConductor::Compiler::Compile(sourceDesc, options, targetDesc);
|
|
|
|
|
|
|
|
// log info
|
|
|
|
LT_ENGINE_INFO("_______________________________________");
|
|
|
|
LT_ENGINE_INFO("Compiled with ShaderConductor:");
|
|
|
|
LT_ENGINE_INFO(" hasError: {}", result.hasError);
|
|
|
|
LT_ENGINE_INFO(" isText: {}", result.isText);
|
|
|
|
|
|
|
|
if (result.errorWarningMsg.Size() != 0u)
|
|
|
|
{
|
|
|
|
const char* errorStr = reinterpret_cast<const char*>(result.errorWarningMsg.Data());
|
|
|
|
LT_ENGINE_ERROR(" errorWarningMsg: \n{}", errorStr);
|
|
|
|
}
|
|
|
|
if (result.target.Size() != 0u)
|
|
|
|
{
|
|
|
|
const char* targetStr = reinterpret_cast<const char*>(result.target.Data());
|
|
|
|
LT_ENGINE_INFO(" target: \n{}", targetStr);
|
2021-05-27 19:54:05 +04:30
|
|
|
}
|
2021-09-13 12:17:26 +04:30
|
|
|
LT_ENGINE_INFO("_______________________________________");
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
unsigned int glShader::CompileShader(const std::string& source, Shader::Stage stage)
|
|
|
|
{
|
|
|
|
// &(address of) needs an lvalue
|
|
|
|
const char* lvalue_source = reinterpret_cast<const char*>(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);
|
|
|
|
|
|
|
|
// compile
|
|
|
|
glShaderSource(shader, 1, &lvalue_source, NULL);
|
|
|
|
glCompileShader(shader);
|
|
|
|
|
|
|
|
// check
|
|
|
|
int isCompiled = 0;
|
|
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
|
2021-05-27 19:54:05 +04:30
|
|
|
if (isCompiled == GL_FALSE)
|
|
|
|
{
|
2021-07-01 19:25:46 +04:30
|
|
|
int logLength = 0;
|
2021-09-13 12:17:26 +04:30
|
|
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-07-01 19:25:46 +04:30
|
|
|
char* errorLog = (char*)alloca(logLength);
|
2021-09-13 12:17:26 +04:30
|
|
|
glGetShaderInfoLog(shader, logLength, &logLength, &errorLog[0]);
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
LT_ENGINE_ASSERT(false, "glShader::glShader: failed to compile vertex shader:\n {}", errorLog);
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
return NULL;
|
2021-05-27 19:54:05 +04:30
|
|
|
}
|
2021-08-01 11:57:51 +04:30
|
|
|
|
|
|
|
#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
|
2021-09-13 12:17:26 +04:30
|
|
|
// info log
|
2021-08-01 11:57:51 +04:30
|
|
|
{
|
|
|
|
int logLength = 0;
|
|
|
|
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);
|
|
|
|
if (logLength)
|
|
|
|
{
|
|
|
|
char* infoLog = (char*)alloca(logLength);
|
2021-09-13 12:17:26 +04:30
|
|
|
glGetShaderInfoLog(vertexShader, logLength, &logLength, &infoLog[0]);
|
2021-08-01 11:57:51 +04:30
|
|
|
|
|
|
|
LT_ENGINE_TRACE(infoLog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-09-13 12:17:26 +04:30
|
|
|
return shader;
|
2021-05-27 19:54:05 +04:30
|
|
|
}
|
|
|
|
|
|
|
|
}
|