summaryrefslogtreecommitdiff
path: root/Client/Source/Graphics/Shader.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-12-13 00:07:19 +0800
committerchai <chaifix@163.com>2021-12-13 00:07:19 +0800
commit60cbbdec07ab7a5636eac5b3c024ae44e937f4d4 (patch)
treeb2c7b0a868f18159dbc43d8954e1bd7668549a88 /Client/Source/Graphics/Shader.cpp
+init
Diffstat (limited to 'Client/Source/Graphics/Shader.cpp')
-rw-r--r--Client/Source/Graphics/Shader.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/Client/Source/Graphics/Shader.cpp b/Client/Source/Graphics/Shader.cpp
new file mode 100644
index 0000000..899578b
--- /dev/null
+++ b/Client/Source/Graphics/Shader.cpp
@@ -0,0 +1,154 @@
+#include <exception>
+
+#include "../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];
+ if (type != "PROGRAM")
+ {
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ if (!success)
+ {
+ glGetShaderInfoLog(shader, 1024, NULL, infoLog);
+ shaderError = "ERROR::SHADER_COMPILATION_ERROR of type: " + type + "\n" + infoLog;
+ }
+ }
+ else
+ {
+ glGetProgramiv(shader, GL_LINK_STATUS, &success);
+ if (!success)
+ {
+ glGetProgramInfoLog(shader, 1024, NULL, infoLog);
+ shaderError = "ERROR::SHADER_COMPILATION_ERROR of type: " + type + "\n" + infoLog;
+ }
+ }
+ if (!success)
+ {
+ throw ShaderCompileExecption(shaderError.c_str());
+ }
+}
+
+Shader::Shader()
+{
+}
+
+Shader::Shader(std::string& glsllShader)
+{
+ // stl的string会在大小超过阈值的情况下在栈里分配,并用RAII保证释放
+ std::string vsh ;
+ std::string fsh ;
+ try
+ {
+ GLSLCompiler::Compile(glsllShader, vsh, fsh, m_Commands);
+ }
+ catch (GLSLCompileException& e)
+ {
+ ReleaseRenderCommandGroup(m_Commands);
+ throw ShaderCompileExecption(e.what());
+ }
+ CompileProgram(vsh.c_str(), fsh.c_str());
+}
+
+Shader::Shader(const char* vert, const char* frag)
+{
+ CompileProgram(vert, frag);
+}
+
+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);//为了支持中文注释,长度传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_ProgramID, "PROGRAM");
+}
+
+Shader::~Shader()
+{
+ glDeleteProgram(m_ProgramID);
+ glDeleteShader(m_VertID);
+ glDeleteShader(m_FragID);
+}
+
+void Shader::ReCompile(std::string& vert, std::string frag)
+{
+ const char* vertCode = vert.c_str();
+ const char* fragCode = frag.c_str();
+ // vertex shader
+ glShaderSource(m_VertID, 1, &vertCode, NULL);
+ glCompileShader(m_VertID);
+ checkCompileshaderErrorors(m_VertID, "VERTEX");
+ // fragment Shader
+ glShaderSource(m_FragID, 1, &fragCode, NULL);
+ glCompileShader(m_FragID);
+ checkCompileshaderErrorors(m_FragID, "FRAGMENT");
+ // create program
+ glAttachShader(m_ProgramID, m_VertID);
+ glAttachShader(m_ProgramID, m_FragID);
+ glLinkProgram(m_ProgramID);
+ checkCompileshaderErrorors(m_FragID, "PROGRAM");
+}
+
+void Shader::ReCompileVert(std::string& vert)
+{
+ glDeleteShader(m_VertID);
+ const char* vertCode = vert.c_str();
+ // vertex shader
+ glShaderSource(m_VertID, 1, &vertCode, NULL);
+ glCompileShader(m_VertID);
+ checkCompileshaderErrorors(m_VertID, "VERTEX");
+ // create program
+ glAttachShader(m_ProgramID, m_VertID);
+ glAttachShader(m_ProgramID, m_FragID);
+ glLinkProgram(m_ProgramID);
+ checkCompileshaderErrorors(m_FragID, "PROGRAM");
+}
+
+void Shader::ReCompileFrag(std::string frag)
+{
+ glDeleteShader(m_FragID);
+ const char* fragCode = frag.c_str();
+ // fragment Shader
+ glShaderSource(m_FragID, 1, &fragCode, NULL);
+ glCompileShader(m_FragID);
+ checkCompileshaderErrorors(m_FragID, "FRAGMENT");
+ // create program
+ glAttachShader(m_ProgramID, m_VertID);
+ glAttachShader(m_ProgramID, m_FragID);
+ glLinkProgram(m_ProgramID);
+ checkCompileshaderErrorors(m_FragID, "PROGRAM");
+}
+
+bool Shader::IsValid()
+{
+ return m_ProgramID != 0;
+}
+
+void Shader::ExecuteCommand()
+{
+ for (int i = 0; i < m_Commands.size(); ++i)
+ {
+ m_Commands[i]->Execute();
+ }
+} \ No newline at end of file