summaryrefslogtreecommitdiff
path: root/Runtime/Graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Graphics')
-rw-r--r--Runtime/Graphics/Shader.cpp80
-rw-r--r--Runtime/Graphics/Shader.h22
-rw-r--r--Runtime/Graphics/ShaderCompiler.cpp35
-rw-r--r--Runtime/Graphics/ShaderCompiler.h2
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)