From 4b24de9ef863f54eb09a5fa1f18e2905cedcc439 Mon Sep 17 00:00:00 2001 From: chai Date: Sun, 31 Oct 2021 17:13:50 +0800 Subject: + shader command --- Data/Resources/Shaders/Editor-Text.glsl | 10 +- Data/Scripts/Editor/AssetBrowser.lua | 48 +----- Projects/VisualStudio/Editor/Editor.vcxproj | 1 + .../VisualStudio/Editor/Editor.vcxproj.filters | 3 + Runtime/Common/DataBuffer.h | 9 +- Runtime/FileSystem/FileJobs.h | 3 +- Runtime/GUI/TextGenerator.cpp | 2 +- Runtime/Graphics/RenderCommands.h | 162 +++++++++++++++++++++ Runtime/Graphics/Shader.h | 3 + Runtime/Rendering/Quad.cpp | 2 +- Runtime/Scripting/IO/IO.bind.cpp | 80 +++++++++- Runtime/Scripting/Rendering/Shader.bind.cpp | 15 +- 12 files changed, 285 insertions(+), 53 deletions(-) create mode 100644 Runtime/Graphics/RenderCommands.h diff --git a/Data/Resources/Shaders/Editor-Text.glsl b/Data/Resources/Shaders/Editor-Text.glsl index 7a88fcf..af76555 100644 --- a/Data/Resources/Shaders/Editor-Text.glsl +++ b/Data/Resources/Shaders/Editor-Text.glsl @@ -1,5 +1,13 @@ #version 330 core +CMD_BEGIN + +Cull Both +DepthTest Off +Blend SrcAlpha OneMinusSrcAlpha + +CMD_END + uniform mat4 gamelab_mat_mvp; uniform sampler2D uiTex; uniform vec2 uiText_ST; @@ -31,4 +39,4 @@ void main() FragColor = sampled; } -FSH_END \ No newline at end of file +FSH_END diff --git a/Data/Scripts/Editor/AssetBrowser.lua b/Data/Scripts/Editor/AssetBrowser.lua index 5f00dc1..7c73ec3 100644 --- a/Data/Scripts/Editor/AssetBrowser.lua +++ b/Data/Scripts/Editor/AssetBrowser.lua @@ -3,6 +3,8 @@ local AssetBrowser = GameLab.Editor.GUI.EditorWindow.Extend("GameLab.Editor.Asse local GL = GameLab.Engine.GL local Matrix44 = GameLab.Engine.Math.Matrix44 local Engine = GameLab.Engine +local IO = GameLab.IO + local inspect = require("inspect") AssetBrowser.Ctor = function(self) @@ -10,49 +12,6 @@ AssetBrowser.Ctor = function(self) end local shader = nil - -local glsl = [[ - -#version 330 core - -VSH_BEGIN - -layout (location = 0) in vec2 vPos; -layout (location = 1) in vec2 vUV; - -uniform mat4 mvp; - -out vec2 uv; - -void main() -{ - vec4 clip = mvp * vec4(vPos, -1, 1.0); - gl_Position = clip; - uv = vUV; -} - -VSH_END - -FSH_BEGIN -uniform sampler2D uiTex; - -in vec2 uv; - -out vec4 FragColor; - -void main() -{ - vec2 uv = vec2(uv.x, 1 - uv.y); - vec4 sampled = vec4(1,1,1,texture(uiTex, uv).r); - FragColor = sampled; -// FragColor = texture(uiTex, uv); -// FragColor.rgb = vec3(1,0,0); -// FragColor.a = 1; -} -FSH_END - -]] - local tex AssetBrowser.OnGUI = function(self) @@ -63,6 +22,7 @@ AssetBrowser.OnGUI = function(self) end if shader == nil then + local glsl = IO.ReadFile("./Resources/Shaders/Editor-Text.glsl", IO.EFileMode.Text) shader = Engine.Rendering.Shader.New(glsl) end @@ -81,7 +41,7 @@ AssetBrowser.OnGUI = function(self) -- GL.End() Engine.Rendering.UseShader(shader) - Engine.Rendering.SetMatrix44("mvp", ortho) + Engine.Rendering.SetMatrix44("gamelab_mat_mvp", ortho) Engine.Rendering.SetTexture("uiTex", tex) Engine.Rendering.DrawUIQuad({10, 30, 300, 300}) diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj b/Projects/VisualStudio/Editor/Editor.vcxproj index d35cb10..e6c8aee 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj +++ b/Projects/VisualStudio/Editor/Editor.vcxproj @@ -274,6 +274,7 @@ + diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.filters b/Projects/VisualStudio/Editor/Editor.vcxproj.filters index 3f35125..78f759a 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj.filters +++ b/Projects/VisualStudio/Editor/Editor.vcxproj.filters @@ -677,6 +677,9 @@ Runtime\Utilities + + Runtime\Graphics + diff --git a/Runtime/Common/DataBuffer.h b/Runtime/Common/DataBuffer.h index 7004937..7b89ab5 100644 --- a/Runtime/Common/DataBuffer.h +++ b/Runtime/Common/DataBuffer.h @@ -1,6 +1,12 @@ #pragma once #include "Runtime/Lua/LuaHelper.h" +enum EDataBufferType +{ + DataBufferMode_Binary, // 不以\0结尾,不包括\0 + DataBufferMode_Text, // 以\0结尾,包括\0 +}; + // 描述内存对象,会作为 // 1. 多线程读取文件的返回 class DataBuffer : public LuaBind::NativeClass @@ -17,8 +23,9 @@ public: delete data; } - unsigned char* data; + char* data; int length; + EDataBufferType type; private: LUA_BIND_DECL_CLASS(DataBuffer); diff --git a/Runtime/FileSystem/FileJobs.h b/Runtime/FileSystem/FileJobs.h index 1fe49f1..cae5341 100644 --- a/Runtime/FileSystem/FileJobs.h +++ b/Runtime/FileSystem/FileJobs.h @@ -22,4 +22,5 @@ public: std::vector files; // 文件路径 LuaBind::StrongRef callback; // 完成后的回调函数 -}; \ No newline at end of file +}; + diff --git a/Runtime/GUI/TextGenerator.cpp b/Runtime/GUI/TextGenerator.cpp index 1b34d1b..d2cd20c 100644 --- a/Runtime/GUI/TextGenerator.cpp +++ b/Runtime/GUI/TextGenerator.cpp @@ -73,7 +73,7 @@ void TextGenerator::RenderCharacter(character::Codepoint codepoint, int pixelSiz int w = m_FTFace->glyph->bitmap.width; int h = m_FTFace->glyph->bitmap.rows; - TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h); + //TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h); GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h)); Assert(atlas); diff --git a/Runtime/Graphics/RenderCommands.h b/Runtime/Graphics/RenderCommands.h new file mode 100644 index 0000000..3908e3a --- /dev/null +++ b/Runtime/Graphics/RenderCommands.h @@ -0,0 +1,162 @@ +锘#pragma once +#include "OpenGL.h" +#include + +struct RenderCommand +{ + virtual void Execute() = 0; +}; + +typedef std::vector RenderCommandGroup; + +// Cull Off|Front|Back|Both +struct Cmd_Cull : RenderCommand +{ + enum ECullFace { + Cull_Disable, + Cull_Front, + Cull_Back, + Cull_Both, + }; + + ECullFace cull; + + void Execute() override + { + if (cull == ECullFace::Cull_Disable) + { + glDisable(GL_CULL_FACE); + return; + } + glEnable(GL_CULL_FACE); + switch (cull) + { + case ECullFace::Cull_Front: glCullFace(GL_FRONT); break; + case ECullFace::Cull_Back: glCullFace(GL_BACK); break; + case ECullFace::Cull_Both: glCullFace(GL_FRONT_AND_BACK); break; + } + } +}; + +// Blend Off +// Blend +struct Cmd_Blend : RenderCommand +{ + enum EBlend + { + Blend_Zero, // 0 + Blend_One, // 1 + Blend_Src_Color, // 婧愰鑹插悜閲廋炉source + Blend_One_Minus_Src_Color, // 1鈭扖炉source + Blend_Dst_Color, // 鐩爣棰滆壊鍚戦噺C炉destination + Blend_One_Minus_Dst_Color, // 1鈭扖炉destination + Blend_Src_Alpha, // C炉source鐨刟lpha鍊 + Blend_One_Minus_Src_Alpha, // 1鈭 C炉source鐨刟lpha鍊 + Blend_Dst_Alpha, // C炉destination鐨刟lpha鍊 + Blend_One_Minus_Dst_Alpha, // 1鈭 C炉destination鐨刟lpha鍊 + Blend_Constant_Color, // 甯搁鑹插悜閲廋炉constant + Blend_One_Minus_Constant_Color, // 1鈭扖炉constant + Blend_Constant_Alpha, // C炉constant鐨刟lpha鍊 + Blend_One_Minus_Constant_Alpha, // 1鈭 C炉constant鐨刟lpha鍊 + }; + + bool enable; + EBlend srcFac; + EBlend dstFac; + + void Execute() override + { + if (!enable) + glDisable(GL_BLEND); + glEnable(GL_BLEND); + GLenum src, dst; + switch (srcFac) + { + case EBlend::Blend_Zero: src = GL_ZERO; break; + case EBlend::Blend_One: src = GL_ONE; break; + case EBlend::Blend_Src_Color: src = GL_SRC_COLOR; break; + case EBlend::Blend_One_Minus_Src_Color: src = GL_ONE_MINUS_SRC_COLOR; break; + case EBlend::Blend_Dst_Color: src = GL_DST_COLOR; break; + case EBlend::Blend_One_Minus_Dst_Color: src = GL_ONE_MINUS_DST_COLOR; break; + case EBlend::Blend_Src_Alpha: src = GL_SRC_ALPHA; break; + case EBlend::Blend_One_Minus_Src_Alpha: src = GL_ONE_MINUS_SRC_ALPHA; break; + case EBlend::Blend_Dst_Alpha: src = GL_DST_ALPHA; break; + case EBlend::Blend_One_Minus_Dst_Alpha: src = GL_ONE_MINUS_DST_ALPHA; break; + case EBlend::Blend_Constant_Color: src = GL_CONSTANT_COLOR; break; + case EBlend::Blend_One_Minus_Constant_Color: src = GL_ONE_MINUS_CONSTANT_COLOR; break; + case EBlend::Blend_Constant_Alpha: src = GL_CONSTANT_ALPHA; break; + case EBlend::Blend_One_Minus_Constant_Alpha: src = GL_ONE_MINUS_CONSTANT_ALPHA; break; + } + switch (dstFac) + { + case EBlend::Blend_Zero: dst = GL_ZERO; break; + case EBlend::Blend_One: dst = GL_ONE; break; + case EBlend::Blend_Src_Color: dst = GL_SRC_COLOR; break; + case EBlend::Blend_One_Minus_Src_Color: dst = GL_ONE_MINUS_SRC_COLOR; break; + case EBlend::Blend_Dst_Color: dst = GL_DST_COLOR; break; + case EBlend::Blend_One_Minus_Dst_Color: dst = GL_ONE_MINUS_DST_COLOR; break; + case EBlend::Blend_Src_Alpha: dst = GL_SRC_ALPHA; break; + case EBlend::Blend_One_Minus_Src_Alpha: dst = GL_ONE_MINUS_SRC_ALPHA; break; + case EBlend::Blend_Dst_Alpha: dst = GL_DST_ALPHA; break; + case EBlend::Blend_One_Minus_Dst_Alpha: dst = GL_ONE_MINUS_DST_ALPHA; break; + case EBlend::Blend_Constant_Color: dst = GL_CONSTANT_COLOR; break; + case EBlend::Blend_One_Minus_Constant_Color: dst = GL_ONE_MINUS_CONSTANT_COLOR; break; + case EBlend::Blend_Constant_Alpha: dst = GL_CONSTANT_ALPHA; break; + case EBlend::Blend_One_Minus_Constant_Alpha: dst = GL_ONE_MINUS_CONSTANT_ALPHA; break; + } + glBlendFunc(srcFac, dstFac); + } +}; + +// DepthTest Off| +struct Cmd_DepthTest : RenderCommand +{ + enum EDepthTest + { + DepthTest_Off, // 涓嶈繘琛屾繁搴︽祴璇 + DepthTest_Always, // 姘歌繙閫氳繃娴嬭瘯 + DepthTest_Never, // 姘歌繙涓嶉氳繃娴嬭瘯 + DepthTest_Less, // 鍦ㄧ墖娈垫繁搴﹀煎皬浜庣紦鍐插尯鐨勬繁搴︽椂閫氳繃娴嬭瘯 + DepthTest_Equal, // 鍦ㄧ墖娈垫繁搴﹀肩瓑浜庣紦鍐插尯鐨勬繁搴︽椂閫氳繃娴嬭瘯 + DepthTest_Lequal, // 鍦ㄧ墖娈垫繁搴﹀煎皬浜庣瓑浜庣紦鍐插尯鐨勬繁搴︽椂閫氳繃娴嬭瘯 + DepthTest_Greater, // 鍦ㄧ墖娈垫繁搴﹀煎ぇ浜庣紦鍐插尯鐨勬繁搴︽椂閫氳繃娴嬭瘯 + DepthTest_Notequal, // 鍦ㄧ墖娈垫繁搴﹀间笉绛変簬缂撳啿鍖虹殑娣卞害鏃堕氳繃娴嬭瘯 + DepthTest_Gequal, // 鍦ㄧ墖娈垫繁搴﹀煎ぇ浜庣瓑浜庣紦鍐插尯鐨勬繁搴︽椂閫氳繃娴嬭瘯 + }; + + EDepthTest test; + + void Execute() override + { + if (test == EDepthTest::DepthTest_Off) + { + glDisable(GL_DEPTH_TEST); + return; + } + glEnable(GL_DEPTH_TEST); + switch (test) + { + case EDepthTest::DepthTest_Always: glDepthFunc(GL_ALWAYS); break; + case EDepthTest::DepthTest_Never: glDepthFunc(GL_NEVER); break; + case EDepthTest::DepthTest_Less: glDepthFunc(GL_LESS); break; + case EDepthTest::DepthTest_Equal: glDepthFunc(GL_EQUAL); break; + case EDepthTest::DepthTest_Lequal: glDepthFunc(GL_LEQUAL); break; + case EDepthTest::DepthTest_Greater: glDepthFunc(GL_GREATER); break; + case EDepthTest::DepthTest_Notequal: glDepthFunc(GL_NOTEQUAL); break; + case EDepthTest::DepthTest_Gequal: glDepthFunc(GL_GEQUAL); break; + } + } +}; + +// DepthWrite Off|On +struct Cmd_DepthWrite : RenderCommand +{ + bool write; + void Execute() override + { + if(write) + glDepthMask(GL_TRUE); + else + glDepthMask(GL_FALSE); + } +}; diff --git a/Runtime/Graphics/Shader.h b/Runtime/Graphics/Shader.h index 3410e20..095d9fe 100644 --- a/Runtime/Graphics/Shader.h +++ b/Runtime/Graphics/Shader.h @@ -6,6 +6,7 @@ #include "Runtime/Utilities/UtilMacros.h" #include "Runtime/Utilities/Assert.h" #include "runtime/Debug/Log.h" +#include "RenderCommands.h" // 着色器程序 class Shader : public LuaBind::NativeClass @@ -28,6 +29,8 @@ public: private: void CompileProgram(const char* vert, const char* frag, bool keepSrc = false); + RenderCommandGroup m_Commands; // 渲染前的状态设置 + GLint m_ProgramID; GLint m_FragID; GLint m_VertID; diff --git a/Runtime/Rendering/Quad.cpp b/Runtime/Rendering/Quad.cpp index b4f81ee..6378bf0 100644 --- a/Runtime/Rendering/Quad.cpp +++ b/Runtime/Rendering/Quad.cpp @@ -58,4 +58,4 @@ void Quad::Draw() g_SharedVBO.ReleaseChunk(4, 6); g_SharedVBO.DrawChunk(layout); -} \ No newline at end of file +} diff --git a/Runtime/Scripting/IO/IO.bind.cpp b/Runtime/Scripting/IO/IO.bind.cpp index ba5691f..a46b110 100644 --- a/Runtime/Scripting/IO/IO.bind.cpp +++ b/Runtime/Scripting/IO/IO.bind.cpp @@ -1,12 +1,24 @@ #include "Runtime/Lua/LuaHelper.h" #include "Runtime/Debug/Log.h" +#include "Runtime/Common/DataBuffer.h" #include "Runtime/FileSystem/FileJobs.h" +#include + +using namespace std; +using namespace LuaBind; + +enum EFileMode +{ + FileMode_Text, + FileMode_Binary, +}; + // IO.ReadFiles({}, callback) int ReadFilesAsync(lua_State* L) { LUA_BIND_STATE(L); - LUA_BIND_CHECK(L, "TF"); + LUA_BIND_CHECK(L, "TF!"); std::vector files; for (int i = 1; true; ++i) @@ -30,9 +42,66 @@ int ReadFilesAsync(lua_State* L) return 0; } +// IO.ReadFile(path[,mode]) +// return DataBuffer +int ReadFile(lua_State* L) +{ + LUA_BIND_STATE(L); + LUA_BIND_CHECK(L, "SN!|S!"); + + const char* path = state.GetValue(1, ""); + int mode = state.GetValue(2, EFileMode::FileMode_Binary); + + bool isTextFile = mode == EFileMode::FileMode_Text; + bool isBinaryFile = mode == EFileMode::FileMode_Binary; + + int openMode = 0; + //if (isBinaryFile) + openMode |= ios::binary; + + std::ifstream file = ifstream(path, openMode); + if (!file.is_open()) + { + log_error(string("Can't read file. ") + path); + state.PushNil(); + return 1; + } + + std::streampos size = file.tellg(); + file.seekg(0, std::ios::end); + size = file.tellg() - size; + if (size == 0) + { + log_error(string("File is Empty. ") + path); + state.PushNil(); + return 1; + } + file.seekg(0, std::ios::beg); + + int bufSize = size; + if (isTextFile) + bufSize += 1; // \0 + + DataBuffer* buffer = new DataBuffer(state.GetVM()); + buffer->type = isBinaryFile ? EDataBufferType::DataBufferMode_Binary : EDataBufferType::DataBufferMode_Text; + buffer->data = new char[bufSize]; + buffer->length = bufSize; + + file.read(buffer->data, size); + file.close(); + + if (isTextFile) + buffer->data[bufSize - 1] = '\0'; + + buffer->PushUserdata(state); + + return 1; +} + static luaL_Reg ioFuncs[] = { - {"ReadFilesAsync", ReadFilesAsync}, - {0, 0} + { "ReadFilesAsync", ReadFilesAsync }, + { "ReadFile", ReadFile }, + { 0, 0 } }; int luaopen_GameLab_IO(lua_State* L) @@ -47,5 +116,10 @@ int luaopen_GameLab_IO(lua_State* L) state.RegisterMethods(ioFuncs); + LUA_BIND_REGISTER_ENUM(state, "EFileMode", + { "Binary", EFileMode::FileMode_Binary}, + { "Text", EFileMode::FileMode_Text} + ); + return 1; } \ No newline at end of file diff --git a/Runtime/Scripting/Rendering/Shader.bind.cpp b/Runtime/Scripting/Rendering/Shader.bind.cpp index 0137447..482efb9 100644 --- a/Runtime/Scripting/Rendering/Shader.bind.cpp +++ b/Runtime/Scripting/Rendering/Shader.bind.cpp @@ -1,6 +1,7 @@ #include "Runtime/Graphics/Shader.h" #include "Runtime/Debug/Log.h" #include "Runtime/Graphics/GfxDevice.h" +#include "Runtime/Common/DataBuffer.h" using namespace LuaBind; @@ -30,10 +31,11 @@ LUA_BIND_POSTPROCESS(Shader) // Shader.New(glsl[, keepSrc]) // Shader.New(vsh, fsh[, keepSrc]) +// Shader.New(DataBuffer) LUA_BIND_IMPL_METHOD(Shader, _New) { LUA_BIND_STATE(L, Shader); - LUA_BIND_CHECK(L, "SS!|S!"); + LUA_BIND_CHECK(L, "SS!|S!|U!"); try { Shader* shader = NULL; if(state.CheckParams(1, "SS!")) @@ -47,6 +49,17 @@ LUA_BIND_IMPL_METHOD(Shader, _New) std::string glsl = state.GetValue(1, ""); shader = new Shader(state.GetVM(), glsl); } + else if (LuaHelper::IsType(state, "GameLab.DataBuffer", 1)) + { + DataBuffer* buffer = state.GetUserdata(1); + if (buffer == NULL) + { + log_error("Unable to create shader, databuffer is empty"); + return 0; + } + std::string glsl = buffer->data; + shader = new Shader(state.GetVM(), glsl); + } if (shader != NULL) shader->PushUserdata(state); else -- cgit v1.1-26-g67d0