From 40d40edcdeef4978a0d9c7333b7007d1fa4c0bc6 Mon Sep 17 00:00:00 2001 From: chai Date: Thu, 28 Oct 2021 16:24:34 +0800 Subject: *misc --- Runtime/Graphics/Shader.cpp | 80 ++++++++++++++++++++++++------------- Runtime/Graphics/Shader.h | 22 +++++----- Runtime/Graphics/ShaderCompiler.cpp | 35 +++++++++++++++- Runtime/Graphics/ShaderCompiler.h | 2 +- 4 files changed, 98 insertions(+), 41 deletions(-) (limited to 'Runtime/Graphics') diff --git a/Runtime/Graphics/Shader.cpp b/Runtime/Graphics/Shader.cpp index b8b9e33..3d4a374 100644 --- a/Runtime/Graphics/Shader.cpp +++ b/Runtime/Graphics/Shader.cpp @@ -2,12 +2,15 @@ #include "Runtime/Debug/log.h" #include "Shader.h" #include "OpenGL.h" +#include "ShaderCompiler.h" +using namespace std; + +std::string shaderError = ""; void checkCompileshaderErrorors(GLuint shader, std::string type) { GLint success; GLchar infoLog[1024]; - std::string shaderError = ""; if (type != "PROGRAM") { glGetShaderiv(shader, GL_COMPILE_STATUS, &success); @@ -28,7 +31,7 @@ void checkCompileshaderErrorors(GLuint shader, std::string type) } if (!success) { - throw ShaderCompileExecption(shaderError); + throw ShaderCompileExecption(shaderError.c_str()); } } @@ -38,34 +41,57 @@ Shader::Shader(LuaBind::VM*vm, bool keepSrc) { } -Shader::Shader(LuaBind::VM* vm, std::string& vert, std::string& frag, bool keepSrc) +Shader::Shader(LuaBind::VM*vm, std::string& glslShader, bool keepSrc) + : NativeClass(vm) + , m_KeepSrc(keepSrc) +{ + // stl的string会在大小超过阈值的情况下在栈里分配,并用RAII保证释放 + std::string vsh ; + std::string fsh ; + try + { + GLSLCompiler::Compile(glslShader, vsh, fsh); + } + catch (GLSLCompileException& e) + { + throw ShaderCompileExecption(e.what()); + } + CompileProgram(vsh.c_str(), fsh.c_str(), keepSrc); +} + +Shader::Shader(LuaBind::VM* vm, const char* vert, const char* frag, bool keepSrc) : NativeClass(vm) , m_KeepSrc(keepSrc) { - const char* vertCode = vert.c_str(); - const char* fragCode = frag.c_str(); - // vertex shader - m_VertID = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(m_VertID, 1, &vertCode, NULL); - glCompileShader(m_VertID); - checkCompileshaderErrorors(m_VertID, "VERTEX"); - // fragment Shader - m_FragID = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(m_FragID, 1, &fragCode, NULL); - glCompileShader(m_FragID); - checkCompileshaderErrorors(m_FragID, "FRAGMENT"); - // create program - m_ProgramID = glCreateProgram(); - glAttachShader(m_ProgramID, m_VertID); - glAttachShader(m_ProgramID, m_FragID); - glLinkProgram(m_ProgramID); - checkCompileshaderErrorors(m_FragID, "PROGRAM"); - // keep src - if (keepSrc) - { - m_VertSrc = vert; - m_FragSrc = frag; - } + CompileProgram(vert, frag, keepSrc); +} + +void Shader::CompileProgram(const char* vert, const char* frag, bool keepSrc) +{ + const char* vertCode = vert; + const char* fragCode = frag; + // vertex shader + m_VertID = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(m_VertID, 1, &vertCode, NULL); + glCompileShader(m_VertID); + checkCompileshaderErrorors(m_VertID, "VERTEX"); + // fragment Shader + m_FragID = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(m_FragID, 1, &fragCode, NULL); + glCompileShader(m_FragID); + checkCompileshaderErrorors(m_FragID, "FRAGMENT"); + // create program + m_ProgramID = glCreateProgram(); + glAttachShader(m_ProgramID, m_VertID); + glAttachShader(m_ProgramID, m_FragID); + glLinkProgram(m_ProgramID); + checkCompileshaderErrorors(m_FragID, "PROGRAM"); + // keep src + if (keepSrc) + { + m_VertSrc = vert; + m_FragSrc = frag; + } } Shader::~Shader() diff --git a/Runtime/Graphics/Shader.h b/Runtime/Graphics/Shader.h index 7cca768..614e127 100644 --- a/Runtime/Graphics/Shader.h +++ b/Runtime/Graphics/Shader.h @@ -4,14 +4,16 @@ #include "Runtime/Graphics/OpenGL.h" #include "Runtime/Lua/LuaHelper.h" #include "Runtime/Utilities/UtilMacros.h" +#include "Runtime/Utilities/Assert.h" #include "runtime/Debug/Log.h" // 着色器程序 class Shader : public LuaBind::NativeClass { public: - Shader(LuaBind::VM*vm, bool keepSrc = false); - Shader(LuaBind::VM*vm, std::string& vert, std::string& frag, bool keepSrc = false)/*throw(ShaderCompileExecption)*/; + Shader(LuaBind::VM*vm, bool keepSrc = false)/*throw(ShaderCompileExecption)*/; + Shader(LuaBind::VM*vm, std::string& glslShader, bool keepSrc = false)/*throw(ShaderCompileExecption)*/; + Shader(LuaBind::VM*vm, const char* vert, const char* frag, bool keepSrc = false)/*throw(ShaderCompileExecption)*/; ~Shader(); void ReCompile(std::string& vert, std::string frag)/*throw(ShaderCompileExecption)*/; @@ -23,6 +25,8 @@ public: GET(GLint, ID, m_ProgramID); private: + void CompileProgram(const char* vert, const char* frag, bool keepSrc = false); + bool m_KeepSrc; std::string m_VertSrc; @@ -47,14 +51,8 @@ private: class ShaderCompileExecption : public std::exception { public: - ShaderCompileExecption(std::string& err) - { - m_Err = err; - } - char const* what() const override - { - return m_Err.c_str(); + ShaderCompileExecption(const char* what) + : std::exception(what) + { } -private: - std::string m_Err; -}; \ No newline at end of file +}; diff --git a/Runtime/Graphics/ShaderCompiler.cpp b/Runtime/Graphics/ShaderCompiler.cpp index 66413e9..b3db629 100644 --- a/Runtime/Graphics/ShaderCompiler.cpp +++ b/Runtime/Graphics/ShaderCompiler.cpp @@ -1,7 +1,40 @@ #include "ShaderCompiler.h" -void GLSLCompiler::Compile(std::string& src, std::string& vsh, std::string& fsh) +using namespace std; + +const char* VSH_BEGIN = "VSH_BEGIN"; +const char* VSH_END = "VSH_END"; +const char* FSH_BEGIN = "FSH_BEGIN"; +const char* FSH_END = "FSH_END"; + +// GLSL分为三部分 +// VERTEX_SHADER_BEGIN 和 VERTEX_SHADER_END之间的顶点着色器 +// FRAGMENT_SHADER_BEGIN 和 FRAGMENT_SHADER_END之间的片段着色器 +// 两者之外的公共部分 +void GLSLCompiler::Compile(std::string& src, std::string& vsh, std::string& fsh)/*throw GLSLCompileException*/ { + int vsh_begin = src.find(VSH_BEGIN); + if (vsh_begin == string::npos) + throw GLSLCompileException("Compile Shader Error: No VSH_BEGIN label"); + int vsh_end = src.find(VSH_END); + if (vsh_end == string::npos) + throw GLSLCompileException("Compile Shader Error: No VSH_END label"); + int fsh_begin = src.find(FSH_BEGIN); + if (fsh_begin == string::npos) + throw GLSLCompileException("Compile Shader Error: No FSH_BEGIN label"); + int fsh_end = src.find(FSH_END); + if (fsh_end == string::npos) + throw GLSLCompileException("Compile Shader Error: No FSH_END label"); + + vsh = src.substr(vsh_begin + strlen(VSH_BEGIN), vsh_end - vsh_begin - strlen(VSH_BEGIN)); + fsh = src.substr(fsh_begin + strlen(FSH_BEGIN), fsh_end - fsh_begin - strlen(FSH_BEGIN)); + string common; + common = src.erase(vsh_begin, vsh_end + strlen(VSH_END) - vsh_begin); + int fsh_begin2 = common.find(FSH_BEGIN); + int fsh_end2 = common.find(FSH_END); + common = common.erase(fsh_begin2, fsh_end2 + strlen(FSH_END) - fsh_begin2); + vsh = common + vsh; + fsh = common + fsh; } diff --git a/Runtime/Graphics/ShaderCompiler.h b/Runtime/Graphics/ShaderCompiler.h index f4dc0a5..4e276c1 100644 --- a/Runtime/Graphics/ShaderCompiler.h +++ b/Runtime/Graphics/ShaderCompiler.h @@ -21,7 +21,7 @@ class CompileGLSLShaderJob : public Job }; -class GLSLCompileException : std::exception +class GLSLCompileException : public std::exception { public: GLSLCompileException(const char* what) -- cgit v1.1-26-g67d0