diff options
Diffstat (limited to 'Client/Source/Graphics/RenderCommands.h')
-rw-r--r-- | Client/Source/Graphics/RenderCommands.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/Client/Source/Graphics/RenderCommands.h b/Client/Source/Graphics/RenderCommands.h new file mode 100644 index 0000000..f66b4e2 --- /dev/null +++ b/Client/Source/Graphics/RenderCommands.h @@ -0,0 +1,164 @@ +#pragma once +#include "OpenGL.h" +#include <vector> + +struct RenderCommand +{ + virtual void Execute() = 0; +}; + +typedef std::vector<RenderCommand*> RenderCommandGroup; +void ReleaseRenderCommandGroup(RenderCommandGroup& group); + +// 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 <srcFac> <dstFac> +struct Cmd_Blend : RenderCommand +{ + enum EBlend + { + Blend_Zero, // 0 + Blend_One, // 1 + Blend_Src_Color, // 源颜色向量C¯source + Blend_One_Minus_Src_Color, // 1−C¯source + Blend_Dst_Color, // 目标颜色向量C¯destination + Blend_One_Minus_Dst_Color, // 1−C¯destination + Blend_Src_Alpha, // C¯source的alpha值 + Blend_One_Minus_Src_Alpha, // 1− C¯source的alpha值 + Blend_Dst_Alpha, // C¯destination的alpha值 + Blend_One_Minus_Dst_Alpha, // 1− C¯destination的alpha值 + Blend_Constant_Color, // 常颜色向量C¯constant + Blend_One_Minus_Constant_Color, // 1−C¯constant + Blend_Constant_Alpha, // C¯constant的alpha值 + Blend_One_Minus_Constant_Alpha, // 1− C¯constant的alpha值 + }; + + bool enable; + EBlend srcFac; + EBlend dstFac; + + void Execute() override + { + if (!enable) + glDisable(GL_BLEND); + glEnable(GL_BLEND); + glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + 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(src, dst); + } +}; + +// DepthTest Off|<func> +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); + } +}; |