From 47e73f9f803bad2db9f067d61b031e0b88592190 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Mon, 12 Jun 2017 08:20:07 -1000 Subject: [PATCH] Add particle data binding for rendering PMUS quads --- .../Graphics/Shaders/CElementGenShaders.cpp | 24 ++- .../Graphics/Shaders/CElementGenShaders.hpp | 12 +- .../Shaders/CElementGenShadersGLSL.cpp | 174 +++++++++++++----- .../Shaders/CElementGenShadersHLSL.cpp | 36 +++- .../Shaders/CElementGenShadersMetal.cpp | 32 +++- Runtime/Particle/CElementGen.cpp | 103 +++++++++-- Runtime/Particle/CElementGen.hpp | 6 + 7 files changed, 305 insertions(+), 82 deletions(-) diff --git a/Runtime/Graphics/Shaders/CElementGenShaders.cpp b/Runtime/Graphics/Shaders/CElementGenShaders.cpp index b44ef00f3..772f76beb 100644 --- a/Runtime/Graphics/Shaders/CElementGenShaders.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShaders.cpp @@ -52,6 +52,8 @@ void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Conte CGenDescription* desc = gen.x1c_genDesc.GetObj(); boo::IShaderPipeline* regPipeline = nullptr; boo::IShaderPipeline* redToAlphaPipeline = nullptr; + boo::IShaderPipeline* regPipelinePmus = nullptr; + boo::IShaderPipeline* redToAlphaPipelinePmus = nullptr; if (desc->x54_x40_TEXR) { @@ -143,7 +145,27 @@ void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Conte } } - CElementGenShaders shad(gen, regPipeline, redToAlphaPipeline); + if (desc->x45_24_x31_26_PMUS) + { + if (desc->x54_x40_TEXR) + { + redToAlphaPipelinePmus = m_texRedToAlphaZTest; + if (desc->x44_31_x31_25_PMAB) + regPipelinePmus = m_texAdditiveZTest; + else + regPipelinePmus = m_texZTestZWrite; + } + else + { + if (desc->x44_31_x31_25_PMAB) + regPipelinePmus = m_noTexAdditiveZTest; + else + regPipelinePmus = m_noTexZTestZWrite; + } + } + + CElementGenShaders shad(gen, regPipeline, redToAlphaPipeline, + regPipelinePmus, redToAlphaPipelinePmus); TShader::BuildShaderDataBinding(ctx, shad); } diff --git a/Runtime/Graphics/Shaders/CElementGenShaders.hpp b/Runtime/Graphics/Shaders/CElementGenShaders.hpp index cc0eda3df..813a76d2e 100644 --- a/Runtime/Graphics/Shaders/CElementGenShaders.hpp +++ b/Runtime/Graphics/Shaders/CElementGenShaders.hpp @@ -58,9 +58,15 @@ private: 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) {} + boo::IShaderPipeline* m_regPipelinePmus; + boo::IShaderPipeline* m_redToAlphaPipelinePmus; + CElementGenShaders(CElementGen& gen, + boo::IShaderPipeline* regPipeline, + boo::IShaderPipeline* redToAlphaPipeline, + boo::IShaderPipeline* regPipelinePmus, + boo::IShaderPipeline* redToAlphaPipelinePmus) + : m_gen(gen), m_regPipeline(regPipeline), m_redToAlphaPipeline(redToAlphaPipeline), + m_regPipelinePmus(regPipelinePmus), m_redToAlphaPipelinePmus(redToAlphaPipelinePmus) {} public: static EShaderClass GetShaderClass(CElementGen& gen); diff --git a/Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp b/Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp index eb61f4225..12a4414a9 100644 --- a/Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShadersGLSL.cpp @@ -199,6 +199,7 @@ struct OGLElementDataBindingFactory : TShader::IDataBindingF CGenDescription* desc = gen.GetDesc(); boo::IVertexFormat* vtxFmt = nullptr; + boo::IVertexFormat* vtxFmtPmus = nullptr; CUVElement* texr = desc->x54_x40_TEXR.get(); CUVElement* tind = desc->x58_x44_TIND.get(); int texCount = 0; @@ -208,67 +209,120 @@ struct OGLElementDataBindingFactory : TShader::IDataBindingF { textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture(); texCount = 1; - if (tind) + if (gen.m_instBuf) { - textures[1] = CGraphics::g_SpareTexture; - textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture(); - texCount = 3; - - const boo::VertexElementDescriptor TexFmtIndTex[] = + if (tind) { - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 4}, - }; - vtxFmt = ctx.newVertexFormat(10, TexFmtIndTex); + textures[1] = CGraphics::g_SpareTexture; + textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture(); + texCount = 3; + + const boo::VertexElementDescriptor TexFmtIndTex[] = + { + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 4}, + }; + vtxFmt = ctx.newVertexFormat(10, TexFmtIndTex); + } + else + { + const boo::VertexElementDescriptor TexFmtTex[] = + { + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3} + }; + vtxFmt = ctx.newVertexFormat(9, TexFmtTex); + } } - else + if (gen.m_instBufPmus) { const boo::VertexElementDescriptor TexFmtTex[] = { - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3} + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3} }; - vtxFmt = ctx.newVertexFormat(9, TexFmtTex); + vtxFmtPmus = ctx.newVertexFormat(9, TexFmtTex); } } else { - const boo::VertexElementDescriptor TexFmtNoTex[] = + if (gen.m_instBuf) { - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, - {gen.m_instBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} - }; - vtxFmt = ctx.newVertexFormat(5, TexFmtNoTex); + const boo::VertexElementDescriptor TexFmtNoTex[] = + { + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {gen.m_instBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} + }; + vtxFmt = ctx.newVertexFormat(5, TexFmtNoTex); + } + if (gen.m_instBufPmus) + { + const boo::VertexElementDescriptor TexFmtNoTex[] = + { + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3}, + {gen.m_instBufPmus, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} + }; + vtxFmtPmus = ctx.newVertexFormat(5, TexFmtNoTex); + } } - boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + if (gen.m_instBuf) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - 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 (shader.m_redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, 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 (shader.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, vtxFmt, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + } + + if (gen.m_instBufPmus) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBufPmus}; + texCount = std::min(texCount, 1); + + if (shader.m_regPipelinePmus) + gen.m_normalDataBindPmus = ctx.newShaderDataBinding(shader.m_regPipelinePmus, vtxFmtPmus, nullptr, + gen.m_instBufPmus, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + if (shader.m_redToAlphaPipelinePmus) + gen.m_redToAlphaDataBindPmus = ctx.newShaderDataBinding(shader.m_redToAlphaPipelinePmus, vtxFmtPmus, nullptr, + gen.m_instBufPmus, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + } + return nullptr; } }; @@ -395,16 +449,34 @@ struct VulkanElementDataBindingFactory : TShader::IDataBindi } } - boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + if (gen.m_instBufPmus) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - 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 (shaders.m_redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, 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 (shaders.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + } + + if (gen.m_instBufPmus) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBufPmus}; + texCount = std::min(texCount, 1); + + if (shader.m_regPipelinePmus) + gen.m_normalDataBindPmus = ctx.newShaderDataBinding(shader.m_regPipelinePmus, nullptr, nullptr, + gen.m_instBufPmus, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + if (shader.m_redToAlphaPipelinePmus) + gen.m_redToAlphaDataBindPmus = ctx.newShaderDataBinding(shader.m_redToAlphaPipelinePmus, nullptr, nullptr, + gen.m_instBufPmus, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + } return nullptr; } diff --git a/Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp b/Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp index 2b4a6bcbd..80e1e0fa7 100644 --- a/Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShadersHLSL.cpp @@ -213,18 +213,38 @@ struct D3DElementDataBindingFactory : TShader::IDataBindingF } } - boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + if (gen.m_instBuf) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - 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 (shaders.m_redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, 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 (shaders.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + nullptr, texCount, textures, + nullptr, nullptr); + } + + if (gen.m_instBufPmus) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBufPmus}; + texCount = std::min(texCount, 1); + + if (shaders.m_regPipelinePmus) + gen.m_normalDataBindPmus = ctx.newShaderDataBinding(shaders.m_regPipelinePmus, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + nullptr, texCount, textures, + nullptr, nullptr); + if (shaders.m_redToAlphaPipelinePmus) + gen.m_redToAlphaDataBindPmus = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelinePmus, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + nullptr, texCount, textures, + nullptr, nullptr); + } return nullptr; } diff --git a/Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp b/Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp index 709d0d06f..9d1e28f36 100644 --- a/Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShadersMetal.cpp @@ -234,16 +234,34 @@ struct MetalElementDataBindingFactory : TShader::IDataBindin } } - boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; + if (gen.m_instBuf) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBuf}; - 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 (shader.m_redToAlphaPipeline) - gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, 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 (shader.m_redToAlphaPipeline) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, nullptr, nullptr, + gen.m_instBuf, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + } + + if (gen.m_instBufPmus) + { + boo::IGraphicsBuffer* uniforms[] = {gen.m_uniformBufPmus}; + texCount = std::min(texCount, 1); + + if (shader.m_regPipelinePmus) + gen.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipelinePmus, nullptr, nullptr, + gen.m_instBufPmus, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + if (shader.m_redToAlphaPipelinePmus) + gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipelinePmus, nullptr, nullptr, + gen.m_instBufPmus, nullptr, 1, uniforms, + nullptr, texCount, textures, nullptr, nullptr); + } return nullptr; } diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index 323553b09..c8bf3543f 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -253,16 +253,26 @@ CElementGen::CElementGen(const TToken& gen, else { m_shaderClass = CElementGenShaders::GetShaderClass(*this); - size_t maxInsts = x26c_30_MBLR ? (m_maxMBSP * x90_MAXP) : x90_MAXP; - maxInsts = (maxInsts == 0 ? 256 : maxInsts); - m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool + } + + size_t maxInsts = x26c_30_MBLR ? (m_maxMBSP * x90_MAXP) : x90_MAXP; + maxInsts = (maxInsts == 0 ? 256 : maxInsts); + + m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool + { + if (!x26c_31_LINE) { m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, ShadClsSizes[int(m_shaderClass)], maxInsts); m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); - CElementGenShaders::BuildShaderDataBinding(ctx, *this); - return true; - }); - } + } + if (desc->x45_24_x31_26_PMUS) + { + m_instBufPmus = ctx.newDynamicBuffer(boo::BufferUse::Vertex, ShadClsSizes[int(m_shaderClass)], maxInsts); + m_uniformBufPmus = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); + } + CElementGenShaders::BuildShaderDataBinding(ctx, *this); + return true; + }); } CElementGen::~CElementGen() @@ -973,6 +983,34 @@ void CElementGen::RenderModels() texConst = texr->HasConstantTexture(); texr->GetValueUV(partFrame, uvs); } + + switch (m_shaderClass) + { + case CElementGenShaders::EShaderClass::Tex: + g_instTexData.clear(); + g_instTexData.reserve(x30_particles.size()); + break; + case CElementGenShaders::EShaderClass::NoTex: + g_instNoTexData.clear(); + g_instNoTexData.reserve(x30_particles.size()); + break; + default: + Log.report(logvisor::Fatal, "unexpected particle shader class"); + break; + } + + SParticleUniforms uniformData = + { + CGraphics::GetPerspectiveProjectionMatrix(true), + {1.f, 1.f, 1.f, 1.f} + }; + + m_uniformBufPmus->load(&uniformData, sizeof(SParticleUniforms)); + + if (moveRedToAlphaBuffer) + CGraphics::SetShaderDataBinding(m_redToAlphaDataBindPmus); + else + CGraphics::SetShaderDataBinding(m_normalDataBindPmus); } zeus::CTransform orient = zeus::CTransform::Identity(); @@ -1080,11 +1118,36 @@ void CElementGen::RenderModels() } } - /* Draw: */ - /* Pos: {0.5, 0.0, 0.5} Color: UV0: {uv[2], uv[3]} */ - /* Pos: {-0.5, 0.0, 0.5} Color: UV0: {uv[0], uv[3]} */ - /* Pos: {-0.5, 0.0, -0.5} Color: UV0: {uv[0], uv[1]} */ - /* Pos: {0.5, 0.0, -0.5} Color: UV0: {uv[2], uv[1]} */ + switch (m_shaderClass) + { + case CElementGenShaders::EShaderClass::Tex: + { + g_instTexData.emplace_back(); + SParticleInstanceTex& inst = g_instTexData.back(); + inst.pos[0] = CGraphics::g_GXModelView * zeus::CVector3f{0.5f, 0.f, 0.5f}; + inst.pos[1] = CGraphics::g_GXModelView * zeus::CVector3f{-0.5f, 0.f, 0.5f}; + inst.pos[2] = CGraphics::g_GXModelView * zeus::CVector3f{0.5f, 0.f, -0.5f}; + inst.pos[3] = CGraphics::g_GXModelView * zeus::CVector3f{-0.5f, 0.f, -0.5f}; + inst.color = col; + inst.uvs[0] = {uvs.xMax, uvs.yMax}; + inst.uvs[1] = {uvs.xMin, uvs.yMax}; + inst.uvs[2] = {uvs.xMax, uvs.yMin}; + inst.uvs[3] = {uvs.xMin, uvs.yMin}; + break; + } + case CElementGenShaders::EShaderClass::NoTex: + { + g_instNoTexData.emplace_back(); + SParticleInstanceNoTex& inst = g_instNoTexData.back(); + inst.pos[0] = CGraphics::g_GXModelView * zeus::CVector3f{0.5f, 0.f, 0.5f}; + inst.pos[1] = CGraphics::g_GXModelView * zeus::CVector3f{-0.5f, 0.f, 0.5f}; + inst.pos[2] = CGraphics::g_GXModelView * zeus::CVector3f{0.5f, 0.f, -0.5f}; + inst.pos[3] = CGraphics::g_GXModelView * zeus::CVector3f{-0.5f, 0.f, -0.5f}; + inst.color = col; + break; + } + default: break; + } } else { @@ -1105,6 +1168,22 @@ void CElementGen::RenderModels() ++matrixIt; } + if (desc->x45_24_x31_26_PMUS) + { + switch (m_shaderClass) + { + case CElementGenShaders::EShaderClass::Tex: + m_instBufPmus->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex)); + CGraphics::DrawInstances(0, 4, g_instTexData.size()); + break; + case CElementGenShaders::EShaderClass::NoTex: + m_instBufPmus->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex)); + CGraphics::DrawInstances(0, 4, g_instNoTexData.size()); + break; + default: break; + } + } + if (x26d_26_modelsUseLights) CGraphics::DisableAllLights(); diff --git a/Runtime/Particle/CElementGen.hpp b/Runtime/Particle/CElementGen.hpp index e0e845185..92fc85a30 100644 --- a/Runtime/Particle/CElementGen.hpp +++ b/Runtime/Particle/CElementGen.hpp @@ -170,11 +170,17 @@ public: ~CElementGen(); boo::GraphicsDataToken m_gfxToken; + boo::IShaderDataBinding* m_normalDataBind = nullptr; boo::IShaderDataBinding* m_redToAlphaDataBind = nullptr; boo::IGraphicsBufferD* m_instBuf = nullptr; boo::IGraphicsBufferD* m_uniformBuf = nullptr; + boo::IShaderDataBinding* m_normalDataBindPmus = nullptr; + boo::IShaderDataBinding* m_redToAlphaDataBindPmus = nullptr; + boo::IGraphicsBufferD* m_instBufPmus = nullptr; + boo::IGraphicsBufferD* m_uniformBufPmus = nullptr; + CGenDescription* GetDesc() {return x1c_genDesc.GetObj();} static bool g_ParticleSystemInitialized;