diff options
Diffstat (limited to 'Runtime/Graphics')
-rw-r--r-- | Runtime/Graphics/Shader.cpp | 80 | ||||
-rw-r--r-- | Runtime/Graphics/Shader.h | 22 | ||||
-rw-r--r-- | Runtime/Graphics/ShaderCompiler.cpp | 35 | ||||
-rw-r--r-- | Runtime/Graphics/ShaderCompiler.h | 2 |
4 files changed, 98 insertions, 41 deletions
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<Shader>(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<Shader>(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<Shader>
{
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)
|