2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-08-05 22:15:34 +00:00

CParticleSwooshShaders: Convert to hsh pipeline

This commit is contained in:
Luke Street 2020-10-03 00:27:25 -04:00
parent 6fa9d39cd6
commit 315ac7d6d7
4 changed files with 80 additions and 78 deletions

View File

@ -65,4 +65,5 @@ runtime_add_hsh(Graphics
Shaders/CEnvFxShaders.cpp
Shaders/CFogVolumeFilter.cpp
Shaders/CMapSurfaceShader.cpp
Shaders/CParticleSwooshShaders.cpp
)

View File

@ -5,57 +5,65 @@
#include "Runtime/Particle/CParticleSwoosh.hpp"
#include "Runtime/Particle/CSwooshDescription.hpp"
#include "CParticleSwooshShaders.cpp.hshhead"
namespace urde {
using namespace hsh::pipeline;
template <bool Additive, bool AlphaWrite, bool ZWrite>
struct CParticleSwooshShadersTexPipeline
: pipeline<topology<hsh::TriangleStrip>,
std::conditional_t<Additive, AdditiveAttachment<AlphaWrite>, BlendAttachment<AlphaWrite>>,
depth_compare<hsh::LEqual>, depth_write<ZWrite>> {
CParticleSwooshShadersTexPipeline(hsh::vertex_buffer<CParticleSwooshShaders::Vert> vbo,
hsh::uniform_buffer<CParticleSwooshShaders::Uniform> uniBuf, hsh::texture2d tex) {
this->position = uniBuf->m_xf * hsh::float4(vbo->m_pos, 1.f);
this->color_out[0] = vbo->m_color * tex.sample<float>(vbo->m_uv);
}
};
template struct CParticleSwooshShadersTexPipeline<true, true, false>;
template struct CParticleSwooshShadersTexPipeline<false, true, true>;
template <bool Additive, bool AlphaWrite, bool ZWrite>
struct CParticleSwooshShadersNoTexPipeline
: pipeline<topology<hsh::TriangleStrip>,
std::conditional_t<Additive, AdditiveAttachment<AlphaWrite>, BlendAttachment<AlphaWrite>>,
depth_compare<hsh::LEqual>, depth_write<ZWrite>> {
CParticleSwooshShadersNoTexPipeline(hsh::vertex_buffer<CParticleSwooshShaders::Vert> vbo,
hsh::uniform_buffer<CParticleSwooshShaders::Uniform> uniBuf) {
this->position = uniBuf->m_xf * hsh::float4(vbo->m_pos, 1.f);
this->color_out[0] = vbo->m_color;
}
};
template struct CParticleSwooshShadersNoTexPipeline<true, true, false>;
template struct CParticleSwooshShadersNoTexPipeline<false, true, true>;
CParticleSwooshShaders::EShaderClass CParticleSwooshShaders::GetShaderClass(CParticleSwoosh& gen) {
CSwooshDescription* desc = gen.GetDesc();
if (desc->x3c_TEXR)
return EShaderClass::Tex;
else
return EShaderClass::NoTex;
return gen.GetDesc()->x3c_TEXR ? EShaderClass::Tex : EShaderClass::NoTex;
}
void CParticleSwooshShaders::BuildShaderDataBinding(CParticleSwoosh& gen) {
CSwooshDescription* desc = gen.GetDesc();
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* 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;
}
auto* desc = gen.GetDesc();
switch (GetShaderClass(gen)) {
case EShaderClass::Tex: {
hsh::texture2d tex = desc->x3c_TEXR->GetValueTexture(0)->GetBooTexture();
gen.m_dataBind[0].hsh_tex_noalphawrite_bind(
CParticleSwooshShadersTexPipeline<desc->x44_31_AALP, false, desc->x45_24_ZBUF>(gen.m_vertBuf.get(),
gen.m_uniformBuf.get(), tex));
gen.m_dataBind[1].hsh_tex_alphawrite_bind(
CParticleSwooshShadersTexPipeline<desc->x44_31_AALP, true, desc->x45_24_ZBUF>(gen.m_vertBuf.get(),
gen.m_uniformBuf.get(), tex));
break;
}
case EShaderClass::NoTex: {
gen.m_dataBind[0].hsh_notex_noalphawrite_bind(
CParticleSwooshShadersNoTexPipeline<desc->x44_31_AALP, false, desc->x45_24_ZBUF>(gen.m_vertBuf.get(),
gen.m_uniformBuf.get()));
gen.m_dataBind[1].hsh_notex_alphawrite_bind(
CParticleSwooshShadersNoTexPipeline<desc->x44_31_AALP, true, desc->x45_24_ZBUF>(gen.m_vertBuf.get(),
gen.m_uniformBuf.get()));
break;
}
const CUVElement* const texr = desc->x3c_TEXR.get();
const std::array<boo::ObjToken<boo::ITexture>, 1> textures{
texr ? texr->GetValueTexture(0).GetObj()->GetBooTexture() : nullptr,
};
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> uniforms{gen.m_uniformBuf.get()};
for (size_t i = 0; i < gen.m_dataBind.size(); ++i) {
gen.m_dataBind[i] =
ctx.newShaderDataBinding((*pipeline)[i], gen.m_vertBuf.get(), nullptr, nullptr, uniforms.size(),
uniforms.data(), nullptr, texr ? 1 : 0, textures.data(), nullptr, nullptr);
}
}

View File

@ -66,17 +66,14 @@ CParticleSwoosh::CParticleSwoosh(const TToken<CSwooshDescription>& desc, int len
if (x1c_desc->x44_29_WIRE) {
const int maxVerts = x1b4_LENG * (x1b0_SPLN + 1) * x1b8_SIDE * 12;
m_lineRenderer.reset(
new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines, maxVerts * 2, nullptr, x1d0_25_AALP));
const bool additive = x1d0_25_AALP;
m_lineRenderer = std::make_unique<CLineRenderer>(CLineRenderer::EPrimitiveMode::Lines, maxVerts * 2,
hsh::texture2d{}, additive, hsh::LEqual);
} else {
const auto maxVerts = size_t(x1b4_LENG * (x1b0_SPLN + 1) * x1b8_SIDE * 4);
const auto maxVerts = x1b4_LENG * (x1b0_SPLN + 1) * x1b8_SIDE * 4;
m_cachedVerts.reserve(maxVerts);
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
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;
} BooTrace);
m_vertBuf = hsh::create_dynamic_vertex_buffer<CParticleSwooshShaders::Vert>(maxVerts);
m_uniformBuf = hsh::create_dynamic_uniform_buffer<CParticleSwooshShaders::Uniform>();
}
}
}
@ -437,7 +434,7 @@ void CParticleSwoosh::RenderNSidedSpline() {
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);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(m_cachedVerts.size() - 4, 4);
} else {
const auto v0 = GetSplinePoint(x16c_p0[k], x17c_p1[k], x18c_p2[k], x19c_p3[k], t0);
const auto v1 = GetSplinePoint(x16c_p0[otherK], x17c_p1[otherK], x18c_p2[otherK], x19c_p3[otherK], t0);
@ -462,7 +459,7 @@ void CParticleSwoosh::RenderNSidedSpline() {
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);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(m_cachedVerts.size() - 4, 4);
}
}
}
@ -593,19 +590,19 @@ void CParticleSwoosh::Render3SidedSolidSpline() {
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_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(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_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(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);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(m_cachedVerts.size() - 4, 4);
}
}
}
@ -685,19 +682,19 @@ void CParticleSwoosh::Render3SidedSolidNoSplineNoGaps() {
m_cachedVerts.push_back({p1[i & 1], {uv0, x1d4_uvs.yMax}, c0});
m_cachedVerts.push_back({p0[!(i & 1)], {uv1, x1d4_uvs.yMin}, c1});
m_cachedVerts.push_back({p1[!(i & 1)], {uv1, x1d4_uvs.yMax}, c1});
CGraphics::DrawArray(m_cachedVerts.size() - 4, 4);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(m_cachedVerts.size() - 4, 4);
m_cachedVerts.push_back({p1[i & 1], {uv0, x1d4_uvs.yMin}, c0});
m_cachedVerts.push_back({p2[i & 1], {uv0, x1d4_uvs.yMax}, c0});
m_cachedVerts.push_back({p1[!(i & 1)], {uv1, x1d4_uvs.yMin}, c1});
m_cachedVerts.push_back({p2[!(i & 1)], {uv1, x1d4_uvs.yMax}, c1});
CGraphics::DrawArray(m_cachedVerts.size() - 4, 4);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(m_cachedVerts.size() - 4, 4);
m_cachedVerts.push_back({p2[i & 1], {uv0, x1d4_uvs.yMin}, c0});
m_cachedVerts.push_back({p0[i & 1], {uv0, x1d4_uvs.yMax}, c0});
m_cachedVerts.push_back({p2[!(i & 1)], {uv1, x1d4_uvs.yMin}, c1});
m_cachedVerts.push_back({p0[!(i & 1)], {uv1, x1d4_uvs.yMax}, c1});
CGraphics::DrawArray(m_cachedVerts.size() - 4, 4);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(m_cachedVerts.size() - 4, 4);
}
}
@ -719,7 +716,7 @@ void CParticleSwoosh::Render2SidedNoSplineGaps() {
if (!swoosh.x0_active) {
if (streaming) {
streaming = false;
CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(drawStart, m_cachedVerts.size() - drawStart);
}
continue;
}
@ -765,7 +762,7 @@ void CParticleSwoosh::Render2SidedNoSplineGaps() {
}
if (streaming)
CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(drawStart, m_cachedVerts.size() - drawStart);
}
void CParticleSwoosh::Render2SidedNoSplineNoGaps() {
@ -818,7 +815,8 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() {
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) {
CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(drawStart,
m_cachedVerts.size() - drawStart);
drawStart = m_cachedVerts.size();
uvOffset -= 1.f;
m_cachedVerts.push_back({v0, {uvOffset, x1d4_uvs.yMin}, color});
@ -872,7 +870,7 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() {
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) {
CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(drawStart, m_cachedVerts.size() - drawStart);
drawStart = m_cachedVerts.size();
uvOffset -= 1.f;
m_cachedVerts.push_back({v0, {uvOffset, x1d4_uvs.yMin}, color});
@ -925,7 +923,7 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps() {
}
}
CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart);
m_dataBind[g_Renderer->IsThermalVisorHotPass() ? 1 : 0].draw(drawStart, m_cachedVerts.size() - drawStart);
}
void CParticleSwoosh::Render(const CActorLights*) {
@ -933,13 +931,10 @@ void CParticleSwoosh::Render(const CActorLights*) {
return;
}
SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CParticleSwoosh::Render {}"),
*x1c_desc.GetObjectTag()).c_str(), zeus::skYellow);
SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CParticleSwoosh::Render {}"), *x1c_desc.GetObjectTag()).c_str(),
zeus::skYellow);
m_cachedVerts.clear();
if (m_dataBind[0]) {
CGraphics::SetShaderDataBinding(m_dataBind[g_Renderer->IsThermalVisorHotPass()]);
}
CParticleGlobals::instance()->SetParticleLifetime(x1b4_LENG);
CGlobalRandom gr(x1c0_rand);
@ -1007,9 +1002,9 @@ void CParticleSwoosh::Render(const CActorLights*) {
}
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));
m_uniformBuf.load({mvp});
if (!m_cachedVerts.empty()) {
m_vertBuf.load(m_cachedVerts);
}
}
@ -1074,9 +1069,7 @@ u32 CParticleSwoosh::GetParticleCount() const { return x1ac_particleCount; }
bool CParticleSwoosh::SystemHasLight() const { return false; }
CLight CParticleSwoosh::GetLight() const {
return CLight::BuildLocalAmbient(zeus::skZero3f, zeus::skWhite);
}
CLight CParticleSwoosh::GetLight() const { return CLight::BuildLocalAmbient(zeus::skZero3f, zeus::skWhite); }
bool CParticleSwoosh::GetParticleEmission() const { return x1d0_24_emitting; }

View File

@ -104,7 +104,7 @@ class CParticleSwoosh : public CParticleGen {
zeus::CColor x20c_moduColor = zeus::skWhite;
std::array<hsh::binding, 2> m_dataBind;
hsh::owner<hsh::vertex_buffer<CParticleSwooshShaders::Vert>> m_vertBuf;
hsh::dynamic_owner<hsh::vertex_buffer<CParticleSwooshShaders::Vert>> m_vertBuf;
hsh::dynamic_owner<hsh::uniform_buffer<CParticleSwooshShaders::Uniform>> m_uniformBuf;
std::unique_ptr<CLineRenderer> m_lineRenderer;
std::vector<CParticleSwooshShaders::Vert> m_cachedVerts;