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 +- Runtime/Lua/LuaBind/LuaBindState.cpp | 156 ++++++++++++++++------------ Runtime/Lua/LuaBind/LuaBindState.h | 3 +- Runtime/Scripting/Rendering/Shader.bind.cpp | 45 +++++--- Runtime/Utilities/DynamicArray.cpp | 0 Runtime/Utilities/DynamicArray.h | 0 9 files changed, 220 insertions(+), 123 deletions(-) create mode 100644 Runtime/Utilities/DynamicArray.cpp create mode 100644 Runtime/Utilities/DynamicArray.h (limited to 'Runtime') 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) diff --git a/Runtime/Lua/LuaBind/LuaBindState.cpp b/Runtime/Lua/LuaBind/LuaBindState.cpp index 137acbf..9210768 100644 --- a/Runtime/Lua/LuaBind/LuaBindState.cpp +++ b/Runtime/Lua/LuaBind/LuaBindState.cpp @@ -4,6 +4,7 @@ #include "LuaBindClass.hpp" #include "LuaBindInternal.h" +#include #include namespace LuaBind @@ -539,75 +540,94 @@ namespace LuaBind return true; } - bool State::CheckParams(int idx, cc8* format) - { - idx = AbsIndex(idx); - - for (int i = 0; format[i]; ++i) { - - int pos = idx + i; - int type = LUA_TNIL; - int expected = LUA_TNONE; - - if (pos <= GetTop()) { - type = lua_type(mState, pos); - } - - switch (format[i]) { - - // boolean - case 'B': - if (type != LUA_TBOOLEAN) expected = LUA_TBOOLEAN; - break; - - // coroutine - case 'C': - if (type != LUA_TTHREAD) expected = LUA_TTHREAD; - break; - - // function - case 'F': - if (type != LUA_TFUNCTION) expected = LUA_TFUNCTION; - break; - - // light userdata - case 'L': - if (type != LUA_TLIGHTUSERDATA) expected = LUA_TLIGHTUSERDATA; - break; - - // number - case 'N': - if (type != LUA_TNUMBER) expected = LUA_TNUMBER; - break; - - // string - case 'S': - if (type != LUA_TSTRING) expected = LUA_TSTRING; - break; - - // table - case 'T': - if (type != LUA_TTABLE) expected = LUA_TTABLE; - break; - - // userdata - case 'U': - if (type != LUA_TUSERDATA) expected = LUA_TUSERDATA; - break; - - // any type - case '*': - case '.': - break; - } - - if (expected != LUA_TNONE) { - return false; - } - } + bool State::CheckParams(int idx, cc8* format, int len) + { + idx = AbsIndex(idx); + + for (int i = 0; i < len; ++i) { + int pos = idx + i; + int type = LUA_TNIL; + bool expected = true; + if (pos <= GetTop()) { + type = lua_type(mState, pos); + } + + switch (format[i]) { + + // boolean + case 'B': + if (type != LUA_TBOOLEAN) expected = false; + break; + + // coroutine + case 'C': + if (type != LUA_TTHREAD) expected = false; + break; + + // function + case 'F': + if (type != LUA_TFUNCTION) expected = false; + break; + + // light userdata + case 'L': + if (type != LUA_TLIGHTUSERDATA) expected = false; + break; + + // number + case 'N': + if (type != LUA_TNUMBER) expected = false; + break; + + // string + case 'S': + if (type != LUA_TSTRING) expected = false; + break; + + // table + case 'T': + if (type != LUA_TTABLE) expected = false; + break; + + // userdata + case 'U': + if (type != LUA_TUSERDATA) expected = false; + break; + + // any type + case '*': + break; + + // not nil + case '+': + if (type == LUA_TNIL) expected = false; + break; + } + + if (!expected) { + return false; + } + } + + return true; + } - return true; - } + bool State::CheckParams(int idx, cc8* fmt) + { + cc8* blank = fmt + strlen(fmt); + while (*fmt) { + int len = blank - fmt; + const char* end = strchr(fmt, '|'); + if (end != NULL){ + len = end - fmt; + } + if (CheckParams(idx, fmt, len)){ + return true; + } + fmt = fmt + len + (end != NULL ? 1 : 0); + } + return false; + } template <> bool State::GetValue < bool >(int idx, const bool value) { diff --git a/Runtime/Lua/LuaBind/LuaBindState.h b/Runtime/Lua/LuaBind/LuaBindState.h index a47ed5d..528c81a 100644 --- a/Runtime/Lua/LuaBind/LuaBindState.h +++ b/Runtime/Lua/LuaBind/LuaBindState.h @@ -65,7 +65,8 @@ namespace LuaBind void SetTop(int top); int GetTop(); - bool CheckParams(int idx, cc8* format); + bool CheckParams(int idx, cc8* format, int len); + bool CheckParams(int idx, cc8* format); int AbsIndex(int idx); void Call(int nArgs, int nResults, ErrorHandler handler = NULL); diff --git a/Runtime/Scripting/Rendering/Shader.bind.cpp b/Runtime/Scripting/Rendering/Shader.bind.cpp index 6646407..1605be5 100644 --- a/Runtime/Scripting/Rendering/Shader.bind.cpp +++ b/Runtime/Scripting/Rendering/Shader.bind.cpp @@ -20,33 +20,52 @@ LUA_BIND_POSTPROCESS(Shader) { } +// Shader.New(glsl[, keepSrc]) +// Shader.New(vsh, fsh[, keepSrc]) LUA_BIND_IMPL_METHOD(Shader, _New) { LUA_BIND_STATE(L, Shader); - LUA_BIND_CHECK(L, "SS*"); + LUA_BIND_CHECK(L, "SS*|S*"); try { - std::string vert, frag; - bool keepCode = false; - if (state.GetTop() == 2) + Shader* shader = NULL; + if (state.CheckParams(1, "SSB")) { - vert = state.GetValue(-2, ""); - frag = state.GetValue(-1, ""); + cc8* vert = state.GetValue(-3, ""); + cc8* frag = state.GetValue(-2, ""); + bool keepCode = state.GetValue(-1, false); + shader = new Shader(state.GetVM(), vert, frag, keepCode); } - else + else if(state.CheckParams(1, "SS")) { - vert = state.GetValue(-3, ""); - frag = state.GetValue(-2, ""); - keepCode = state.GetValue(-1, false); + cc8* vert = state.GetValue(-2, ""); + cc8* frag = state.GetValue(-1, ""); + shader = new Shader(state.GetVM(), vert, frag); } - Shader* shader = new Shader(state.GetVM(), vert, frag, keepCode); - shader->PushUserdata(state); + else if (state.CheckParams(1, "SB")) + { + std::string glsl = state.GetValue(1, ""); + bool keepCode = state.GetValue(2, false); + shader = new Shader(state.GetVM(), glsl, keepCode); + } + else if (state.CheckParams(1, "S")) + { + std::string glsl = state.GetValue(1, ""); + shader = new Shader(state.GetVM(), glsl); + } + if (shader != NULL) + shader->PushUserdata(state); + else + state.PushNil(); return 1; } catch (ShaderCompileExecption e) { log_error(e.what()); + state.PushNil(); + return 1; } - return 0; + Assert(false); + return 0; } LUA_BIND_IMPL_METHOD(Shader, _ReCompile) diff --git a/Runtime/Utilities/DynamicArray.cpp b/Runtime/Utilities/DynamicArray.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Runtime/Utilities/DynamicArray.h b/Runtime/Utilities/DynamicArray.h new file mode 100644 index 0000000..e69de29 -- cgit v1.1-26-g67d0