2021-05-27 19:54:05 +04:30
|
|
|
#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-10-02 08:51:54 +03:30
|
|
|
glShader::glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile):
|
|
|
|
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
|
2021-10-02 08:51:54 +03:30
|
|
|
ShaderConductor::Compiler::ResultDesc vertexResult = CompileHLSL(vertexFile, Shader::Stage::VERTEX);
|
|
|
|
ShaderConductor::Compiler::ResultDesc pixelResult = CompileHLSL(pixelFile, Shader::Stage::PIXEL);
|
2021-05-27 19:54:05 +04:30
|
|
|
|
2021-10-02 08:51:54 +03:30
|
|
|
LT_ENGINE_ASSERT(!vertexResult.hasError, "glShader::glShader: failed to compile hlsl vertex shader: {}", vertexFile.GetPath());
|
|
|
|
LT_ENGINE_ASSERT(!pixelResult.hasError, "glShader::glShader: failed to compile hlsl pixel shader: {}", pixelFile.GetPath());
|
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-10-02 08:51:54 +03:30
|
|
|
ShaderConductor::Compiler::ResultDesc glShader::CompileHLSL(BasicFileHandle file, Shader::Stage stage)
|
2021-09-13 12:17:26 +04:30
|
|
|
{
|
|
|
|
// check
|
2021-10-02 08:51:54 +03:30
|
|
|
LT_ENGINE_ASSERT(file.IsValid(), "glShader::CompileHLSL: invalid 'file'");
|
|
|
|
LT_ENGINE_ASSERT(stage, "glShader::CompileHLSL: invalid 'stage': None");
|
2021-09-13 12:17:26 +04:30
|
|
|
|
|
|
|
// 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 = {};
|
2021-10-02 08:51:54 +03:30
|
|
|
std::string source = std::string(reinterpret_cast<char*>(file.GetData()), file.GetSize());
|
2021-09-13 12:17:26 +04:30
|
|
|
sourceDesc.source = source.c_str();
|
2021-10-02 08:51:54 +03:30
|
|
|
sourceDesc.fileName = file.GetName().c_str();
|
2021-09-13 12:17:26 +04:30
|
|
|
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);
|
|
|
|
|
2021-10-02 08:51:54 +03:30
|
|
|
// log error/warning
|
2021-09-13 12:17:26 +04:30
|
|
|
if (result.errorWarningMsg.Size() != 0u)
|
|
|
|
{
|
2021-10-02 08:51:54 +03:30
|
|
|
const char* errorWarningStr = reinterpret_cast<const char*>(result.errorWarningMsg.Data());
|
|
|
|
|
|
|
|
if(result.hasError)
|
|
|
|
LT_ENGINE_ERROR("glShader::CompileHLSL: ShaderConductor error:'{}': {}", file.GetName(), errorWarningStr);
|
|
|
|
else
|
|
|
|
LT_ENGINE_WARN("glShader::CompileHLSL: ShaderConductor warning:'{}': {}", errorWarningStr);
|
2021-05-27 19:54:05 +04:30
|
|
|
}
|
2021-09-13 12:17:26 +04:30
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
}
|