mirror of https://github.com/AxioDL/metaforce.git
hsh pipelines for ThermalCold, ThermalHot, ElemenGen
Plus various fixes
This commit is contained in:
parent
485e0afb43
commit
6c56f6452e
|
@ -577,7 +577,8 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::GenerateFogVolumeRampTex() {
|
void CBooRenderer::GenerateFogVolumeRampTex() {
|
||||||
x1b8_fogVolumeRamp = hsh::create_texture2d({FOGVOL_RAMP_RES, FOGVOL_RAMP_RES}, hsh::R16_UNORM, 1, [&](u16* data, std::size_t size) {
|
x1b8_fogVolumeRamp = hsh::create_texture2d({FOGVOL_RAMP_RES, FOGVOL_RAMP_RES}, hsh::R16_UNORM, 1, [&](void* data, std::size_t size) {
|
||||||
|
auto* out = static_cast<u16*>(data);
|
||||||
for (size_t y = 0; y < FOGVOL_RAMP_RES; ++y) {
|
for (size_t y = 0; y < FOGVOL_RAMP_RES; ++y) {
|
||||||
for (size_t x = 0; x < FOGVOL_RAMP_RES; ++x) {
|
for (size_t x = 0; x < FOGVOL_RAMP_RES; ++x) {
|
||||||
const int tmp = int(y << 16 | x << 8 | 0x7f);
|
const int tmp = int(y << 16 | x << 8 | 0x7f);
|
||||||
|
@ -586,19 +587,20 @@ void CBooRenderer::GenerateFogVolumeRampTex() {
|
||||||
(-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) *
|
(-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) *
|
||||||
3.0 / (FOGVOL_FAR - FOGVOL_NEAR),
|
3.0 / (FOGVOL_FAR - FOGVOL_NEAR),
|
||||||
1.0);
|
1.0);
|
||||||
data[x + y * FOGVOL_RAMP_RES] = u16((a * a + a) / 2.0 * 65535);
|
out[x + y * FOGVOL_RAMP_RES] = u16((a * a + a) / 2.0 * 65535);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::GenerateSphereRampTex() {
|
void CBooRenderer::GenerateSphereRampTex() {
|
||||||
x220_sphereRamp = hsh::create_texture2d({SPHERE_RAMP_RES, SPHERE_RAMP_RES}, hsh::R8_UNORM, 1, [&](u8* data, std::size_t size) {
|
x220_sphereRamp = hsh::create_texture2d({SPHERE_RAMP_RES, SPHERE_RAMP_RES}, hsh::R8_UNORM, 1, [&](void* data, std::size_t size) {
|
||||||
|
auto* out = static_cast<u8*>(data);
|
||||||
constexpr float halfRes = SPHERE_RAMP_RES / 2.f;
|
constexpr float halfRes = SPHERE_RAMP_RES / 2.f;
|
||||||
for (size_t y = 0; y < SPHERE_RAMP_RES; ++y) {
|
for (size_t y = 0; y < SPHERE_RAMP_RES; ++y) {
|
||||||
for (size_t x = 0; x < SPHERE_RAMP_RES; ++x) {
|
for (size_t x = 0; x < SPHERE_RAMP_RES; ++x) {
|
||||||
const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes);
|
const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes);
|
||||||
data[x + y * SPHERE_RAMP_RES] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
|
out[x + y * SPHERE_RAMP_RES] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -647,8 +649,9 @@ hsh::texture2d CBooRenderer::GetColorTexture(const zeus::CColor& color) {
|
||||||
return search->second;
|
return search->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_colorTextures.emplace(color, hsh::create_texture2d({1, 1}, hsh::RGBA8_UNORM, 1, [&](zeus::Comp8* data, std::size_t size) {
|
m_colorTextures.emplace(color, hsh::create_texture2d({1, 1}, hsh::RGBA8_UNORM, 1, [&](void* data, std::size_t size) {
|
||||||
color.toRGBA8(data[0], data[1], data[2], data[3]);
|
auto* out = static_cast<zeus::Comp8*>(data);
|
||||||
|
color.toRGBA8(out[0], out[1], out[2], out[3]);
|
||||||
}));
|
}));
|
||||||
return m_colorTextures[color].get();
|
return m_colorTextures[color].get();
|
||||||
}
|
}
|
||||||
|
@ -690,7 +693,7 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac)
|
||||||
|
|
||||||
GenerateFogVolumeRampTex();
|
GenerateFogVolumeRampTex();
|
||||||
GenerateSphereRampTex();
|
GenerateSphereRampTex();
|
||||||
m_ballShadowId = hsh::create_render_texture2d({m_ballShadowIdW, m_ballShadowIdH}, hsh::RGBA8_UNORM, 1, 0);
|
m_ballShadowId = hsh::create_render_texture2d({skBallShadowIdSize, skBallShadowIdSize}, hsh::RGBA8_UNORM, 1, 0);
|
||||||
x14c_reflectionTex = hsh::create_render_texture2d({256, 256}, hsh::RGBA8_UNORM, 1, 0);
|
x14c_reflectionTex = hsh::create_render_texture2d({256, 256}, hsh::RGBA8_UNORM, 1, 0);
|
||||||
GenerateScanLinesVBO();
|
GenerateScanLinesVBO();
|
||||||
|
|
||||||
|
|
|
@ -289,15 +289,15 @@ public:
|
||||||
void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model,
|
void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model,
|
||||||
const CSkinnedModel* sModel);
|
const CSkinnedModel* sModel);
|
||||||
|
|
||||||
auto GetThermoPalette() const { return x288_thermoPalette.get(); }
|
hsh::texture2d GetThermoPalette() const { return x288_thermoPalette; }
|
||||||
auto GetFogRampTex() const { return x1b8_fogVolumeRamp.get(); }
|
hsh::texture2d GetFogRampTex() const { return x1b8_fogVolumeRamp.get(); }
|
||||||
auto GetRandomStaticEntropyTex() const { return m_staticEntropy->GetBooTexture(); }
|
hsh::texture2d GetRandomStaticEntropyTex() const { return m_staticEntropy->GetBooTexture(); }
|
||||||
auto GetScanLinesEvenVBO() const { return m_scanLinesEvenVBO.get(); }
|
auto GetScanLinesEvenVBO() const { return m_scanLinesEvenVBO.get(); }
|
||||||
auto GetScanLinesOddVBO() const { return m_scanLinesOddVBO.get(); }
|
auto GetScanLinesOddVBO() const { return m_scanLinesOddVBO.get(); }
|
||||||
|
|
||||||
auto GetClearTexture() const { return m_clearTexture.get(); }
|
hsh::texture2d GetClearTexture() const { return m_clearTexture.get(); }
|
||||||
auto GetBlackTexture() const { return m_blackTexture.get(); }
|
hsh::texture2d GetBlackTexture() const { return m_blackTexture.get(); }
|
||||||
auto GetWhiteTexture() const { return m_whiteTexture.get(); }
|
hsh::texture2d GetWhiteTexture() const { return m_whiteTexture.get(); }
|
||||||
|
|
||||||
hsh::texture2d GetColorTexture(const zeus::CColor& color);
|
hsh::texture2d GetColorTexture(const zeus::CColor& color);
|
||||||
|
|
||||||
|
|
|
@ -59,4 +59,7 @@ runtime_add_hsh(Graphics
|
||||||
Shaders/CColoredStripShader.cpp
|
Shaders/CColoredStripShader.cpp
|
||||||
Shaders/CDecalShaders.cpp
|
Shaders/CDecalShaders.cpp
|
||||||
Shaders/CEnergyBarShader.cpp
|
Shaders/CEnergyBarShader.cpp
|
||||||
|
Shaders/CThermalColdFilter.cpp
|
||||||
|
Shaders/CThermalHotFilter.cpp
|
||||||
|
Shaders/CElementGenShaders.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,12 +12,7 @@ CRainSplashGenerator::CRainSplashGenerator(const zeus::CVector3f& scale, u32 max
|
||||||
: x14_scale(scale), x2c_minZ(minZ) {
|
: x14_scale(scale), x2c_minZ(minZ) {
|
||||||
x30_alpha = std::min(1.f, alpha);
|
x30_alpha = std::min(1.f, alpha);
|
||||||
x44_genRate = std::min(maxSplashes, genRate);
|
x44_genRate = std::min(maxSplashes, genRate);
|
||||||
x0_rainSplashes.reserve(maxSplashes);
|
x0_rainSplashes.resize(maxSplashes);
|
||||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
|
||||||
for (u32 i = 0; i < maxSplashes; ++i)
|
|
||||||
x0_rainSplashes.emplace_back(ctx);
|
|
||||||
return true;
|
|
||||||
} BooTrace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRainSplashGenerator::SSplashLine::Draw(float alpha, float dt, const zeus::CVector3f& pos) {
|
void CRainSplashGenerator::SSplashLine::Draw(float alpha, float dt, const zeus::CVector3f& pos) {
|
||||||
|
@ -73,13 +68,11 @@ void CRainSplashGenerator::Draw(const zeus::CTransform& xf) {
|
||||||
DoDraw(xf);
|
DoDraw(xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRainSplashGenerator::SSplashLine::SSplashLine(boo::IGraphicsDataFactory::Context& ctx)
|
CRainSplashGenerator::SSplashLine::SSplashLine()
|
||||||
: m_renderer(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 3, nullptr, false) {}
|
: m_renderer(CLineRenderer::EPrimitiveMode::LineStrip, 3, hsh::texture2d{}, false, hsh::LEqual) {}
|
||||||
|
|
||||||
CRainSplashGenerator::SRainSplash::SRainSplash(boo::IGraphicsDataFactory::Context& ctx) {
|
CRainSplashGenerator::SRainSplash::SRainSplash() {
|
||||||
for (size_t i = 0; i < x0_lines.capacity(); ++i) {
|
x0_lines.resize(x0_lines.capacity());
|
||||||
x0_lines.emplace_back(ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRainSplashGenerator::SSplashLine::Update(float dt, CStateManager& mgr) {
|
void CRainSplashGenerator::SSplashLine::Update(float dt, CStateManager& mgr) {
|
||||||
|
@ -158,8 +151,7 @@ u32 CRainSplashGenerator::GetNextBestPt(u32 pt, const std::vector<std::pair<zeus
|
||||||
const auto idx = u32(rand.Range(0, int(vn.size() - 1)));
|
const auto idx = u32(rand.Range(0, int(vn.size() - 1)));
|
||||||
const auto& vert = vn[idx];
|
const auto& vert = vn[idx];
|
||||||
const float distSq = (refVert.first - vert.first).magSquared();
|
const float distSq = (refVert.first - vert.first).magSquared();
|
||||||
if (distSq > maxDist && vert.second.dot(zeus::skUp) >= 0.f &&
|
if (distSq > maxDist && vert.second.dot(zeus::skUp) >= 0.f && (vert.first.z() <= 0.f || vert.first.z() > minZ)) {
|
||||||
(vert.first.z() <= 0.f || vert.first.z() > minZ)) {
|
|
||||||
nextPt = idx;
|
nextPt = idx;
|
||||||
maxDist = distSq;
|
maxDist = distSq;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,20 +32,20 @@ void CSkinnedModel::Calculate(const CPoseAsTransforms& pose, const CModelFlags&
|
||||||
const std::optional<CVertexMorphEffect>& morphEffect,
|
const std::optional<CVertexMorphEffect>& morphEffect,
|
||||||
const float* morphMagnitudes) {
|
const float* morphMagnitudes) {
|
||||||
if (morphEffect || g_PointGenFunc) {
|
if (morphEffect || g_PointGenFunc) {
|
||||||
if (auto vertBuf = m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr)) {
|
if (auto* vertBuf = m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr)) {
|
||||||
x10_skinRules->TransformVerticesCPU(m_vertWorkspace, pose, *x4_model);
|
x10_skinRules->TransformVerticesCPU(m_vertWorkspace, pose, *x4_model);
|
||||||
if (morphEffect)
|
if (morphEffect)
|
||||||
morphEffect->MorphVertices(m_vertWorkspace, morphMagnitudes, x10_skinRules, pose);
|
morphEffect->MorphVertices(m_vertWorkspace, morphMagnitudes, x10_skinRules, pose);
|
||||||
if (g_PointGenFunc)
|
if (g_PointGenFunc)
|
||||||
g_PointGenFunc(g_PointGenCtx, m_vertWorkspace);
|
g_PointGenFunc(g_PointGenCtx, m_vertWorkspace);
|
||||||
x4_model->ApplyVerticesCPU(vertBuf, m_vertWorkspace);
|
x4_model->ApplyVerticesCPU(*vertBuf, m_vertWorkspace);
|
||||||
m_modifiedVBO = true;
|
m_modifiedVBO = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (auto vertBuf =
|
if (auto* vertBuf =
|
||||||
m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose)) {
|
m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose)) {
|
||||||
if (m_modifiedVBO) {
|
if (m_modifiedVBO) {
|
||||||
x4_model->RestoreVerticesCPU(vertBuf);
|
x4_model->RestoreVerticesCPU(*vertBuf);
|
||||||
m_modifiedVBO = false;
|
m_modifiedVBO = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,13 @@ struct CAABoxShaderPipeline
|
||||||
this->color_out[0] = uniBuf->m_color;
|
this->color_out[0] = uniBuf->m_color;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template struct CAABoxShaderPipeline<ERglCullMode::None, ERglEnum::Always, true, ERglBlendMode::Blend,
|
template struct CAABoxShaderPipeline<ERglCullMode::None, ERglEnum::LEqual, true, ERglBlendMode::Blend,
|
||||||
ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear, true>;
|
ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear, true>;
|
||||||
|
|
||||||
|
constexpr size_t VertexCount = 34;
|
||||||
|
|
||||||
CAABoxShader::CAABoxShader(const zeus::CAABox& aabb) {
|
CAABoxShader::CAABoxShader(const zeus::CAABox& aabb) {
|
||||||
const std::array<Vert, 34> verts{{
|
const std::array<Vert, VertexCount> verts{{
|
||||||
{{aabb.max.x(), aabb.max.y(), aabb.min.z()}}, {{aabb.max.x(), aabb.min.y(), aabb.min.z()}},
|
{{aabb.max.x(), aabb.max.y(), aabb.min.z()}}, {{aabb.max.x(), aabb.min.y(), aabb.min.z()}},
|
||||||
{{aabb.max.x(), aabb.max.y(), aabb.max.z()}}, {{aabb.max.x(), aabb.min.y(), aabb.max.z()}},
|
{{aabb.max.x(), aabb.max.y(), aabb.max.z()}}, {{aabb.max.x(), aabb.min.y(), aabb.max.z()}},
|
||||||
{{aabb.max.x(), aabb.min.y(), aabb.max.z()}},
|
{{aabb.max.x(), aabb.min.y(), aabb.max.z()}},
|
||||||
|
@ -62,7 +64,7 @@ void CAABoxShader::draw(const zeus::CColor& color) {
|
||||||
m_uniform.m_color = color;
|
m_uniform.m_color = color;
|
||||||
m_uniBuf.load(m_uniform);
|
m_uniBuf.load(m_uniform);
|
||||||
|
|
||||||
m_dataBind.draw(0, 34);
|
m_dataBind.draw(0, VertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace urde {
|
||||||
|
|
||||||
class CCameraBlurFilter {
|
class CCameraBlurFilter {
|
||||||
friend struct CCameraBlurFilterPipeline;
|
friend struct CCameraBlurFilterPipeline;
|
||||||
|
|
||||||
|
public:
|
||||||
struct Vert {
|
struct Vert {
|
||||||
hsh::float2 m_pos;
|
hsh::float2 m_pos;
|
||||||
hsh::float2 m_uv;
|
hsh::float2 m_uv;
|
||||||
|
@ -16,6 +18,7 @@ class CCameraBlurFilter {
|
||||||
float m_opacity = 1.f;
|
float m_opacity = 1.f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
hsh::dynamic_owner<hsh::vertex_buffer<Vert>> m_vbo;
|
hsh::dynamic_owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||||
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
||||||
hsh::binding m_dataBind;
|
hsh::binding m_dataBind;
|
||||||
|
|
|
@ -31,7 +31,7 @@ template struct CDecalShaderTexPipeline<false, false>;
|
||||||
template <bool Additive>
|
template <bool Additive>
|
||||||
struct CDecalShaderNoTexPipeline : pipeline<std::conditional_t<Additive, AdditiveAttachment<>, BlendAttachment<>>,
|
struct CDecalShaderNoTexPipeline : pipeline<std::conditional_t<Additive, AdditiveAttachment<>, BlendAttachment<>>,
|
||||||
depth_compare<hsh::LEqual>, depth_write<!Additive>> {
|
depth_compare<hsh::LEqual>, depth_write<!Additive>> {
|
||||||
CDecalShaderNoTexPipeline(hsh::vertex_buffer<SParticleInstanceTex> vbo,
|
CDecalShaderNoTexPipeline(hsh::vertex_buffer<SParticleInstanceNoTex> vbo,
|
||||||
hsh::uniform_buffer<SParticleUniforms> uniBuf) {
|
hsh::uniform_buffer<SParticleUniforms> uniBuf) {
|
||||||
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||||
this->color_out[0] = vbo->color * uniBuf->moduColor;
|
this->color_out[0] = vbo->color * uniBuf->moduColor;
|
||||||
|
|
|
@ -1,274 +1,133 @@
|
||||||
#include "Runtime/Graphics/Shaders/CElementGenShaders.hpp"
|
#include "Runtime/Graphics/Shaders/CElementGenShaders.hpp"
|
||||||
|
|
||||||
#include <iterator>
|
#include "Runtime/GameGlobalObjects.hpp"
|
||||||
|
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||||
#include "Runtime/Particle/CElementGen.hpp"
|
#include "Runtime/Particle/CElementGen.hpp"
|
||||||
|
|
||||||
#include <hecl/Pipeline.hpp>
|
enum class BlendMode {
|
||||||
|
Regular,
|
||||||
|
Additive,
|
||||||
|
Subtract,
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "CElementGenShaders.cpp.hshhead"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
using namespace hsh::pipeline;
|
||||||
|
|
||||||
void CElementGenShaders::Initialize() {
|
template <BlendMode Mode, bool AlphaWrite>
|
||||||
m_texZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{}),
|
struct BlendModeAttachmentExt {
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{})};
|
using type = BlendAttachment<AlphaWrite>;
|
||||||
m_texNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWrite{}),
|
};
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWriteAWrite{})};
|
template <bool AlphaWrite>
|
||||||
m_texZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWrite{}),
|
struct BlendModeAttachmentExt<BlendMode::Additive, AlphaWrite> {
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteAWrite{})};
|
using type = AdditiveAttachment<AlphaWrite>;
|
||||||
m_texNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWrite{}),
|
};
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteAWrite{})};
|
template <bool AlphaWrite>
|
||||||
m_texAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTest{}),
|
struct BlendModeAttachmentExt<BlendMode::Subtract, AlphaWrite> {
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTestAWrite{})};
|
using type = SubtractAttachment<AlphaWrite>;
|
||||||
m_texAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTest{}),
|
};
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTestAWrite{})};
|
template <BlendMode Mode, bool AlphaWrite>
|
||||||
m_texRedToAlphaZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTest{}),
|
using BlendModeAttachment = typename BlendModeAttachmentExt<Mode, AlphaWrite>::type;
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestAWrite{})};
|
|
||||||
m_texRedToAlphaNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTest{}),
|
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestAWrite{})};
|
|
||||||
m_texZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSub{}),
|
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSubAWrite{})};
|
|
||||||
m_texNoZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSub{}),
|
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSubAWrite{})};
|
|
||||||
m_texRedToAlphaZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSub{}),
|
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSubAWrite{})};
|
|
||||||
m_texRedToAlphaNoZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSub{}),
|
|
||||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSubAWrite{})};
|
|
||||||
|
|
||||||
m_indTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexZWrite{}),
|
template <BlendMode Mode, bool AlphaWrite, bool ZTest, bool ZWrite, bool RedToAlpha>
|
||||||
hecl::conv->convert(Shader_CElementGenShaderIndTexZWriteAWrite{})};
|
struct CElementGenShadersTexPipeline : pipeline<topology<hsh::TriangleStrip>, BlendModeAttachment<Mode, AlphaWrite>,
|
||||||
m_indTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWrite{}),
|
depth_compare<ZTest ? hsh::LEqual : hsh::Always>, depth_write<ZWrite>> {
|
||||||
hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWriteAWrite{})};
|
CElementGenShadersTexPipeline(hsh::vertex_buffer<SParticleInstanceTex> vbo,
|
||||||
m_indTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderIndTexAdditive{}),
|
hsh::uniform_buffer<SParticleUniforms> uniBuf, hsh::texture2d tex) {
|
||||||
hecl::conv->convert(Shader_CElementGenShaderIndTexAdditiveAWrite{})};
|
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||||
|
this->color_out[0] = vbo->color * uniBuf->moduColor * tex.sample<float>(vbo->uvs[this->vertex_id]);
|
||||||
|
if constexpr (RedToAlpha) {
|
||||||
|
this->color_out[0].w = this->color_out[0].x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template struct CElementGenShadersTexPipeline<BlendMode::Regular, true, true, true, false>;
|
||||||
|
template struct CElementGenShadersTexPipeline<BlendMode::Additive, true, true, true, true>;
|
||||||
|
template struct CElementGenShadersTexPipeline<BlendMode::Subtract, true, true, true, true>;
|
||||||
|
|
||||||
m_cindTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexZWrite{}),
|
template <BlendMode Mode, bool AlphaWrite, bool ZTest, bool ZWrite, bool ColoredIndirect>
|
||||||
hecl::conv->convert(Shader_CElementGenShaderCindTexZWriteAWrite{})};
|
struct CElementGenShadersIndTexPipeline
|
||||||
m_cindTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWrite{}),
|
: pipeline<topology<hsh::TriangleStrip>, BlendModeAttachment<Mode, AlphaWrite>,
|
||||||
hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWriteAWrite{})};
|
depth_compare<ZTest ? hsh::LEqual : hsh::Always>, depth_write<ZWrite>> {
|
||||||
m_cindTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderCindTexAdditive{}),
|
CElementGenShadersIndTexPipeline(hsh::vertex_buffer<SParticleInstanceIndTex> vbo,
|
||||||
hecl::conv->convert(Shader_CElementGenShaderCindTexAdditiveAWrite{})};
|
hsh::uniform_buffer<SParticleUniforms> uniBuf, hsh::texture2d texrTex,
|
||||||
|
hsh::texture2d tindTex, hsh::render_texture2d sceneTex) {
|
||||||
|
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||||
|
hsh::float4 texrTexel = texrTex.sample<float>(vbo->texrTindUVs[this->vertex_id].xy());
|
||||||
|
hsh::float2 tindTexel = tindTex.sample<float>(vbo->texrTindUVs[this->vertex_id].zw()).xy();
|
||||||
|
hsh::float4 sceneTexel = sceneTex.sample<float>(hsh::lerp(vbo->sceneUVs.xy(), vbo->sceneUVs.zw(), tindTexel));
|
||||||
|
if constexpr (ColoredIndirect) {
|
||||||
|
this->color_out[0] = vbo->color * hsh::float4(sceneTexel.xyz(), 1.f) * texrTexel;
|
||||||
|
} else {
|
||||||
|
this->color_out[0] = vbo->color * hsh::float4(sceneTexel.xyz(), 1.f) + texrTexel;
|
||||||
|
this->color_out[0].w *= texrTexel.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template struct CElementGenShadersIndTexPipeline<BlendMode::Regular, true, true, true, true>;
|
||||||
|
template struct CElementGenShadersIndTexPipeline<BlendMode::Additive, true, true, true, false>;
|
||||||
|
|
||||||
m_noTexZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWrite{}),
|
template <BlendMode Mode, bool AlphaWrite, bool ZTest, bool ZWrite>
|
||||||
hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWriteAWrite{})};
|
struct CElementGenShadersNoTexPipeline
|
||||||
m_noTexNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWrite{}),
|
: pipeline<topology<hsh::TriangleStrip>, BlendModeAttachment<Mode, AlphaWrite>,
|
||||||
hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWriteAWrite{})};
|
depth_compare<ZTest ? hsh::LEqual : hsh::Always>, depth_write<ZWrite>> {
|
||||||
m_noTexZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWrite{}),
|
CElementGenShadersNoTexPipeline(hsh::vertex_buffer<SParticleInstanceNoTex> vbo,
|
||||||
hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWriteAWrite{})};
|
hsh::uniform_buffer<SParticleUniforms> uniBuf) {
|
||||||
m_noTexNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWrite{}),
|
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||||
hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWriteAWrite{})};
|
this->color_out[0] = vbo->color * uniBuf->moduColor;
|
||||||
m_noTexAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTest{}),
|
}
|
||||||
hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTestAWrite{})};
|
};
|
||||||
m_noTexAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTest{}),
|
template struct CElementGenShadersNoTexPipeline<BlendMode::Regular, true, true, true>;
|
||||||
hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTestAWrite{})};
|
template struct CElementGenShadersNoTexPipeline<BlendMode::Additive, true, true, true>;
|
||||||
}
|
template struct CElementGenShadersNoTexPipeline<BlendMode::Subtract, true, true, true>;
|
||||||
|
|
||||||
void CElementGenShaders::Shutdown() {
|
|
||||||
for (auto& s : m_texZTestZWrite) s.reset();
|
|
||||||
for (auto& s : m_texNoZTestZWrite) s.reset();
|
|
||||||
for (auto& s : m_texZTestNoZWrite) s.reset();
|
|
||||||
for (auto& s : m_texNoZTestNoZWrite) s.reset();
|
|
||||||
for (auto& s : m_texAdditiveZTest) s.reset();
|
|
||||||
for (auto& s : m_texAdditiveNoZTest) s.reset();
|
|
||||||
for (auto& s : m_texRedToAlphaZTest) s.reset();
|
|
||||||
for (auto& s : m_texRedToAlphaNoZTest) s.reset();
|
|
||||||
for (auto& s : m_texZTestNoZWriteSub) s.reset();
|
|
||||||
for (auto& s : m_texNoZTestNoZWriteSub) s.reset();
|
|
||||||
for (auto& s : m_texRedToAlphaZTestSub) s.reset();
|
|
||||||
for (auto& s : m_texRedToAlphaNoZTestSub) s.reset();
|
|
||||||
|
|
||||||
for (auto& s : m_indTexZWrite) s.reset();
|
|
||||||
for (auto& s : m_indTexNoZWrite) s.reset();
|
|
||||||
for (auto& s : m_indTexAdditive) s.reset();
|
|
||||||
|
|
||||||
for (auto& s : m_cindTexZWrite) s.reset();
|
|
||||||
for (auto& s : m_cindTexNoZWrite) s.reset();
|
|
||||||
for (auto& s : m_cindTexAdditive) s.reset();
|
|
||||||
|
|
||||||
for (auto& s : m_noTexZTestZWrite) s.reset();
|
|
||||||
for (auto& s : m_noTexNoZTestZWrite) s.reset();
|
|
||||||
for (auto& s : m_noTexZTestNoZWrite) s.reset();
|
|
||||||
for (auto& s : m_noTexNoZTestNoZWrite) s.reset();
|
|
||||||
for (auto& s : m_noTexAdditiveZTest) s.reset();
|
|
||||||
for (auto& s : m_noTexAdditiveNoZTest) s.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) {
|
CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) {
|
||||||
CGenDescription* desc = gen.x1c_genDesc.GetObj();
|
const auto* desc = gen.x1c_genDesc.GetObj();
|
||||||
|
|
||||||
if (desc->x54_x40_TEXR) {
|
if (desc->x54_x40_TEXR) {
|
||||||
if (desc->x58_x44_TIND)
|
if (desc->x58_x44_TIND) {
|
||||||
return EShaderClass::IndTex;
|
return EShaderClass::IndTex;
|
||||||
else
|
}
|
||||||
return EShaderClass::Tex;
|
return EShaderClass::Tex;
|
||||||
} else
|
}
|
||||||
return EShaderClass::NoTex;
|
return EShaderClass::NoTex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen) {
|
hsh::binding& CElementGenShaders::BuildShaderDataBinding(CElementGen& gen, bool pmus) {
|
||||||
CGenDescription* desc = gen.x1c_genDesc.GetObj();
|
const auto& desc = gen.x1c_genDesc;
|
||||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* regPipeline = nullptr;
|
BlendMode mode = BlendMode::Regular;
|
||||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* regPipelineSub = nullptr;
|
if (CElementGen::g_subtractBlend) {
|
||||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* redToAlphaPipeline = nullptr;
|
mode = BlendMode::Subtract;
|
||||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* redToAlphaPipelineSub = nullptr;
|
} else if (gen.x26c_26_AAPH) {
|
||||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* regPipelinePmus = nullptr;
|
mode = BlendMode::Additive;
|
||||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* redToAlphaPipelinePmus = 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;
|
|
||||||
regPipelineSub = &m_texZTestNoZWriteSub;
|
|
||||||
redToAlphaPipelineSub = &m_texRedToAlphaZTestSub;
|
|
||||||
} else {
|
|
||||||
redToAlphaPipeline = &m_texRedToAlphaNoZTest;
|
|
||||||
regPipelineSub = &m_texNoZTestNoZWriteSub;
|
|
||||||
redToAlphaPipelineSub = &m_texRedToAlphaNoZTestSub;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const CUVElement* const texr = desc->x54_x40_TEXR.get();
|
|
||||||
const CUVElement* const tind = desc->x58_x44_TIND.get();
|
|
||||||
int texCount = 0;
|
|
||||||
std::array<boo::ObjToken<boo::ITexture>, 3> textures;
|
|
||||||
|
|
||||||
if (texr) {
|
|
||||||
textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
|
||||||
texCount = 1;
|
|
||||||
if (gen.m_instBuf) {
|
|
||||||
if (tind) {
|
|
||||||
textures[1] = CGraphics::g_SpareTexture.get();
|
|
||||||
textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture();
|
|
||||||
texCount = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen.m_instBuf) {
|
|
||||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> uniforms{gen.m_uniformBuf.get()};
|
|
||||||
|
|
||||||
if (regPipeline != nullptr) {
|
|
||||||
for (size_t i = 0; i < gen.m_normalDataBind.size(); ++i) {
|
|
||||||
gen.m_normalDataBind[i] =
|
|
||||||
ctx.newShaderDataBinding((*regPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(),
|
|
||||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (regPipelineSub != nullptr) {
|
|
||||||
for (size_t i = 0; i < gen.m_normalSubDataBind.size(); ++i) {
|
|
||||||
gen.m_normalSubDataBind[i] =
|
|
||||||
ctx.newShaderDataBinding((*regPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(),
|
|
||||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (redToAlphaPipeline != nullptr) {
|
|
||||||
for (size_t i = 0; i < gen.m_redToAlphaDataBind.size(); ++i) {
|
|
||||||
gen.m_redToAlphaDataBind[i] =
|
|
||||||
ctx.newShaderDataBinding((*redToAlphaPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(),
|
|
||||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (redToAlphaPipelineSub != nullptr) {
|
|
||||||
for (size_t i = 0; i < gen.m_redToAlphaSubDataBind.size(); ++i) {
|
|
||||||
gen.m_redToAlphaSubDataBind[i] = ctx.newShaderDataBinding(
|
|
||||||
(*redToAlphaPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), uniforms.data(),
|
|
||||||
nullptr, texCount, textures.data(), nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen.m_instBufPmus) {
|
|
||||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> uniforms{gen.m_uniformBufPmus.get()};
|
|
||||||
texCount = std::min(texCount, 1);
|
|
||||||
|
|
||||||
if (regPipelinePmus != nullptr) {
|
|
||||||
for (size_t i = 0; i < gen.m_normalDataBindPmus.size(); ++i) {
|
|
||||||
gen.m_normalDataBindPmus[i] =
|
|
||||||
ctx.newShaderDataBinding((*regPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(),
|
|
||||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (redToAlphaPipelinePmus != nullptr) {
|
|
||||||
for (size_t i = 0; i < gen.m_redToAlphaDataBindPmus.size(); ++i) {
|
|
||||||
gen.m_redToAlphaDataBindPmus[i] = ctx.newShaderDataBinding(
|
|
||||||
(*redToAlphaPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(), uniforms.data(),
|
|
||||||
nullptr, texCount, textures.data(), nullptr, nullptr);
|
|
||||||
}
|
}
|
||||||
|
hsh::vertex_buffer_typeless instBuf = pmus ? gen.m_instBufPmus.get() : gen.m_instBuf.get();
|
||||||
|
hsh::uniform_buffer_typeless uniBuf = pmus ? gen.m_uniformBufPmus.get() : gen.m_uniformBuf.get();
|
||||||
|
switch (GetShaderClass(gen)) {
|
||||||
|
case EShaderClass::Tex: {
|
||||||
|
hsh::texture2d tex = desc->x54_x40_TEXR->GetValueTexture(0)->GetBooTexture();
|
||||||
|
m_shaderBind.hsh_tex_bind(
|
||||||
|
CElementGenShadersTexPipeline<mode, g_Renderer->IsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF,
|
||||||
|
CElementGen::sMoveRedToAlphaBuffer>(instBuf, uniBuf, tex));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EShaderClass::IndTex: {
|
||||||
|
hsh::texture2d texrTex = desc->x54_x40_TEXR->GetValueTexture(0)->GetBooTexture();
|
||||||
|
hsh::texture2d tindTex = desc->x58_x44_TIND->GetValueTexture(0)->GetBooTexture();
|
||||||
|
hsh::render_texture2d sceneTex = CGraphics::g_SpareTexture.get_color(0);
|
||||||
|
m_shaderBind.hsh_indtex_bind(
|
||||||
|
CElementGenShadersIndTexPipeline<mode, g_Renderer->IsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF,
|
||||||
|
desc->x45_30_x32_24_CIND>(instBuf, uniBuf, texrTex, tindTex, sceneTex));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EShaderClass::NoTex: {
|
||||||
|
m_shaderBind.hsh_notex_bind(
|
||||||
|
CElementGenShadersNoTexPipeline<mode, g_Renderer->IsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF>(
|
||||||
|
instBuf, uniBuf));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return m_shaderBind;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -8,11 +8,12 @@ class CElementGen;
|
||||||
|
|
||||||
class CElementGenShaders {
|
class CElementGenShaders {
|
||||||
hsh::binding m_shaderBind;
|
hsh::binding m_shaderBind;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class EShaderClass { Tex, IndTex, NoTex };
|
enum class EShaderClass { Tex, IndTex, NoTex };
|
||||||
|
|
||||||
static EShaderClass GetShaderClass(CElementGen& gen);
|
static EShaderClass GetShaderClass(CElementGen& gen);
|
||||||
hsh::binding& BuildShaderDataBinding(CElementGen& gen);
|
hsh::binding& BuildShaderDataBinding(CElementGen& gen, bool pmus);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -4,31 +4,54 @@
|
||||||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||||
#include "Runtime/Graphics/CGraphics.hpp"
|
#include "Runtime/Graphics/CGraphics.hpp"
|
||||||
|
|
||||||
#include "zeus/CVector2f.hpp"
|
#include "CThermalColdFilter.cpp.hshhead"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
using namespace hsh::pipeline;
|
||||||
|
|
||||||
|
struct CThermalColdFilterPipeline : pipeline<topology<hsh::TriangleStrip>,
|
||||||
|
ERglBlendModeAttachment<ERglBlendMode::Blend, ERglBlendFactor::One,
|
||||||
|
ERglBlendFactor::Zero, ERglLogicOp::Clear, true>,
|
||||||
|
depth_write<false>> {
|
||||||
|
CThermalColdFilterPipeline(hsh::vertex_buffer<CThermalColdFilter::Vert> vbo,
|
||||||
|
hsh::uniform_buffer<CThermalColdFilter::Uniform> ubo, hsh::render_texture2d sceneTex,
|
||||||
|
hsh::texture2d noiseTex) {
|
||||||
|
static hsh::float4 kRGBToYPrime = {0.257f, 0.504f, 0.098f, 0.f};
|
||||||
|
|
||||||
|
this->position = hsh::float4(vbo->m_pos, 0.f, 1.f);
|
||||||
|
hsh::float4 noiseTexel = noiseTex.read<float>(Lookup8BPP(vbo->m_uvNoise, ubo->m_randOff));
|
||||||
|
hsh::float2 indCoord = (hsh::float3x3(ubo->m_indMtx[0].xyz(), ubo->m_indMtx[1].xyz(), ubo->m_indMtx[2].xyz()) *
|
||||||
|
hsh::float3(noiseTexel.x - 0.5f, noiseTexel.w - 0.5f, 1.f))
|
||||||
|
.xy();
|
||||||
|
hsh::float2 sceneUv = vbo->m_uv + indCoord;
|
||||||
|
sceneUv.y = 1.f - sceneUv.y;
|
||||||
|
float indScene = hsh::dot(sceneTex.sample<float>(sceneUv), kRGBToYPrime) + 16.f / 255.f;
|
||||||
|
this->color_out[0] = ubo->m_colorRegs[0] * indScene + ubo->m_colorRegs[2] - ubo->m_colorRegs[1] * noiseTexel.x;
|
||||||
|
this->color_out[0].w = ubo->m_colorRegs[1].x + ubo->m_colorRegs[1].w * noiseTexel.x + ubo->m_colorRegs[2].w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr hsh::uint2 Lookup8BPP(hsh::float2 uv, float randOff) {
|
||||||
|
int bx = int(uv.x) >> 3;
|
||||||
|
int rx = int(uv.x) & 0x7;
|
||||||
|
int by = int(uv.y) >> 2;
|
||||||
|
int ry = int(uv.y) & 0x3;
|
||||||
|
int bidx = by * 128 + bx;
|
||||||
|
int addr = bidx * 32 + ry * 8 + rx + int(randOff);
|
||||||
|
return hsh::uint2(addr & 0x3ff, addr >> 10);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
CThermalColdFilter::CThermalColdFilter() {
|
CThermalColdFilter::CThermalColdFilter() {
|
||||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
|
||||||
const std::array<Vert, 4> verts{{
|
const std::array<Vert, 4> verts{{
|
||||||
{{-1.f, -1.f}, {0.f, 0.f}, {0.f, 0.f}},
|
{{-1.f, -1.f}, {0.f, 0.f}, {0.f, 0.f}},
|
||||||
{{-1.f, 1.f}, {0.f, 1.f}, {0.f, 448.f}},
|
{{-1.f, 1.f}, {0.f, 1.f}, {0.f, 448.f}},
|
||||||
{{1.f, -1.f}, {1.f, 0.f}, {640.f, 0.f}},
|
{{1.f, -1.f}, {1.f, 0.f}, {640.f, 0.f}},
|
||||||
{{1.f, 1.f}, {1.f, 1.f}, {640.f, 448.f}},
|
{{1.f, 1.f}, {1.f, 1.f}, {640.f, 448.f}},
|
||||||
}};
|
}};
|
||||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 48, verts.size());
|
m_vbo = hsh::create_vertex_buffer(verts);
|
||||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
m_uniBuf = hsh::create_dynamic_uniform_buffer<Uniform>();
|
||||||
|
m_dataBind.hsh_bind(CThermalColdFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0),
|
||||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> bufs{m_uniBuf.get()};
|
g_Renderer->GetRandomStaticEntropyTex()));
|
||||||
constexpr std::array<boo::PipelineStage, 1> stages{boo::PipelineStage::Vertex};
|
|
||||||
const std::array<boo::ObjToken<boo::ITexture>, 2> texs{
|
|
||||||
CGraphics::g_SpareTexture.get(),
|
|
||||||
g_Renderer->GetRandomStaticEntropyTex(),
|
|
||||||
};
|
|
||||||
m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(),
|
|
||||||
stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr);
|
|
||||||
return true;
|
|
||||||
} BooTrace);
|
|
||||||
|
|
||||||
setNoiseOffset(0);
|
setNoiseOffset(0);
|
||||||
setScale(0.f);
|
setScale(0.f);
|
||||||
|
@ -38,9 +61,8 @@ void CThermalColdFilter::draw() {
|
||||||
SCOPED_GRAPHICS_DEBUG_GROUP("CThermalColdFilter::draw", zeus::skMagenta);
|
SCOPED_GRAPHICS_DEBUG_GROUP("CThermalColdFilter::draw", zeus::skMagenta);
|
||||||
|
|
||||||
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
|
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
|
||||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
m_uniBuf.load(m_uniform);
|
||||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
m_dataBind.draw(0, 4);
|
||||||
CGraphics::DrawArray(0, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -8,20 +8,23 @@
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
class CThermalColdFilter {
|
class CThermalColdFilter {
|
||||||
|
public:
|
||||||
struct Uniform {
|
struct Uniform {
|
||||||
zeus::CMatrix4f m_indMtx;
|
hsh::float4x4 m_indMtx;
|
||||||
std::array<zeus::CColor, 3> m_colorRegs;
|
std::array<hsh::float4, 3> m_colorRegs;
|
||||||
float m_randOff = 0.f;
|
float m_randOff = 0.f;
|
||||||
};
|
};
|
||||||
struct Vert {
|
struct Vert {
|
||||||
zeus::CVector2f m_pos;
|
hsh::float2 m_pos;
|
||||||
zeus::CVector2f m_uv;
|
hsh::float2 m_uv;
|
||||||
zeus::CVector2f m_uvNoise;
|
hsh::float2 m_uvNoise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||||
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
||||||
hsh::binding m_dataBind;
|
hsh::binding m_dataBind;
|
||||||
Uniform m_uniform;
|
Uniform m_uniform{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CThermalColdFilter();
|
CThermalColdFilter();
|
||||||
|
|
|
@ -4,42 +4,49 @@
|
||||||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||||
#include "Runtime/Graphics/CGraphics.hpp"
|
#include "Runtime/Graphics/CGraphics.hpp"
|
||||||
|
|
||||||
#include "zeus/CVector2f.hpp"
|
#include "CThermalHotFilter.cpp.hshhead"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
using namespace hsh::pipeline;
|
||||||
|
|
||||||
|
struct CThermalHotFilterPipeline
|
||||||
|
: pipeline<ERglBlendModeAttachment<ERglBlendMode::Blend, ERglBlendFactor::DstAlpha, ERglBlendFactor::InvDstAlpha,
|
||||||
|
ERglLogicOp::Clear, true>,
|
||||||
|
depth_write<false>> {
|
||||||
|
CThermalHotFilterPipeline(hsh::vertex_buffer<CThermalHotFilter::Vert> vbo,
|
||||||
|
hsh::uniform_buffer<CThermalHotFilter::Uniform> ubo, hsh::render_texture2d sceneTex,
|
||||||
|
hsh::texture2d paletteTex) {
|
||||||
|
static hsh::float4 kRGBToYPrime = {0.257f, 0.504f, 0.098f, 0.f};
|
||||||
|
|
||||||
|
this->position = hsh::float4(vbo->m_pos, 0.f, 1.f);
|
||||||
|
|
||||||
|
hsh::float2 sceneUv = vbo->m_uv;
|
||||||
|
sceneUv.y = 1.f - sceneUv.y;
|
||||||
|
float sceneSample = hsh::dot(sceneTex.sample<float>(sceneUv), kRGBToYPrime) + 16.f / 255.f;
|
||||||
|
hsh::float4 colorSample = paletteTex.sample<float>(hsh::float2(sceneSample / 16.f, 0.5f));
|
||||||
|
this->color_out[0] = hsh::float4(colorSample.xyz(), 0.f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
CThermalHotFilter::CThermalHotFilter() {
|
CThermalHotFilter::CThermalHotFilter() {
|
||||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
|
||||||
const std::array<Vert, 4> verts{{
|
const std::array<Vert, 4> verts{{
|
||||||
{{-1.0, -1.0}, {0.0, 0.0}},
|
{{-1.0, -1.0}, {0.0, 0.0}},
|
||||||
{{-1.0, 1.0}, {0.0, 1.0}},
|
{{-1.0, 1.0}, {0.0, 1.0}},
|
||||||
{{1.0, -1.0}, {1.0, 0.0}},
|
{{1.0, -1.0}, {1.0, 0.0}},
|
||||||
{{1.0, 1.0}, {1.0, 1.0}},
|
{{1.0, 1.0}, {1.0, 1.0}},
|
||||||
}};
|
}};
|
||||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size());
|
m_vbo = hsh::create_vertex_buffer(verts);
|
||||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
m_uniBuf = hsh::create_dynamic_uniform_buffer<Uniform>();
|
||||||
|
m_dataBind.hsh_bind(CThermalHotFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0),
|
||||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> bufs{m_uniBuf.get()};
|
g_Renderer->GetThermoPalette()));
|
||||||
constexpr std::array<boo::PipelineStage, 1> stages{boo::PipelineStage::Vertex};
|
|
||||||
const std::array<boo::ObjToken<boo::ITexture>, 2> texs{
|
|
||||||
CGraphics::g_SpareTexture.get(),
|
|
||||||
g_Renderer->GetThermoPalette(),
|
|
||||||
};
|
|
||||||
m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(),
|
|
||||||
stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr);
|
|
||||||
return true;
|
|
||||||
} BooTrace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CThermalHotFilter::draw() {
|
void CThermalHotFilter::draw() {
|
||||||
SCOPED_GRAPHICS_DEBUG_GROUP("CThermalHotFilter::draw", zeus::skMagenta);
|
SCOPED_GRAPHICS_DEBUG_GROUP("CThermalHotFilter::draw", zeus::skMagenta);
|
||||||
|
|
||||||
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
|
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
|
||||||
|
m_uniBuf.load(m_uniform);
|
||||||
// m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
m_dataBind.draw(0, 4);
|
||||||
|
|
||||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
|
||||||
CGraphics::DrawArray(0, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -2,22 +2,26 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include "hsh/hsh.h"
|
||||||
#include "zeus/CColor.hpp"
|
#include "zeus/CColor.hpp"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
class CThermalHotFilter {
|
class CThermalHotFilter {
|
||||||
|
public:
|
||||||
struct Uniform {
|
struct Uniform {
|
||||||
std::array<zeus::CColor, 3> m_colorRegs;
|
std::array<hsh::float4, 3> m_colorRegs;
|
||||||
};
|
};
|
||||||
struct Vert {
|
struct Vert {
|
||||||
zeus::CVector2f m_pos;
|
hsh::float2 m_pos;
|
||||||
zeus::CVector2f m_uv;
|
hsh::float2 m_uv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||||
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
||||||
hsh::binding m_dataBind;
|
hsh::binding m_dataBind;
|
||||||
Uniform m_uniform;
|
Uniform m_uniform{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CThermalHotFilter();
|
CThermalHotFilter();
|
||||||
|
|
|
@ -200,8 +200,8 @@ void CGuiFrame::ProcessUserInput(const CFinalInput& input) const {
|
||||||
|
|
||||||
bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDrawParms& parms) {
|
bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDrawParms& parms) {
|
||||||
if (const auto& kbm = input.GetKBM()) {
|
if (const auto& kbm = input.GetKBM()) {
|
||||||
zeus::CVector2f point(kbm->m_mouseCoord.norm[0] * 2.f - 1.f,
|
zeus::CVector2f point(kbm->m_mouseCoord.x * 2.f - 1.f,
|
||||||
kbm->m_mouseCoord.norm[1] * 2.f - 1.f);
|
kbm->m_mouseCoord.y * 2.f - 1.f);
|
||||||
CGuiWidget* hit = BestCursorHit(point, parms);
|
CGuiWidget* hit = BestCursorHit(point, parms);
|
||||||
if (hit != m_lastMouseOverWidget) {
|
if (hit != m_lastMouseOverWidget) {
|
||||||
if (m_inMouseDown && m_mouseDownWidget != hit) {
|
if (m_inMouseDown && m_mouseDownWidget != hit) {
|
||||||
|
@ -220,14 +220,14 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw
|
||||||
m_lastMouseOverWidget = hit;
|
m_lastMouseOverWidget = hit;
|
||||||
}
|
}
|
||||||
if (hit && hit->m_lastScroll) {
|
if (hit && hit->m_lastScroll) {
|
||||||
boo::SScrollDelta delta = kbm->m_accumScroll - *hit->m_lastScroll;
|
auto delta = kbm->m_accumScroll - *hit->m_lastScroll;
|
||||||
hit->m_lastScroll.emplace(kbm->m_accumScroll);
|
hit->m_lastScroll.emplace(kbm->m_accumScroll);
|
||||||
if (!delta.isZero()) {
|
if (delta.x != 0.0 || delta.y != 0.0) {
|
||||||
hit->m_integerScroll += delta;
|
hit->m_integerScroll += delta;
|
||||||
if (m_mouseScrollCb)
|
if (m_mouseScrollCb)
|
||||||
m_mouseScrollCb(hit, delta, int(hit->m_integerScroll.delta[0]), int(hit->m_integerScroll.delta[1]));
|
m_mouseScrollCb(hit, delta, int(hit->m_integerScroll.x), int(hit->m_integerScroll.y));
|
||||||
hit->m_integerScroll.delta[0] -= std::trunc(hit->m_integerScroll.delta[0]);
|
hit->m_integerScroll.x -= std::trunc(hit->m_integerScroll.x);
|
||||||
hit->m_integerScroll.delta[1] -= std::trunc(hit->m_integerScroll.delta[1]);
|
hit->m_integerScroll.y -= std::trunc(hit->m_integerScroll.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_inMouseDown && kbm->m_mouseButtons[size_t(boo2::MouseButton::Primary)]) {
|
if (!m_inMouseDown && kbm->m_mouseButtons[size_t(boo2::MouseButton::Primary)]) {
|
||||||
|
|
|
@ -213,22 +213,28 @@ CElementGen::CElementGen(TToken<CGenDescription> gen, EModelOrientationType orie
|
||||||
if (!x26c_31_LINE) {
|
if (!x26c_31_LINE) {
|
||||||
switch (m_shaderClass) {
|
switch (m_shaderClass) {
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts); break;
|
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts);
|
||||||
|
break;
|
||||||
case CElementGenShaders::EShaderClass::IndTex:
|
case CElementGenShaders::EShaderClass::IndTex:
|
||||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts); break;
|
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts);
|
||||||
|
break;
|
||||||
case CElementGenShaders::EShaderClass::NoTex:
|
case CElementGenShaders::EShaderClass::NoTex:
|
||||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts); break;
|
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
m_uniformBuf = hsh::create_dynamic_uniform_buffer<SParticleUniforms>();
|
m_uniformBuf = hsh::create_dynamic_uniform_buffer<SParticleUniforms>();
|
||||||
}
|
}
|
||||||
if (desc->x45_24_x31_26_PMUS) {
|
if (desc->x45_24_x31_26_PMUS) {
|
||||||
switch (m_shaderClass) {
|
switch (m_shaderClass) {
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts); break;
|
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts);
|
||||||
|
break;
|
||||||
case CElementGenShaders::EShaderClass::IndTex:
|
case CElementGenShaders::EShaderClass::IndTex:
|
||||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts); break;
|
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts);
|
||||||
|
break;
|
||||||
case CElementGenShaders::EShaderClass::NoTex:
|
case CElementGenShaders::EShaderClass::NoTex:
|
||||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts); break;
|
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
m_uniformBufPmus = hsh::create_dynamic_uniform_buffer<SParticleUniforms>();
|
m_uniformBufPmus = hsh::create_dynamic_uniform_buffer<SParticleUniforms>();
|
||||||
}
|
}
|
||||||
|
@ -907,14 +913,6 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
|
||||||
}
|
}
|
||||||
|
|
||||||
m_uniformBufPmus.load({CGraphics::GetPerspectiveProjectionMatrix(true), {1.f, 1.f, 1.f, 1.f}});
|
m_uniformBufPmus.load({CGraphics::GetPerspectiveProjectionMatrix(true), {1.f, 1.f, 1.f, 1.f}});
|
||||||
|
|
||||||
// TODO: Implement in builder
|
|
||||||
#if 0
|
|
||||||
if (moveRedToAlphaBuffer)
|
|
||||||
CGraphics::SetShaderDataBinding(m_redToAlphaDataBindPmus[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
else
|
|
||||||
CGraphics::SetShaderDataBinding(m_normalDataBindPmus[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CTransform orient = zeus::CTransform();
|
zeus::CTransform orient = zeus::CTransform();
|
||||||
|
@ -1064,11 +1062,11 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
|
||||||
switch (m_shaderClass) {
|
switch (m_shaderClass) {
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
m_instBufPmus.load<SParticleInstanceTex>(g_instTexData);
|
m_instBufPmus.load<SParticleInstanceTex>(g_instTexData);
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instTexData.size());
|
m_shaderBuilder.BuildShaderDataBinding(*this, true).draw_instanced(0, 4, g_instTexData.size());
|
||||||
break;
|
break;
|
||||||
case CElementGenShaders::EShaderClass::NoTex:
|
case CElementGenShaders::EShaderClass::NoTex:
|
||||||
m_instBufPmus.load<SParticleInstanceNoTex>(g_instNoTexData);
|
m_instBufPmus.load<SParticleInstanceNoTex>(g_instNoTexData);
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instNoTexData.size());
|
m_shaderBuilder.BuildShaderDataBinding(*this, true).draw_instanced(0, 4, g_instNoTexData.size());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1194,12 +1192,12 @@ void CElementGen::RenderParticles() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CRealElement* size = desc->x4c_x38_SIZE.get();
|
CRealElement* sizeElem = desc->x4c_x38_SIZE.get();
|
||||||
if (size && size->IsConstant()) {
|
if (sizeElem && sizeElem->IsConstant()) {
|
||||||
float sizeVal;
|
float sizeVal;
|
||||||
size->GetValue(0, sizeVal);
|
sizeElem->GetValue(0, sizeVal);
|
||||||
if (sizeVal == 0.f) {
|
if (sizeVal == 0.f) {
|
||||||
size->GetValue(1, sizeVal);
|
sizeElem->GetValue(1, sizeVal);
|
||||||
if (sizeVal == 0.f)
|
if (sizeVal == 0.f)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1263,22 +1261,6 @@ void CElementGen::RenderParticles() {
|
||||||
if (sMoveRedToAlphaBuffer && x26c_26_AAPH)
|
if (sMoveRedToAlphaBuffer && x26c_26_AAPH)
|
||||||
moveRedToAlphaBuffer = true;
|
moveRedToAlphaBuffer = true;
|
||||||
|
|
||||||
// TODO: Implement in builder
|
|
||||||
#if 0
|
|
||||||
if (g_subtractBlend) {
|
|
||||||
// FIXME should there be NoTex specializations for RedToAlpha?
|
|
||||||
if (moveRedToAlphaBuffer && desc->x54_x40_TEXR)
|
|
||||||
CGraphics::SetShaderDataBinding(m_redToAlphaSubDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
else
|
|
||||||
CGraphics::SetShaderDataBinding(m_normalSubDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
} else {
|
|
||||||
if (moveRedToAlphaBuffer && desc->x54_x40_TEXR)
|
|
||||||
CGraphics::SetShaderDataBinding(m_redToAlphaDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
else
|
|
||||||
CGraphics::SetShaderDataBinding(m_normalDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int mbspVal = std::max(1, x270_MBSP);
|
int mbspVal = std::max(1, x270_MBSP);
|
||||||
|
|
||||||
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
|
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
|
||||||
|
@ -1490,11 +1472,11 @@ void CElementGen::RenderParticles() {
|
||||||
switch (m_shaderClass) {
|
switch (m_shaderClass) {
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
m_instBuf.load<SParticleInstanceTex>(g_instTexData);
|
m_instBuf.load<SParticleInstanceTex>(g_instTexData);
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instTexData.size());
|
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instTexData.size());
|
||||||
break;
|
break;
|
||||||
case CElementGenShaders::EShaderClass::NoTex:
|
case CElementGenShaders::EShaderClass::NoTex:
|
||||||
m_instBuf.load<SParticleInstanceNoTex>(g_instNoTexData);
|
m_instBuf.load<SParticleInstanceNoTex>(g_instNoTexData);
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instNoTexData.size());
|
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instNoTexData.size());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1604,11 +1586,11 @@ void CElementGen::RenderParticles() {
|
||||||
switch (m_shaderClass) {
|
switch (m_shaderClass) {
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
m_instBuf.load<SParticleInstanceTex>(g_instTexData);
|
m_instBuf.load<SParticleInstanceTex>(g_instTexData);
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instTexData.size());
|
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instTexData.size());
|
||||||
break;
|
break;
|
||||||
case CElementGenShaders::EShaderClass::NoTex:
|
case CElementGenShaders::EShaderClass::NoTex:
|
||||||
m_instBuf.load<SParticleInstanceNoTex>(g_instNoTexData);
|
m_instBuf.load<SParticleInstanceNoTex>(g_instNoTexData);
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instNoTexData.size());
|
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instNoTexData.size());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1681,12 +1663,6 @@ void CElementGen::RenderParticlesIndirectTexture() {
|
||||||
g_instIndTexData.clear();
|
g_instIndTexData.clear();
|
||||||
g_instIndTexData.reserve(x30_particles.size());
|
g_instIndTexData.reserve(x30_particles.size());
|
||||||
|
|
||||||
// TODO: move to builder
|
|
||||||
#if 0
|
|
||||||
if (!x30_particles.empty())
|
|
||||||
CGraphics::SetShaderDataBinding(m_normalDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (size_t i = 0; i < x30_particles.size(); ++i) {
|
for (size_t i = 0; i < x30_particles.size(); ++i) {
|
||||||
const int partIdx = desc->x44_28_x30_28_SORT ? sortItems[i].x0_partIdx : int(i);
|
const int partIdx = desc->x44_28_x30_28_SORT ? sortItems[i].x0_partIdx : int(i);
|
||||||
CParticle& particle = x30_particles[partIdx];
|
CParticle& particle = x30_particles[partIdx];
|
||||||
|
@ -1743,9 +1719,9 @@ void CElementGen::RenderParticlesIndirectTexture() {
|
||||||
inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax};
|
inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax};
|
||||||
inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin};
|
inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin};
|
||||||
inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMin, uvsInd.yMin};
|
inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMin, uvsInd.yMin};
|
||||||
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, 1.f - clipRect.x24_uvYMax, clipRect.x1c_uvXMax,
|
inst.sceneUVs =
|
||||||
1.f - clipRect.x20_uvYMin};
|
zeus::CVector4f{clipRect.x18_uvXMin, 1.f - clipRect.x24_uvYMax, clipRect.x1c_uvXMax, 1.f - clipRect.x20_uvYMin};
|
||||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instIndTexData.size() - 1);
|
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instIndTexData.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_instIndTexData.empty()) {
|
if (!g_instIndTexData.empty()) {
|
||||||
|
|
Loading…
Reference in New Issue