From f3acc97d638219ad6b32b87f4c83b822c005ef43 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 9 Jun 2017 19:34:39 -1000 Subject: [PATCH] Implement actual CParticleSwoosh rendering --- Runtime/Graphics/CMakeLists.txt | 10 +- .../Graphics/Shaders/CElementGenShaders.cpp | 154 +++++++++++++ .../Shaders}/CElementGenShaders.hpp | 37 ++-- .../Shaders}/CElementGenShadersGLSL.cpp | 28 +-- .../Shaders}/CElementGenShadersHLSL.cpp | 29 +-- .../Shaders}/CElementGenShadersMetal.cpp | 27 ++- .../Shaders/CParticleSwooshShaders.cpp | 78 +++++++ .../Shaders/CParticleSwooshShaders.hpp | 63 ++++++ .../Shaders/CParticleSwooshShadersGLSL.cpp | 204 ++++++++++++++++++ .../Shaders/CParticleSwooshShadersHLSL.cpp | 0 .../Shaders/CParticleSwooshShadersMetal.cpp | 138 ++++++++++++ Runtime/Particle/CElementGen.cpp | 192 +---------------- Runtime/Particle/CElementGen.hpp | 2 +- Runtime/Particle/CMakeLists.txt | 8 - Runtime/Particle/CParticleSwoosh.cpp | 173 +++++++++++---- Runtime/Particle/CParticleSwoosh.hpp | 16 ++ nod | 2 +- specter | 2 +- 18 files changed, 851 insertions(+), 312 deletions(-) create mode 100644 Runtime/Graphics/Shaders/CElementGenShaders.cpp rename Runtime/{Particle => Graphics/Shaders}/CElementGenShaders.hpp (67%) rename Runtime/{Particle => Graphics/Shaders}/CElementGenShadersGLSL.cpp (97%) rename Runtime/{Particle => Graphics/Shaders}/CElementGenShadersHLSL.cpp (95%) rename Runtime/{Particle => Graphics/Shaders}/CElementGenShadersMetal.cpp (96%) create mode 100644 Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp create mode 100644 Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp create mode 100644 Runtime/Graphics/Shaders/CParticleSwooshShadersGLSL.cpp create mode 100644 Runtime/Graphics/Shaders/CParticleSwooshShadersHLSL.cpp create mode 100644 Runtime/Graphics/Shaders/CParticleSwooshShadersMetal.cpp diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 25b8f145b..8da2d0b47 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -17,7 +17,9 @@ if(WIN32) Shaders/CMapSurfaceShaderHLSL.cpp Shaders/CPhazonSuitFilterHLSL.cpp Shaders/CScanLinesFilterHLSL.cpp - Shaders/CRandomStaticFilterHLSL.cpp) + Shaders/CRandomStaticFilterHLSL.cpp + Shaders/CElementGenShadersHLSL.cpp + Shaders/CParticleSwooshShadersHLSL.cpp) elseif(BOO_HAS_METAL) set(PLAT_SRCS Shaders/CLineRendererShadersMetal.cpp @@ -37,7 +39,9 @@ elseif(BOO_HAS_METAL) Shaders/CMapSurfaceShaderMetal.cpp Shaders/CPhazonSuitFilterMetal.cpp Shaders/CScanLinesFilterMetal.cpp - Shaders/CRandomStaticFilterMetal.cpp) + Shaders/CRandomStaticFilterMetal.cpp + Shaders/CElementGenShadersMetal.cpp + Shaders/CParticleSwooshShadersMetal.cpp) endif() set(GRAPHICS_SOURCES @@ -79,6 +83,8 @@ set(GRAPHICS_SOURCES Shaders/CPhazonSuitFilter.hpp Shaders/CPhazonSuitFilter.cpp Shaders/CPhazonSuitFilterGLSL.cpp Shaders/CScanLinesFilter.hpp Shaders/CScanLinesFilter.cpp Shaders/CScanLinesFilterGLSL.cpp Shaders/CRandomStaticFilter.hpp Shaders/CRandomStaticFilter.cpp Shaders/CRandomStaticFilterGLSL.cpp + Shaders/CElementGenShaders.hpp Shaders/CElementGenShaders.cpp Shaders/CElementGenShadersGLSL.cpp + Shaders/CParticleSwooshShaders.hpp Shaders/CParticleSwooshShaders.cpp Shaders/CParticleSwooshShadersGLSL.cpp ${PLAT_SRCS}) runtime_add_list(Graphics GRAPHICS_SOURCES) diff --git a/Runtime/Graphics/Shaders/CElementGenShaders.cpp b/Runtime/Graphics/Shaders/CElementGenShaders.cpp new file mode 100644 index 000000000..b44ef00f3 --- /dev/null +++ b/Runtime/Graphics/Shaders/CElementGenShaders.cpp @@ -0,0 +1,154 @@ +#include "CElementGenShaders.hpp" +#include "Particle/CElementGen.hpp" + +namespace urde +{ + +boo::IShaderPipeline* CElementGenShaders::m_texZTestZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texNoZTestZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texZTestNoZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texNoZTestNoZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texAdditiveZTest = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texAdditiveNoZTest = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaZTest = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaNoZTest = nullptr; + +boo::IShaderPipeline* CElementGenShaders::m_indTexZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_indTexNoZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_indTexAdditive = nullptr; + +boo::IShaderPipeline* CElementGenShaders::m_cindTexZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_cindTexNoZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_cindTexAdditive = nullptr; + +boo::IShaderPipeline* CElementGenShaders::m_noTexZTestZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_noTexNoZTestZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_noTexZTestNoZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_noTexNoZTestNoZWrite = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_noTexAdditiveZTest = nullptr; +boo::IShaderPipeline* CElementGenShaders::m_noTexAdditiveNoZTest = nullptr; + +boo::IVertexFormat* CElementGenShaders::m_vtxFormatTex = nullptr; +boo::IVertexFormat* CElementGenShaders::m_vtxFormatIndTex = nullptr; +boo::IVertexFormat* CElementGenShaders::m_vtxFormatNoTex = nullptr; + +CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) +{ + CGenDescription* desc = gen.x1c_genDesc.GetObj(); + + if (desc->x54_x40_TEXR) + { + if (desc->x58_x44_TIND) + return EShaderClass::IndTex; + else + return EShaderClass::Tex; + } + else + return EShaderClass::NoTex; +} + +void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen) +{ + CGenDescription* desc = gen.x1c_genDesc.GetObj(); + boo::IShaderPipeline* regPipeline = nullptr; + boo::IShaderPipeline* redToAlphaPipeline = nullptr; + + if (desc->x54_x40_TEXR) + { + if (desc->x58_x44_TIND) + { + if (desc->x45_30_x32_24_CIND) + { + if (gen.x26c_26_AAPH) + regPipeline = m_cindTexAdditive; + else + { + if (gen.x26c_27_ZBUF) + regPipeline = m_cindTexZWrite; + else + regPipeline = m_cindTexNoZWrite; + } + } + else + { + if (gen.x26c_26_AAPH) + regPipeline = m_indTexAdditive; + else + { + if (gen.x26c_27_ZBUF) + regPipeline = m_indTexZWrite; + else + regPipeline = m_indTexNoZWrite; + } + } + } + else + { + if (gen.x26c_28_zTest) + redToAlphaPipeline = m_texRedToAlphaZTest; + else + redToAlphaPipeline = m_texRedToAlphaNoZTest; + + if (gen.x26c_26_AAPH) + { + if (gen.x26c_28_zTest) + regPipeline = m_texAdditiveZTest; + else + regPipeline = m_texAdditiveNoZTest; + } + else + { + if (gen.x26c_28_zTest) + { + if (gen.x26c_27_ZBUF) + regPipeline = m_texZTestZWrite; + else + regPipeline = m_texZTestNoZWrite; + } + else + { + if (gen.x26c_27_ZBUF) + regPipeline = m_texNoZTestZWrite; + else + regPipeline = m_texNoZTestNoZWrite; + } + } + } + } + else + { + if (gen.x26c_26_AAPH) + { + if (gen.x26c_28_zTest) + regPipeline = m_noTexAdditiveZTest; + else + regPipeline = m_noTexAdditiveNoZTest; + } + else + { + if (gen.x26c_28_zTest) + { + if (gen.x26c_27_ZBUF) + regPipeline = m_noTexZTestZWrite; + else + regPipeline = m_noTexZTestNoZWrite; + } + else + { + if (gen.x26c_27_ZBUF) + regPipeline = m_noTexNoZTestZWrite; + else + regPipeline = m_noTexNoZTestNoZWrite; + } + } + } + + CElementGenShaders shad(gen, regPipeline, redToAlphaPipeline); + TShader::BuildShaderDataBinding(ctx, shad); +} + +void CElementGenShaders::Shutdown() {} + +URDE_SPECIALIZE_SHADER(CElementGenShaders) + +} diff --git a/Runtime/Particle/CElementGenShaders.hpp b/Runtime/Graphics/Shaders/CElementGenShaders.hpp similarity index 67% rename from Runtime/Particle/CElementGenShaders.hpp rename to Runtime/Graphics/Shaders/CElementGenShaders.hpp index 2878eea36..cc0eda3df 100644 --- a/Runtime/Particle/CElementGenShaders.hpp +++ b/Runtime/Graphics/Shaders/CElementGenShaders.hpp @@ -1,6 +1,7 @@ #ifndef __URDE_CELEMENTGENSHADERS_HPP__ #define __URDE_CELEMENTGENSHADERS_HPP__ +#include "TShader.hpp" #include "Graphics/CGraphics.hpp" #include "boo/graphicsdev/GL.hpp" #include "boo/graphicsdev/D3D.hpp" @@ -13,15 +14,11 @@ class CElementGen; class CElementGenShaders { + friend struct OGLElementDataBindingFactory; + friend struct VulkanElementDataBindingFactory; + friend struct D3DElementDataBindingFactory; + friend struct MetalElementDataBindingFactory; public: - struct IDataBindingFactory - { - virtual void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, - CElementGen& gen, - boo::IShaderPipeline* regPipeline, - boo::IShaderPipeline* redToAlphaPipeline)=0; - }; - enum class EShaderClass { Tex, @@ -58,25 +55,19 @@ private: static boo::IVertexFormat* m_vtxFormatIndTex; /* No OpenGL */ static boo::IVertexFormat* m_vtxFormatNoTex; /* No OpenGL */ - static std::unique_ptr m_bindFactory; - static boo::GraphicsDataToken m_gfxToken; + CElementGen& m_gen; + boo::IShaderPipeline* m_regPipeline; + boo::IShaderPipeline* m_redToAlphaPipeline; + CElementGenShaders(CElementGen& gen, boo::IShaderPipeline* regPipeline, + boo::IShaderPipeline* redToAlphaPipeline) + : m_gen(gen), m_regPipeline(regPipeline), m_redToAlphaPipeline(redToAlphaPipeline) {} public: - static IDataBindingFactory* Initialize(boo::GLDataFactory::Context& ctx); -#if _WIN32 - static IDataBindingFactory* Initialize(boo::ID3DDataFactory::Context& ctx); -#endif -#if BOO_HAS_METAL - static IDataBindingFactory* Initialize(boo::MetalDataFactory::Context& ctx); -#endif -#if BOO_HAS_VULKAN - static IDataBindingFactory* Initialize(boo::VulkanDataFactory::Context& ctx); -#endif - - static void Initialize(); - static void Shutdown(); static EShaderClass GetShaderClass(CElementGen& gen); static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen); + + using _CLS = CElementGenShaders; +#include "TShaderDecl.hpp" }; } diff --git a/Runtime/Particle/CElementGenShadersGLSL.cpp b/Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp similarity index 97% rename from Runtime/Particle/CElementGenShadersGLSL.cpp rename to Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp index 170561b41..cbf390b28 100644 --- a/Runtime/Particle/CElementGenShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp @@ -1,8 +1,8 @@ #include "CElementGenShaders.hpp" -#include "CElementGen.hpp" -#include "CGenDescription.hpp" -#include "CElectricDescription.hpp" -#include "CSwooshDescription.hpp" +#include "Particle/CElementGen.hpp" +#include "Particle/CGenDescription.hpp" +#include "Particle/CElectricDescription.hpp" +#include "Particle/CSwooshDescription.hpp" #include "Graphics/CModel.hpp" namespace urde @@ -190,13 +190,12 @@ BOO_GLSL_BINDING_HEAD " colorOut = vtf.color;\n" "}\n"; -struct OGLElementDataBindingFactory : CElementGenShaders::IDataBindingFactory +struct OGLElementDataBindingFactory : TShader::IDataBindingFactory { - void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, - CElementGen& gen, - boo::IShaderPipeline* regPipeline, - boo::IShaderPipeline* redToAlphaPipeline) + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CElementGenShaders& shader) { + CElementGen& gen = shader.m_gen; CGenDescription* desc = gen.GetDesc(); boo::IVertexFormat* vtxFmt = nullptr; @@ -262,14 +261,15 @@ struct OGLElementDataBindingFactory : CElementGenShaders::IDataBindingFactory boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - if (regPipeline) - gen.m_normalDataBind = ctx.newShaderDataBinding(regPipeline, vtxFmt, nullptr, + if (shader.m_regPipeline) + gen.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipeline, vtxFmt, nullptr, gen.m_instBuf, nullptr, 1, uniforms, nullptr, texCount, textures, nullptr, nullptr); - if (redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(redToAlphaPipeline, vtxFmt, nullptr, + if (shader.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, vtxFmt, nullptr, gen.m_instBuf, nullptr, 1, uniforms, nullptr, texCount, textures, nullptr, nullptr); + return nullptr; } }; @@ -277,7 +277,7 @@ static const char* UniNames[] = {"ParticleUniform"}; static const char* TexNames[] = {"tex"}; static const char* TindTexNames[] = {"texrMap", "sceneMap", "tindMap"}; -CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::GLDataFactory::Context& ctx) +TShader::IDataBindingFactory* CElementGenShaders::Initialize(boo::GLDataFactory::Context& ctx) { m_texZTestZWrite = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, diff --git a/Runtime/Particle/CElementGenShadersHLSL.cpp b/Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp similarity index 95% rename from Runtime/Particle/CElementGenShadersHLSL.cpp rename to Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp index 4e21e9237..2b4a6bcbd 100644 --- a/Runtime/Particle/CElementGenShadersHLSL.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp @@ -1,8 +1,8 @@ #include "CElementGenShaders.hpp" -#include "CElementGen.hpp" -#include "CGenDescription.hpp" -#include "CElectricDescription.hpp" -#include "CSwooshDescription.hpp" +#include "Particle/CElementGen.hpp" +#include "Particle/CGenDescription.hpp" +#include "Particle/CElectricDescription.hpp" +#include "Particle/CSwooshDescription.hpp" #include "Graphics/CModel.hpp" namespace urde @@ -188,13 +188,12 @@ static const char* FS_HLSL_NOTEX = " return vtf.color;\n" "}\n"; -struct D3DElementDataBindingFactory : CElementGenShaders::IDataBindingFactory +struct D3DElementDataBindingFactory : TShader::IDataBindingFactory { - void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, - CElementGen& gen, - boo::IShaderPipeline* regPipeline, - boo::IShaderPipeline* redToAlphaPipeline) + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CElementGenShaders& shaders) { + CElementGen& gen = shaders.m_gen; CGenDescription* desc = gen.GetDesc(); CUVElement* texr = desc->x54_x40_TEXR.get(); @@ -216,20 +215,22 @@ struct D3DElementDataBindingFactory : CElementGenShaders::IDataBindingFactory boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - if (regPipeline) - gen.m_normalDataBind = ctx.newShaderDataBinding(regPipeline, nullptr, nullptr, + if (shaders.m_regPipeline) + gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, nullptr, nullptr, gen.m_instBuf, nullptr, 1, uniforms, nullptr, texCount, textures, nullptr, nullptr); - if (redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(redToAlphaPipeline, nullptr, nullptr, + if (shaders.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr, gen.m_instBuf, nullptr, 1, uniforms, nullptr, texCount, textures, nullptr, nullptr); + + return nullptr; } }; -CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::ID3DDataFactory::Context& ctx) +TShader::IDataBindingFactory* CElementGenShaders::Initialize(boo::ID3DDataFactory::Context& ctx) { static const boo::VertexElementDescriptor TexFmtTex[] = { diff --git a/Runtime/Particle/CElementGenShadersMetal.cpp b/Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp similarity index 96% rename from Runtime/Particle/CElementGenShadersMetal.cpp rename to Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp index 6c08d83cb..709d0d06f 100644 --- a/Runtime/Particle/CElementGenShadersMetal.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp @@ -1,7 +1,6 @@ #include "CElementGenShaders.hpp" -#if BOO_HAS_METAL -#include "CElementGen.hpp" -#include "CGenDescription.hpp" +#include "Particle/CElementGen.hpp" +#include "Particle/CGenDescription.hpp" namespace urde { @@ -210,13 +209,12 @@ static const char* FS_METAL_NOTEX = " return vtf.color;\n" "}\n"; -struct MetalElementDataBindingFactory : CElementGenShaders::IDataBindingFactory +struct MetalElementDataBindingFactory : TShader::IDataBindingFactory { - void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, - CElementGen& gen, - boo::IShaderPipeline* regPipeline, - boo::IShaderPipeline* redToAlphaPipeline) + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CElementGenShaders& shader) { + CElementGen& gen = shader.m_gen; CGenDescription* desc = gen.GetDesc(); CUVElement* texr = desc->x54_x40_TEXR.get(); @@ -238,18 +236,20 @@ struct MetalElementDataBindingFactory : CElementGenShaders::IDataBindingFactory boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - if (regPipeline) - gen.m_normalDataBind = ctx.newShaderDataBinding(regPipeline, nullptr, nullptr, + if (shader.m_regPipeline) + gen.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipeline, nullptr, nullptr, gen.m_instBuf, nullptr, 1, uniforms, nullptr, texCount, textures, nullptr, nullptr); - if (redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(redToAlphaPipeline, nullptr, nullptr, + if (shader.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, nullptr, nullptr, gen.m_instBuf, nullptr, 1, uniforms, nullptr, texCount, textures, nullptr, nullptr); + + return nullptr; } }; -CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::MetalDataFactory::Context& ctx) +TShader::IDataBindingFactory* CElementGenShaders::Initialize(boo::MetalDataFactory::Context& ctx) { static const boo::VertexElementDescriptor TexFmtTex[] = { @@ -381,4 +381,3 @@ CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::Met } } -#endif diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp b/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp new file mode 100644 index 000000000..b1083fa93 --- /dev/null +++ b/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp @@ -0,0 +1,78 @@ +#include "CParticleSwooshShaders.hpp" +#include "Particle/CParticleSwoosh.hpp" +#include "Particle/CSwooshDescription.hpp" + +namespace urde +{ + +boo::IShaderPipeline* CParticleSwooshShaders::m_texZWrite = nullptr; +boo::IShaderPipeline* CParticleSwooshShaders::m_texNoZWrite = nullptr; +boo::IShaderPipeline* CParticleSwooshShaders::m_texAdditiveZWrite = nullptr; +boo::IShaderPipeline* CParticleSwooshShaders::m_texAdditiveNoZWrite = nullptr; + +boo::IShaderPipeline* CParticleSwooshShaders::m_noTexZWrite = nullptr; +boo::IShaderPipeline* CParticleSwooshShaders::m_noTexNoZWrite = nullptr; +boo::IShaderPipeline* CParticleSwooshShaders::m_noTexAdditiveZWrite = nullptr; +boo::IShaderPipeline* CParticleSwooshShaders::m_noTexAdditiveNoZWrite = nullptr; + +boo::IVertexFormat* CParticleSwooshShaders::m_vtxFormat = nullptr; + +CParticleSwooshShaders::EShaderClass CParticleSwooshShaders::GetShaderClass(CParticleSwoosh& gen) +{ + CSwooshDescription* desc = gen.GetDesc(); + + if (desc->x3c_TEXR) + return EShaderClass::Tex; + else + return EShaderClass::NoTex; +} + +void CParticleSwooshShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CParticleSwoosh& gen) +{ + CSwooshDescription* desc = gen.GetDesc(); + boo::IShaderPipeline* pipeline = nullptr; + + if (desc->x3c_TEXR) + { + if (desc->x44_31_AALP) + { + if (desc->x45_24_ZBUF) + pipeline = m_texAdditiveZWrite; + else + pipeline = m_texAdditiveNoZWrite; + } + else + { + if (desc->x45_24_ZBUF) + pipeline = m_texZWrite; + else + pipeline = m_texNoZWrite; + } + } + else + { + if (desc->x44_31_AALP) + { + if (desc->x45_24_ZBUF) + pipeline = m_noTexAdditiveZWrite; + else + pipeline = m_noTexAdditiveNoZWrite; + } + else + { + if (desc->x45_24_ZBUF) + pipeline = m_noTexZWrite; + else + pipeline = m_noTexNoZWrite; + } + } + + CParticleSwooshShaders shad(gen, pipeline); + TShader::BuildShaderDataBinding(ctx, shad); +} + +void CParticleSwooshShaders::Shutdown() {} + +URDE_SPECIALIZE_SHADER(CParticleSwooshShaders) + +} diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp b/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp new file mode 100644 index 000000000..acc02362a --- /dev/null +++ b/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp @@ -0,0 +1,63 @@ +#ifndef __URDE_CPARTICLESWOOSHSHADERS_HPP__ +#define __URDE_CPARTICLESWOOSHSHADERS_HPP__ + +#include "TShader.hpp" +#include "Graphics/CGraphics.hpp" +#include "boo/graphicsdev/GL.hpp" +#include "boo/graphicsdev/D3D.hpp" +#include "boo/graphicsdev/Metal.hpp" +#include "boo/graphicsdev/Vulkan.hpp" + +namespace urde +{ +class CParticleSwoosh; + +class CParticleSwooshShaders +{ + friend struct OGLParticleSwooshDataBindingFactory; + friend struct VulkanParticleSwooshDataBindingFactory; + friend struct D3DParticleSwooshDataBindingFactory; + friend struct MetalParticleSwooshDataBindingFactory; +public: + enum class EShaderClass + { + Tex, + NoTex + }; + + struct Vert + { + zeus::CVector3f m_pos; + zeus::CVector2f m_uv; + zeus::CColor m_color; + }; + +private: + static boo::IShaderPipeline* m_texZWrite; + static boo::IShaderPipeline* m_texNoZWrite; + static boo::IShaderPipeline* m_texAdditiveZWrite; + static boo::IShaderPipeline* m_texAdditiveNoZWrite; + + static boo::IShaderPipeline* m_noTexZWrite; + static boo::IShaderPipeline* m_noTexNoZWrite; + static boo::IShaderPipeline* m_noTexAdditiveZWrite; + static boo::IShaderPipeline* m_noTexAdditiveNoZWrite; + + static boo::IVertexFormat* m_vtxFormat; /* No OpenGL */ + + CParticleSwoosh& m_gen; + boo::IShaderPipeline* m_pipeline; + CParticleSwooshShaders(CParticleSwoosh& gen, boo::IShaderPipeline* pipeline) + : m_gen(gen), m_pipeline(pipeline) {} + +public: + static EShaderClass GetShaderClass(CParticleSwoosh& gen); + static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CParticleSwoosh& gen); + + using _CLS = CParticleSwooshShaders; +#include "TShaderDecl.hpp" +}; + +} + +#endif // __URDE_CPARTICLESWOOSHSHADERS_HPP__ diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShadersGLSL.cpp b/Runtime/Graphics/Shaders/CParticleSwooshShadersGLSL.cpp new file mode 100644 index 000000000..347b27b89 --- /dev/null +++ b/Runtime/Graphics/Shaders/CParticleSwooshShadersGLSL.cpp @@ -0,0 +1,204 @@ +#include "CParticleSwooshShaders.hpp" +#include "Particle/CParticleSwoosh.hpp" +#include "Particle/CSwooshDescription.hpp" + +namespace urde +{ + +static const char* VS = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"layout(location=0) in vec4 posIn;\n" +"layout(location=1) in vec4 uvIn;\n" +"layout(location=2) in vec4 colorIn;\n" +"\n" +"UBINDING0 uniform SwooshUniform\n" +"{\n" +" mat4 mvp;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" vec4 color;\n" +" vec2 uv;\n" +"};\n" +"\n" +"SBINDING(0) out VertToFrag vtf;\n" +"void main()\n" +"{\n" +" vtf.color = colorIn;\n" +" vtf.uv = uvIn;\n" +" gl_Position = mvp * vec4(posIn.xyz, 1.0);\n" +"}\n"; + +static const char* FS_TEX = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"struct VertToFrag\n" +"{\n" +" vec4 color;\n" +" vec2 uv;\n" +"};\n" +"\n" +"SBINDING(0) in VertToFrag vtf;\n" +"layout(location=0) out vec4 colorOut;\n" +"TBINDING0 uniform sampler2D tex;\n" +"void main()\n" +"{\n" +" colorOut = vtf.color * texture(tex, vtf.uv);\n" +"}\n"; + +static const char* FS_NOTEX = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"struct VertToFrag\n" +"{\n" +" vec4 color;\n" +" vec2 uv;\n" +"};\n" +"\n" +"SBINDING(0) in VertToFrag vtf;\n" +"layout(location=0) out vec4 colorOut;\n" +"void main()\n" +"{\n" +" colorOut = vtf.color;\n" +"}\n"; + +struct OGLParticleSwooshDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CParticleSwooshShaders& shaders) + { + CParticleSwoosh& gen = shaders.m_gen; + CSwooshDescription* desc = gen.GetDesc(); + + CUVElement* texr = desc->x3c_TEXR.get(); + boo::ITexture* textures[] = {texr->GetValueTexture(0).GetObj()->GetBooTexture()}; + + const boo::VertexElementDescriptor VtxFmt[] = + { + {gen.m_vertBuf, nullptr, boo::VertexSemantic::Position4}, + {gen.m_vertBuf, nullptr, boo::VertexSemantic::UV4}, + {gen.m_vertBuf, nullptr, boo::VertexSemantic::Color}, + }; + boo::IVertexFormat* vtxFmt = ctx.newVertexFormat(3, VtxFmt); + + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, vtxFmt, gen.m_vertBuf, + nullptr, nullptr, 1, uniforms, + nullptr, texr ? 1 : 0, textures, nullptr, nullptr); + return nullptr; + } +}; + +static const char* UniNames[] = {"SwooshUniform"}; +static const char* TexNames[] = {"tex"}; + +TShader::IDataBindingFactory* CParticleSwooshShaders::Initialize(boo::GLDataFactory::Context& ctx) +{ + m_texZWrite = ctx.newShaderPipeline(VS, FS_TEX, 1, TexNames, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_texNoZWrite = ctx.newShaderPipeline(VS, FS_TEX, 1, TexNames, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + m_texAdditiveZWrite = ctx.newShaderPipeline(VS, FS_TEX, 1, TexNames, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_texAdditiveNoZWrite = ctx.newShaderPipeline(VS, FS_TEX, 1, TexNames, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + + m_noTexZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, 0, nullptr, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_noTexNoZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, 0, nullptr, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + m_noTexAdditiveZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, 0, nullptr, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_noTexAdditiveNoZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, 0, nullptr, 1, UniNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + + return new struct OGLParticleSwooshDataBindingFactory; +} + +#if BOO_HAS_VULKAN +struct VulkanParticleSwooshDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CParticleSwooshShaders& shaders) + { + CParticleSwoosh& gen = shaders.m_gen; + CSwooshDescription* desc = gen.GetDesc(); + + CUVElement* texr = desc->x3c_TEXR.get(); + boo::ITexture* textures[] = {texr->GetValueTexture(0).GetObj()->GetBooTexture()}; + + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, CParticleSwooshShaders::m_vtxFormat, + gen.m_vertBuf, nullptr, nullptr, 1, uniforms, + nullptr, texr ? 1 : 0, textures, nullptr, nullptr); + return nullptr; + } +}; + +TShader::IDataBindingFactory* CParticleSwooshShaders::Initialize(boo::VulkanDataFactory::Context& ctx) +{ + static const boo::VertexElementDescriptor VtxFmt[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::UV4}, + {nullptr, nullptr, boo::VertexSemantic::Color}, + }; + m_vtxFormat = ctx.newVertexFormat(3, VtxFmt); + + m_texZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_texNoZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + m_texAdditiveZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_texAdditiveNoZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + + m_noTexZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_noTexNoZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + m_noTexAdditiveZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_noTexAdditiveNoZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + + return new struct VulkanParticleSwooshDataBindingFactory; +} +#endif + +} diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShadersHLSL.cpp b/Runtime/Graphics/Shaders/CParticleSwooshShadersHLSL.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShadersMetal.cpp b/Runtime/Graphics/Shaders/CParticleSwooshShadersMetal.cpp new file mode 100644 index 000000000..8c6d698f6 --- /dev/null +++ b/Runtime/Graphics/Shaders/CParticleSwooshShadersMetal.cpp @@ -0,0 +1,138 @@ +#include "CParticleSwooshShaders.hpp" +#include "Particle/CParticleSwoosh.hpp" +#include "Particle/CSwooshDescription.hpp" + +namespace urde +{ + +static const char* VS = +"#include \n" +"using namespace metal;\n" +"struct VertData\n" +"{\n" +" float4 posIn [[ attribute(0) ]];\n" +" float4 uvIn [[ attribute(1) ]];\n" +" float4 colorIn [[ attribute(2) ]];\n" +"};\n" +"\n" +"struct SwooshUniform\n" +"{\n" +" float4x4 mvp;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" float4 pos [[ position ]];\n" +" float4 color;\n" +" float2 uv;\n" +"};\n" +"\n" +"SBINDING(0) out VertToFrag vtf;\n" +"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SwooshUniform& su [[ buffer(2) ]])\n" +"{\n" +" VertToFrag vtf;\n" +" vtf.color = v.colorIn;\n" +" vtf.uv = v.uvIn;\n" +" vtf.pos = su.mvp * float4(v.posIn.xyz, 1.0);\n" +" return vtf;\n" +"}\n"; + +static const char* FS_TEX = +"#include \n" +"using namespace metal;\n" +"constexpr sampler samp(address::repeat, filter::linear);\n" +"struct VertToFrag\n" +"{\n" +" float4 pos [[ position ]];\n" +" float4 color;\n" +" float2 uv;\n" +"};\n" +"\n" +"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n" +" texture2d tex [[ texture(0) ]])\n" +"{\n" +" return vtf.color * tex.sample(samp, vtf.uv);\n" +"}\n"; + +static const char* FS_NOTEX = +"#include \n" +"using namespace metal;\n" +"struct VertToFrag\n" +"{\n" +" float4 pos [[ position ]];\n" +" float4 color;\n" +" float2 uv;\n" +"};\n" +"\n" +"fragment float4 fmain(VertToFrag vtf [[ stage_in ]])\n" +"{\n" +" return vtf.color;\n" +"}\n"; + +struct MetalParticleSwooshDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, + CParticleSwooshShaders& shaders) + { + CParticleSwoosh& gen = shaders.m_gen; + CSwooshDescription* desc = gen.GetDesc(); + + CUVElement* texr = desc->x3c_TEXR.get(); + boo::ITexture* textures[] = {texr->GetValueTexture(0).GetObj()->GetBooTexture()}; + + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + gen.m_dataBind = ctx.newShaderDataBinding(shaders.m_pipeline, CParticleSwooshShaders::m_vtxFormat, + gen.m_vertBuf, nullptr, nullptr, 1, uniforms, + nullptr, texr ? 1 : 0, textures, nullptr, nullptr); + return nullptr; + } +}; + +TShader::IDataBindingFactory* CParticleSwooshShaders::Initialize(boo::MetalDataFactory::Context& ctx) +{ + static const boo::VertexElementDescriptor VtxFmt[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::UV4}, + {nullptr, nullptr, boo::VertexSemantic::Color}, + }; + m_vtxFormat = ctx.newVertexFormat(3, VtxFmt); + + m_texZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_texNoZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + m_texAdditiveZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_texAdditiveNoZWrite = ctx.newShaderPipeline(VS, FS_TEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + + m_noTexZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_noTexNoZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + m_noTexAdditiveZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, true, + true, false, boo::CullMode::None); + m_noTexAdditiveNoZWrite = ctx.newShaderPipeline(VS, FS_NOTEX, m_vtxFormat, CGraphics::g_ViewportSamples, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::One, + boo::Primitive::TriStrips, boo::ZTest::LEqual, false, + true, false, boo::CullMode::None); + + return new struct MetalParticleSwooshDataBindingFactory; +} + +} diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index 4a05e651c..2e3b5f8e6 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -7,7 +7,7 @@ #include "CParticleElectric.hpp" #include "Graphics/CModel.hpp" -#include "CElementGenShaders.hpp" +#include "Graphics/Shaders/CElementGenShaders.hpp" #define MAX_GLOBAL_PARTICLES 2560 @@ -15,6 +15,8 @@ namespace urde { static logvisor::Module Log("urde::CElementGen"); +URDE_DECL_SPECIALIZE_SHADER(CElementGenShaders) + CRandom16 CElementGen::g_GlobalSeed = 99; int CElementGen::g_ParticleAliveCount; @@ -23,190 +25,6 @@ bool CElementGen::g_ParticleSystemInitialized = false; bool CElementGen::sMoveRedToAlphaBuffer = false; CElementGen::CParticle* CElementGen::g_currentParticle = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texZTestZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texNoZTestZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texZTestNoZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texNoZTestNoZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texAdditiveZTest = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texAdditiveNoZTest = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaZTest = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_texRedToAlphaNoZTest = nullptr; - -boo::IShaderPipeline* CElementGenShaders::m_indTexZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_indTexNoZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_indTexAdditive = nullptr; - -boo::IShaderPipeline* CElementGenShaders::m_cindTexZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_cindTexNoZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_cindTexAdditive = nullptr; - -boo::IShaderPipeline* CElementGenShaders::m_noTexZTestZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_noTexNoZTestZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_noTexZTestNoZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_noTexNoZTestNoZWrite = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_noTexAdditiveZTest = nullptr; -boo::IShaderPipeline* CElementGenShaders::m_noTexAdditiveNoZTest = nullptr; - -boo::IVertexFormat* CElementGenShaders::m_vtxFormatTex = nullptr; -boo::IVertexFormat* CElementGenShaders::m_vtxFormatIndTex = nullptr; -boo::IVertexFormat* CElementGenShaders::m_vtxFormatNoTex = nullptr; - -std::unique_ptr CElementGenShaders::m_bindFactory; -boo::GraphicsDataToken CElementGenShaders::m_gfxToken; - -CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) -{ - CGenDescription* desc = gen.x1c_genDesc.GetObj(); - - if (desc->x54_x40_TEXR) - { - if (desc->x58_x44_TIND) - return EShaderClass::IndTex; - else - return EShaderClass::Tex; - } - else - return EShaderClass::NoTex; -} - -void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen) -{ - CGenDescription* desc = gen.x1c_genDesc.GetObj(); - boo::IShaderPipeline* regPipeline = nullptr; - boo::IShaderPipeline* redToAlphaPipeline = nullptr; - - if (desc->x54_x40_TEXR) - { - if (desc->x58_x44_TIND) - { - if (desc->x45_30_x32_24_CIND) - { - if (gen.x26c_26_AAPH) - regPipeline = m_cindTexAdditive; - else - { - if (gen.x26c_27_ZBUF) - regPipeline = m_cindTexZWrite; - else - regPipeline = m_cindTexNoZWrite; - } - } - else - { - if (gen.x26c_26_AAPH) - regPipeline = m_indTexAdditive; - else - { - if (gen.x26c_27_ZBUF) - regPipeline = m_indTexZWrite; - else - regPipeline = m_indTexNoZWrite; - } - } - } - else - { - if (gen.x26c_28_zTest) - redToAlphaPipeline = m_texRedToAlphaZTest; - else - redToAlphaPipeline = m_texRedToAlphaNoZTest; - - if (gen.x26c_26_AAPH) - { - if (gen.x26c_28_zTest) - regPipeline = m_texAdditiveZTest; - else - regPipeline = m_texAdditiveNoZTest; - } - else - { - if (gen.x26c_28_zTest) - { - if (gen.x26c_27_ZBUF) - regPipeline = m_texZTestZWrite; - else - regPipeline = m_texZTestNoZWrite; - } - else - { - if (gen.x26c_27_ZBUF) - regPipeline = m_texNoZTestZWrite; - else - regPipeline = m_texNoZTestNoZWrite; - } - } - } - } - else - { - if (gen.x26c_26_AAPH) - { - if (gen.x26c_28_zTest) - regPipeline = m_noTexAdditiveZTest; - else - regPipeline = m_noTexAdditiveNoZTest; - } - else - { - if (gen.x26c_28_zTest) - { - if (gen.x26c_27_ZBUF) - regPipeline = m_noTexZTestZWrite; - else - regPipeline = m_noTexZTestNoZWrite; - } - else - { - if (gen.x26c_27_ZBUF) - regPipeline = m_noTexNoZTestZWrite; - else - regPipeline = m_noTexNoZTestNoZWrite; - } - } - } - - m_bindFactory->BuildShaderDataBinding(ctx, gen, regPipeline, redToAlphaPipeline); -} - -void CElementGenShaders::Initialize() -{ - if (!CGraphics::g_BooFactory) - return; - - m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool - { - switch (ctx.platform()) - { - case boo::IGraphicsDataFactory::Platform::OpenGL: - m_bindFactory.reset(Initialize(static_cast(ctx))); - break; -#if _WIN32 - case boo::IGraphicsDataFactory::Platform::D3D11: - case boo::IGraphicsDataFactory::Platform::D3D12: - m_bindFactory.reset(Initialize(static_cast(ctx))); - break; -#endif -#if BOO_HAS_METAL - case boo::IGraphicsDataFactory::Platform::Metal: - m_bindFactory.reset(Initialize(static_cast(ctx))); - break; -#endif -#if BOO_HAS_VULKAN - case boo::IGraphicsDataFactory::Platform::Vulkan: - m_bindFactory.reset(Initialize(static_cast(ctx))); - break; -#endif - default: break; - } - return true; - }); -} - -void CElementGenShaders::Shutdown() -{ - m_gfxToken.doDestroy(); -} - struct SParticleInstanceTex { zeus::CVector4f pos[4]; @@ -247,12 +65,12 @@ void CElementGen::Initialize() g_ParticleSystemInitialized = true; /* Compile shaders */ - CElementGenShaders::Initialize(); + TShader::Initialize(); } void CElementGen::Shutdown() { - CElementGenShaders::Shutdown(); + TShader::Shutdown(); } static const size_t ShadClsSizes[] = diff --git a/Runtime/Particle/CElementGen.hpp b/Runtime/Particle/CElementGen.hpp index 48aa8c483..a4ee6ee5e 100644 --- a/Runtime/Particle/CElementGen.hpp +++ b/Runtime/Particle/CElementGen.hpp @@ -11,7 +11,7 @@ #include "Graphics/CGraphics.hpp" #include "CRandom16.hpp" #include "CParticleGen.hpp" -#include "CElementGenShaders.hpp" +#include "Graphics/Shaders/CElementGenShaders.hpp" #include "Graphics/CLineRenderer.hpp" #include "Particle/CGenDescription.hpp" diff --git a/Runtime/Particle/CMakeLists.txt b/Runtime/Particle/CMakeLists.txt index 48497f398..3df0ea25d 100644 --- a/Runtime/Particle/CMakeLists.txt +++ b/Runtime/Particle/CMakeLists.txt @@ -1,9 +1,3 @@ -if(WIN32) - set(PLAT_SRCS CElementGenShadersHLSL.cpp) -elseif(BOO_HAS_METAL) - set(PLAT_SRCS CElementGenShadersMetal.cpp) -endif() - set(PARTICLE_SOURCES IElement.hpp CGenDescription.hpp @@ -33,8 +27,6 @@ set(PARTICLE_SOURCES CWarp.hpp CWarp.cpp CFlameWarp.hpp CFlameWarp.cpp CParticleGlobals.hpp CParticleGlobals.cpp - CElementGenShaders.hpp - CElementGenShadersGLSL.cpp ${PLAT_SRCS}) runtime_add_list(Particle PARTICLE_SOURCES) diff --git a/Runtime/Particle/CParticleSwoosh.cpp b/Runtime/Particle/CParticleSwoosh.cpp index 2e4050cd9..8814ae62e 100644 --- a/Runtime/Particle/CParticleSwoosh.cpp +++ b/Runtime/Particle/CParticleSwoosh.cpp @@ -6,12 +6,14 @@ namespace urde { +URDE_DECL_SPECIALIZE_SHADER(CParticleSwooshShaders) + int CParticleSwoosh::g_ParticleSystemAliveCount = 0; CParticleSwoosh::CParticleSwoosh(const TToken& desc, int leng) - : x1c_desc(desc), x1c0_rand(x1c_desc->x45_26_CRND ? - std::chrono::duration_cast( - std::chrono::steady_clock::now().time_since_epoch()).count() : 99) +: x1c_desc(desc), x1c0_rand(x1c_desc->x45_26_CRND ? + std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch()).count() : 99) { x1d0_24_emitting = true; ++g_ParticleSystemAliveCount; @@ -56,6 +58,25 @@ CParticleSwoosh::CParticleSwoosh(const TToken& desc, int len x17c_p1.resize(x1b8_SIDE); x18c_p2.resize(x1b8_SIDE); x19c_p3.resize(x1b8_SIDE); + + if (x1c_desc->x44_29_WIRE) + { + int maxVerts = x1b4_LENG * (x1b0_SPLN+1) * x1b8_SIDE * 12; + m_lineRenderer.reset(new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines, + maxVerts * 2, nullptr, x1d0_25_AALP)); + } + else + { + int maxVerts = x1b4_LENG * (x1b0_SPLN+1) * x1b8_SIDE * 4; + m_cachedVerts.reserve(maxVerts); + m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool + { + m_vertBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(CParticleSwooshShaders::Vert), maxVerts); + m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CMatrix4f), 1); + CParticleSwooshShaders::BuildShaderDataBinding(ctx, *this); + return true; + }); + } } } @@ -308,11 +329,14 @@ int CParticleSwoosh::WrapIndex(int i) const void CParticleSwoosh::RenderNSidedSpline() { if (x1c_desc->x44_29_WIRE) + { x1bc_prim = GX::LINES; + m_lineRenderer->Reset(); + } else + { x1bc_prim = GX::QUADS; - - // StreamBegin(x1bc_prim); + } bool cros = x1c_desc->x44_25_CROS; if (x1b8_SIDE >= 4 || x1b8_SIDE & 0x1) @@ -442,8 +466,12 @@ void CParticleSwoosh::RenderNSidedSpline() zeus::CVector3f v1 = GetSplinePoint(x16c_p0[otherK], x17c_p1[otherK], x18c_p2[otherK], x19c_p3[otherK], t0); zeus::CVector3f v2 = GetSplinePoint(x16c_p0[otherK], x17c_p1[otherK], x18c_p2[otherK], x19c_p3[otherK], t1); zeus::CVector3f v3 = GetSplinePoint(x16c_p0[k], x17c_p1[k], x18c_p2[k], x19c_p3[k], t1); - // Render in quads - // UVs: {(x1d4, x1d8), (x1d4, x1e0), (x1dc, x1e0), (x1dc, x1d8)} + + m_cachedVerts.push_back({v0, {x1d4_uvs.xMin, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {x1d4_uvs.xMin, x1d4_uvs.yMax}, color}); + m_cachedVerts.push_back({v2, {x1d4_uvs.xMax, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v3, {x1d4_uvs.xMax, x1d4_uvs.yMax}, color}); + CGraphics::DrawArray(m_cachedVerts.size() - 4, 4); } else { @@ -454,13 +482,26 @@ void CParticleSwoosh::RenderNSidedSpline() if (x1bc_prim == GX::LINES) { - // Render in lines - // v0 -> v1 v1 -> v2 v2 -> v0 v0 -> v2 v2 -> v3 v3 -> v0 + m_lineRenderer->AddVertex(v0, color, 1.f); + m_lineRenderer->AddVertex(v1, color, 1.f); + m_lineRenderer->AddVertex(v1, color, 1.f); + m_lineRenderer->AddVertex(v2, color, 1.f); + m_lineRenderer->AddVertex(v2, color, 1.f); + m_lineRenderer->AddVertex(v0, color, 1.f); + m_lineRenderer->AddVertex(v0, color, 1.f); + m_lineRenderer->AddVertex(v2, color, 1.f); + m_lineRenderer->AddVertex(v2, color, 1.f); + m_lineRenderer->AddVertex(v3, color, 1.f); + m_lineRenderer->AddVertex(v3, color, 1.f); + m_lineRenderer->AddVertex(v0, color, 1.f); } else if (x1bc_prim == GX::QUADS) { - // Render in quads - // UVs: {(x1d4, x1d8), (x1d4, x1e0), (x1dc, x1e0), (x1dc, x1d8)} + m_cachedVerts.push_back({v0, {x1d4_uvs.xMin, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {x1d4_uvs.xMin, x1d4_uvs.yMax}, color}); + m_cachedVerts.push_back({v2, {x1d4_uvs.xMax, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v3, {x1d4_uvs.xMax, x1d4_uvs.yMax}, color}); + CGraphics::DrawArray(m_cachedVerts.size() - 4, 4); } } } @@ -474,7 +515,8 @@ void CParticleSwoosh::RenderNSidedSpline() curIdx = x15c_swooshes.size() - 1; } - // StreamEnd(); + if (x1bc_prim == GX::LINES) + m_lineRenderer->Render(); } void CParticleSwoosh::RenderNSidedNoSpline() @@ -560,7 +602,6 @@ void CParticleSwoosh::Render3SidedSolidSpline() { //int vertCount = (x1b0_SPLN + 1) * 12; float uv1 = 0.f; - // begin quads zeus::CColor useColor1 = prevColor1; zeus::CVector3f v01 = zeus::CVector3f::skZero; zeus::CVector3f v11 = zeus::CVector3f::skZero; @@ -592,13 +633,24 @@ void CParticleSwoosh::Render3SidedSolidSpline() c1 = zeus::CColor::lerp(useColor0, useColor1, t1); uv1 = t1 * uvDelta + curUvSpan; - // Draw: v00, v10, v11, v01, v10, v20, v21, v11, v20, v00, v01, v21 - // Color: c0, c0, c1, c1, c0, c0, c1, c1, c0, c0, c1, c1 - // UVs: (uv0, yMin), (uv0, yMax), (uv1, yMax), (uv1, yMin), - // (uv0, yMin), (uv0, yMax), (uv1, yMax), (uv1, yMin), - // (uv0, yMin), (uv0, yMax), (uv1, yMax), (uv1, yMin), + m_cachedVerts.push_back({v00, {uv0, x1d4_uvs.yMin}, c0}); + m_cachedVerts.push_back({v10, {uv0, x1d4_uvs.yMax}, c0}); + m_cachedVerts.push_back({v01, {uv1, x1d4_uvs.yMin}, c1}); + m_cachedVerts.push_back({v11, {uv1, x1d4_uvs.yMax}, c1}); + CGraphics::DrawArray(m_cachedVerts.size() - 4, 4); + + m_cachedVerts.push_back({v10, {uv0, x1d4_uvs.yMin}, c0}); + m_cachedVerts.push_back({v20, {uv0, x1d4_uvs.yMax}, c0}); + m_cachedVerts.push_back({v11, {uv1, x1d4_uvs.yMin}, c1}); + m_cachedVerts.push_back({v21, {uv1, x1d4_uvs.yMax}, c1}); + CGraphics::DrawArray(m_cachedVerts.size() - 4, 4); + + m_cachedVerts.push_back({v20, {uv0, x1d4_uvs.yMin}, c0}); + m_cachedVerts.push_back({v00, {uv0, x1d4_uvs.yMax}, c0}); + m_cachedVerts.push_back({v21, {uv1, x1d4_uvs.yMin}, c1}); + m_cachedVerts.push_back({v01, {uv1, x1d4_uvs.yMax}, c1}); + CGraphics::DrawArray(m_cachedVerts.size() - 4, 4); } - // End } } } @@ -616,6 +668,7 @@ void CParticleSwoosh::Render3SidedSolidNoSplineNoGaps() int curIdx = x158_curParticle; bool lastActive = false; zeus::CColor c0 = zeus::CColor::skClear; + float uv0 = -x1e8_uvSpan; for (int i=0 ; i= x15c_swooshes.size() - 2) continue; streaming = true; - // StreamBegin(TRISTRIPS); + drawStart = m_cachedVerts.size(); } float ang = zeus::degToRad(swoosh.x30_irot + swoosh.x34_rotm); @@ -737,19 +805,19 @@ void CParticleSwoosh::Render2SidedNoSplineGaps() zeus::CColor color = swoosh.x6c_color * x20c_moduColor; - // Draw: v0, v1, v0, v1 - // UVs: (1.0, yMin), (1.0, yMax), (0.0, yMin), (0.0, yMax) + m_cachedVerts.push_back({v0, {1.f, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {1.f, x1d4_uvs.yMax}, color}); + m_cachedVerts.push_back({v0, {0.f, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {0.f, x1d4_uvs.yMax}, color}); } if (streaming) - { - // StreamEnd(); - } + CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart); } void CParticleSwoosh::Render2SidedNoSplineNoGaps() { - // StreamBegin(TRISTRIPS); + int drawStart = 0; int curIdx = x158_curParticle; int particleCount = x1ac_particleCount; float uvOffset = 0.f; @@ -795,15 +863,15 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() zeus::CColor color = swoosh.x6c_color * x20c_moduColor; - // Draw: (v1, v2) - // UVs: (uvOffset, yMin), (uvOffset, yMax) + m_cachedVerts.push_back({v0, {uvOffset, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {uvOffset, x1d4_uvs.yMax}, color}); if (uvOffset >= 1.f && particleCount) { - // StreamEnd(); - // StreamBegin(TRISTRIPS); + CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart); + drawStart = m_cachedVerts.size(); uvOffset -= 1.f; - // Draw: (v1, v2) - // UVs: (uvOffset, yMin), (uvOffset, yMax) + m_cachedVerts.push_back({v0, {uvOffset, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {uvOffset, x1d4_uvs.yMax}, color}); } if (x1ec_TSPN > 0) @@ -850,15 +918,15 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() zeus::CColor color = swoosh.x6c_color * x20c_moduColor; - // Draw: (v1, v2) - // UVs: (uvOffset, yMin), (uvOffset, yMax) + m_cachedVerts.push_back({v0, {uvOffset, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {uvOffset, x1d4_uvs.yMax}, color}); if (uvOffset >= 1.f && particleCount) { - // StreamEnd(); - // StreamBegin(TRISTRIPS); + CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart); + drawStart = m_cachedVerts.size(); uvOffset -= 1.f; - // Draw: (v1, v2) - // UVs: (uvOffset, yMin), (uvOffset, yMax) + m_cachedVerts.push_back({v0, {uvOffset, x1d4_uvs.yMin}, color}); + m_cachedVerts.push_back({v1, {uvOffset, x1d4_uvs.yMax}, color}); } if (x1ec_TSPN > 0) @@ -901,11 +969,13 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() zeus::CVector3f(-cosAng * swoosh.x8_rightRad, 0.f, -sinAng * swoosh.x8_rightRad) + useOffset; zeus::CColor color = swoosh.x6c_color * x20c_moduColor; - // Draw: (v1, v2) + m_cachedVerts.push_back({v0, {}, color}); + m_cachedVerts.push_back({v1, {}, color}); } } } - // StreamEnd(); + + CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart); } void CParticleSwoosh::Render() @@ -913,6 +983,10 @@ void CParticleSwoosh::Render() if (x1b4_LENG < 2 || x1ac_particleCount <= 1) return; + m_cachedVerts.clear(); + if (m_dataBind) + CGraphics::SetShaderDataBinding(m_dataBind); + CParticleGlobals::SetParticleLifetime(x1b4_LENG); CGlobalRandom gr(x1c0_rand); CGraphics::DisableAllLights(); @@ -983,6 +1057,11 @@ void CParticleSwoosh::Render() else RenderNSidedNoSpline(); } + + zeus::CMatrix4f mvp = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniformBuf->load(&mvp, sizeof(zeus::CMatrix4f)); + if (m_cachedVerts.size()) + m_vertBuf->load(m_cachedVerts.data(), m_cachedVerts.size() * sizeof(CParticleSwooshShaders::Vert)); } void CParticleSwoosh::SetOrientation(const zeus::CTransform& xf) diff --git a/Runtime/Particle/CParticleSwoosh.hpp b/Runtime/Particle/CParticleSwoosh.hpp index 3882070a4..00d61f56a 100644 --- a/Runtime/Particle/CParticleSwoosh.hpp +++ b/Runtime/Particle/CParticleSwoosh.hpp @@ -5,8 +5,10 @@ #include "CToken.hpp" #include "CRandom16.hpp" #include "Graphics/CTexture.hpp" +#include "Graphics/CLineRenderer.hpp" #include "CUVElement.hpp" #include "DataSpec/DNACommon/GX.hpp" +#include "Graphics/Shaders/CParticleSwooshShaders.hpp" namespace urde { @@ -14,6 +16,11 @@ class CSwooshDescription; class CParticleSwoosh : public CParticleGen { + friend struct OGLParticleSwooshDataBindingFactory; + friend struct VulkanParticleSwooshDataBindingFactory; + friend struct D3DParticleSwooshDataBindingFactory; + friend struct MetalParticleSwooshDataBindingFactory; + struct SSwooshData { bool x0_active; @@ -93,6 +100,13 @@ class CParticleSwoosh : public CParticleGen float x208_maxRadius = 0.f; zeus::CColor x20c_moduColor = zeus::CColor::skWhite; + boo::GraphicsDataToken m_gfxToken; + boo::IShaderDataBinding* m_dataBind = nullptr; + boo::IGraphicsBufferD* m_vertBuf = nullptr; + boo::IGraphicsBufferD* m_uniformBuf = nullptr; + std::unique_ptr m_lineRenderer; + std::vector m_cachedVerts; + static int g_ParticleSystemAliveCount; bool IsValid() const { return x1b4_LENG >= 2 && x1b8_SIDE >= 2; } @@ -118,6 +132,8 @@ public: CParticleSwoosh(const TToken& desc, int); ~CParticleSwoosh(); + CSwooshDescription* GetDesc() { return x1c_desc.GetObj(); } + bool Update(double); void Render(); void SetOrientation(const zeus::CTransform&); diff --git a/nod b/nod index 7260012be..671e73c4b 160000 --- a/nod +++ b/nod @@ -1 +1 @@ -Subproject commit 7260012be57607149e312ac8565bc2fae9c7c972 +Subproject commit 671e73c4bc98a6a3f94c768a046b5489b524d63f diff --git a/specter b/specter index b1f6555cf..59f00d829 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit b1f6555cf27f8874da7460d8f6feed615c00e839 +Subproject commit 59f00d82970cd5a424775273988983d7ad0516a5