Various bug fixes and CActor rendering

This commit is contained in:
Jack Andersen 2018-02-04 20:56:09 -10:00
parent acf2dab66f
commit ac8dfde174
38 changed files with 549 additions and 142 deletions

View File

@ -76,7 +76,7 @@ public:
void StartMixing()
{
//m_voice->start();
m_voice->start();
}
void StopMixing()
{

View File

@ -288,7 +288,7 @@ void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx,
break;
}
case 1:
reinterpret_cast<const CSimpleShadow*>(drawable)->Render(mgr.x8f0_shadowTex.GetObj());
reinterpret_cast<const CSimpleShadow*>(drawable)->Render(mgr.x8f0_shadowTex);
break;
case 2:
reinterpret_cast<const CDecal*>(drawable)->Render();
@ -578,6 +578,25 @@ void CStateManager::DrawAdditionalFilters() const
}
}
zeus::CFrustum CStateManager::SetupDrawFrustum(const SViewport& vp) const
{
zeus::CFrustum ret;
const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this);
zeus::CTransform camXf = x870_cameraManager->GetCurrentCameraTransform(*this);
//int vpWidth = xf2c_viewportScale.x * vp.x8_width;
//int vpHeight = xf2c_viewportScale.y * vp.xc_height;
//int vpLeft = (vp.x8_width - vpWidth) / 2 + vp.x0_left;
//int vpTop = (vp.xc_height - vpHeight) / 2 + vp.x4_top;
//g_Renderer->SetViewport(vpLeft, vpTop, vpWidth, vpHeight);
float fov = std::atan(std::tan(zeus::degToRad(cam->GetFov()) * 0.5f) * xf2c_viewportScale.y) * 2.f;
float width = xf2c_viewportScale.x * vp.x8_width;
float height = xf2c_viewportScale.y * vp.xc_height;
zeus::CProjection proj;
proj.setPersp(zeus::SProjPersp{fov, width / height, cam->GetNearClipDistance(), cam->GetFarClipDistance()});
ret.updatePlanes(camXf, proj);
return ret;
}
zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const
{
const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this);
@ -616,7 +635,7 @@ void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport,
zeus::CFrustum frustum;
frustum.updatePlanes(backupViewMatrix, zeus::SProjPersp(zeus::degToRad(cam->GetFov()),
cam->GetAspectRatio(),
g_Viewport.x8_width / float(g_Viewport.xc_height),
cam->GetNearClipDistance(),
cam->GetFarClipDistance()));
g_Renderer->SetClippingPlanes(frustum);
@ -681,13 +700,13 @@ void CStateManager::DrawWorld() const
bool thermal = visor == CPlayerState::EPlayerVisor::Thermal;
if (thermal)
{
const_cast<CStateManager&>(*this).xf34_particleFlags = 1;
const_cast<CStateManager&>(*this).xf34_thermalFlag = EThermalDrawFlag::Cold;
mask = 0x34;
targetMask = 0;
}
else
{
const_cast<CStateManager&>(*this).xf34_particleFlags = 2;
const_cast<CStateManager&>(*this).xf34_thermalFlag = EThermalDrawFlag::Bypass;
mask = 1 << (visor == CPlayerState::EPlayerVisor::XRay ? 3 : 1);
targetMask = 0;
}
@ -796,6 +815,7 @@ void CStateManager::DrawWorld() const
CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR);
}
g_Renderer->DoThermalBlendCold();
const_cast<CStateManager&>(*this).xf34_thermalFlag = EThermalDrawFlag::Hot;
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
@ -871,7 +891,7 @@ void CStateManager::DrawWorld() const
{
g_Renderer->DoThermalBlendHot();
g_Renderer->SetThermal(false, 0.f, zeus::CColor::skBlack);
const_cast<CStateManager&>(*this).xf34_particleFlags = 2;
const_cast<CStateManager&>(*this).xf34_thermalFlag = EThermalDrawFlag::Bypass;
}
DrawDebugStuff();
@ -923,19 +943,14 @@ bool CStateManager::SetupFogForDraw() const
void CStateManager::PreRender()
{
if (xf94_24_)
if (xf94_24_readyToRender)
{
zeus::CFrustum frustum = SetupDrawFrustum(g_Viewport);
x86c_stateManagerContainer->xf370_.clear();
x86c_stateManagerContainer->xf39c_renderLast.clear();
xf7c_projectedShadow = nullptr;
x850_world->PreRender();
BuildDynamicLightListForWorld();
CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this);
zeus::CFrustum frustum;
zeus::CProjection proj;
proj.setPersp(zeus::SProjPersp{zeus::degToRad(cam->GetFov()),
cam->GetAspectRatio(), cam->GetNearClipDistance(), cam->GetFarClipDistance()});
frustum.updatePlanes(x870_cameraManager->GetCurrentCameraTransform(*this), proj);
for (const CGameArea& area : *x850_world)
{
CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::Occluded;
@ -1939,7 +1954,7 @@ void CStateManager::Update(float dt)
UpdateAreaSounds();
xf94_24_ = true;
xf94_24_readyToRender = true;
if (xf94_27_inMapScreen)
{

View File

@ -77,6 +77,13 @@ enum class EStateManagerTransition
MessageScreen
};
enum class EThermalDrawFlag
{
Hot,
Cold,
Bypass
};
class CStateManager
{
friend class MP1::CMFGameLoader;
@ -193,7 +200,7 @@ private:
float xf24_thermColdScale1 = 0.f;
float xf28_thermColdScale2 = 0.f;
zeus::CVector2f xf2c_viewportScale = {1.f, 1.f};
u32 xf34_particleFlags = 2;
EThermalDrawFlag xf34_thermalFlag = EThermalDrawFlag::Bypass;
TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId;
std::list<u32> xf3c_;
std::list<u32> xf54_;
@ -215,7 +222,7 @@ private:
{
struct
{
bool xf94_24_ : 1;
bool xf94_24_readyToRender : 1;
bool xf94_25_quitGame : 1;
bool xf94_26_generatingObject : 1;
bool xf94_27_inMapScreen : 1;
@ -268,6 +275,7 @@ public:
void RenderCamerasAndAreaLights() const;
void DrawE3DeathEffect() const;
void DrawAdditionalFilters() const;
zeus::CFrustum SetupDrawFrustum(const SViewport& vp) const;
zeus::CFrustum SetupViewForDraw(const SViewport& vp) const;
void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const;
void DrawWorld() const;
@ -431,7 +439,7 @@ public:
TUniqueId GetLastRelayId() const { return xf76_lastRelay; }
bool GetIsGeneratingObject() const { return xf94_26_generatingObject; }
void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; }
u32 GetParticleFlags() const { return xf34_particleFlags; }
EThermalDrawFlag GetThermalDrawFlag() const { return xf34_thermalFlag; }
const CFinalInput& GetFinalInput() const { return xb54_finalInput; }
void SetBossParams(TUniqueId bossId, float maxEnergy, u32 stringIdx);
TUniqueId GetBossId() const { return xf18_bossId; }
@ -439,6 +447,7 @@ public:
u32 GetBossStringIdx() const { return xf20_bossStringIdx; }
const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; }
void SetViewportScale(const zeus::CVector2f& scale) { xf2c_viewportScale = scale; }
float GetThermalColdScale1() const { return xf24_thermColdScale1; }
float GetThermalColdScale2() const { return xf28_thermColdScale2; }
void SetThermalColdScale2(float s) { xf28_thermColdScale2 = s; }
float IntegrateVisorFog(float f) const;

View File

@ -88,7 +88,9 @@ CModelData::EWhichModel CModelData::GetRenderingModel(const CStateManager& state
case CPlayerState::EPlayerVisor::XRay:
return CModelData::EWhichModel::XRay;
case CPlayerState::EPlayerVisor::Thermal:
return CModelData::EWhichModel::Thermal;
if (stateMgr.GetThermalDrawFlag() == EThermalDrawFlag::Cold)
return CModelData::EWhichModel::Thermal;
return CModelData::EWhichModel::ThermalHot;
default:
return CModelData::EWhichModel::Normal;
}
@ -103,6 +105,7 @@ CSkinnedModel& CModelData::PickAnimatedModel(EWhichModel which) const
ret = x10_animData->xf4_xrayModel.get();
break;
case EWhichModel::Thermal:
case EWhichModel::ThermalHot:
ret = x10_animData->xf8_infraModel.get();
break;
default: break;
@ -121,6 +124,7 @@ const std::unique_ptr<CBooModel>& CModelData::PickStaticModel(EWhichModel which)
ret = &m_xrayModelInst;
break;
case EWhichModel::Thermal:
case EWhichModel::ThermalHot:
ret = &m_infraModelInst;
break;
default: break;
@ -323,23 +327,25 @@ void CModelData::Touch(const CStateManager& stateMgr, int shaderIdx) const
Touch(const_cast<CModelData&>(*this).GetRenderingModel(stateMgr), shaderIdx);
}
void CModelData::RenderThermal(const zeus::CTransform& xf,
const zeus::CColor& a, const zeus::CColor& b) const
void CModelData::RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor,
const zeus::CColor& addColor, const CModelFlags& flags) const
{
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale));
CGraphics::DisableAllLights();
CModelFlags drawFlags;
drawFlags.m_extendedShader = EExtendedShader::ForcedAlpha;
CModelFlags drawFlags = flags;
drawFlags.x4_color *= mulColor;
drawFlags.addColor = addColor;
drawFlags.m_extendedShader = EExtendedShader::Thermal;
if (x10_animData)
{
CSkinnedModel& model = PickAnimatedModel(EWhichModel::Thermal);
CSkinnedModel& model = PickAnimatedModel(EWhichModel::ThermalHot);
x10_animData->SetupRender(model, drawFlags, {}, nullptr);
model.Draw(drawFlags);
}
else
{
const auto& model = PickStaticModel(EWhichModel::Thermal);
const auto& model = PickStaticModel(EWhichModel::ThermalHot);
model->Draw(drawFlags, nullptr, nullptr);
}
}
@ -347,8 +353,8 @@ void CModelData::RenderThermal(const zeus::CTransform& xf,
void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& xf,
const CActorLights* lights, const CModelFlags& drawFlags) const
{
if ((x14_25_sortThermal && which == EWhichModel::Thermal) ||
x10_animData || !x1c_normalModel || drawFlags.x0_blendMode > 2)
if ((x14_25_sortThermal && which == EWhichModel::ThermalHot) ||
x10_animData || !x1c_normalModel || drawFlags.x0_blendMode > 4)
{
const_cast<CModelData*>(this)->x14_24_renderSorted = false;
return;
@ -371,10 +377,10 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform&
void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
const CActorLights* lights, const CModelFlags& drawFlags) const
{
if (x14_25_sortThermal && which == EWhichModel::Thermal)
if (x14_25_sortThermal && which == EWhichModel::ThermalHot)
{
zeus::CColor mul(drawFlags.x4_color.a, drawFlags.x4_color.a, drawFlags.x4_color.a, drawFlags.x4_color.a);
RenderThermal(xf, mul, {0.f, 0.f, 0.f, 0.25f});
zeus::CColor mul(drawFlags.x4_color.a, drawFlags.x4_color.a);
RenderThermal(xf, mul, {0.f, 0.f, 0.f, 0.25f}, drawFlags);
}
else
{

View File

@ -95,10 +95,12 @@ public:
{
Normal,
XRay,
Thermal
Thermal,
ThermalHot
};
void SetSortThermal(bool v) { x14_25_sortThermal = v; }
bool GetSortThermal() const { return x14_25_sortThermal; }
~CModelData();
CModelData(const CStaticRes& res, int instCount=1);
@ -135,7 +137,8 @@ public:
void RenderParticles(const zeus::CFrustum& frustum) const;
void Touch(EWhichModel, int shaderIdx) const;
void Touch(const CStateManager& stateMgr, int shaderIdx) const;
void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& a, const zeus::CColor& b) const;
void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor,
const zeus::CColor& addColor, const CModelFlags& flags) const;
void RenderUnsortedParts(EWhichModel, const zeus::CTransform& xf,
const CActorLights* lights, const CModelFlags& drawFlags) const;
void Render(EWhichModel, const zeus::CTransform& xf,

View File

@ -714,9 +714,11 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
{
case UVAnimation::Mode::MvInvNoTranslation:
{
/* Handled in-shader
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
texMtxOut.vec[3].zeroOut();
texMtxOut.vec[3].w = 1.f;
*/
postMtxOut.vec[0].x = 0.5f;
postMtxOut.vec[1].y = 0.5f;
postMtxOut.vec[3].x = 0.5f;
@ -725,7 +727,8 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
}
case UVAnimation::Mode::MvInv:
{
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
texMtxOut.vec[3] = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix.origin;
texMtxOut.vec[3].w = 1.f;
postMtxOut.vec[0].x = 0.5f;
postMtxOut.vec[1].y = 0.5f;
postMtxOut.vec[3].x = 0.5f;
@ -767,7 +770,6 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
{
texMtxOut = CGraphics::g_GXModelMatrix.toMatrix4f();
texMtxOut.vec[3].zeroOut();
postMtxOut.vec[0].x = 0.5f;
postMtxOut.vec[1].y = 0.f;
postMtxOut.vec[2].y = 0.5f;
@ -777,9 +779,11 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
}
case UVAnimation::Mode::CylinderEnvironment:
{
/* Handled in-shader
//texMtxOut = (CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix).toMatrix4f();
texMtxOut = CGraphics::g_GXModelView.toMatrix4f();
texMtxOut.vec[3].zeroOut();
*/
const zeus::CVector3f& viewOrigin = CGraphics::g_ViewMatrix.origin;
float xy = (viewOrigin.x + viewOrigin.y) * 0.025f * anim.vals[1];
@ -848,10 +852,12 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet
/* Special Mode0 matrix for exclusive Thermal Visor use */
specialMtxOut.emplace();
/* This part handled in-shader
zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0];
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
texMtxOut.vec[3].zeroOut();
texMtxOut.vec[3].w = 1.f;
*/
zeus::CMatrix4f& postMtxOut = (*specialMtxOut)[1];
postMtxOut.vec[0].x = 0.5f;

View File

@ -1,14 +1,99 @@
#include "CSimpleShadow.hpp"
#include "CStateManager.hpp"
#include "Collision/CGameCollision.hpp"
namespace urde
{
CSimpleShadow::CSimpleShadow(float, float, float, float)
CSimpleShadow::CSimpleShadow(float scale, float userAlpha, float maxObjHeight, float displacement)
: x30_scale(scale), x38_userAlpha(userAlpha), x40_maxObjHeight(maxObjHeight), x44_displacement(displacement)
{
x48_24_collision = false;
x48_25_alwaysCalculateRadius = true;
x48_26_radiusCalculated = false;
}
void CSimpleShadow::Render(const CTexture* tex) const
zeus::CAABox CSimpleShadow::GetMaxShadowBox(const zeus::CAABox& aabb) const
{
float extent = x34_radius * x30_scale;
zeus::CVector3f center = aabb.center();
zeus::CAABox expandedAABB = aabb;
expandedAABB.accumulateBounds({center.x + extent, center.y + extent, center.z - GetMaxObjectHeight()});
expandedAABB.accumulateBounds({center.x - extent, center.y - extent, center.z - GetMaxObjectHeight()});
return expandedAABB;
}
zeus::CAABox CSimpleShadow::GetBounds() const
{
float extent = x34_radius * x30_scale;
return {{x0_xf.origin.x - extent, x0_xf.origin.y - extent, x0_xf.origin.z - extent},
{x0_xf.origin.x + extent, x0_xf.origin.y + extent, x0_xf.origin.z + extent}};
}
void CSimpleShadow::Render(const TLockedToken<CTexture>& tex) const
{
if (!x48_24_collision)
return;
CGraphics::DisableAllLights();
CGraphics::SetModelMatrix(x0_xf);
if (!m_filter || m_filter->GetTex().GetObj() != tex.GetObj())
m_filter.emplace(EFilterType::Blend, tex, CTexturedQuadFilter::ZTest::LEqual);
float radius = x34_radius * x30_scale;
CTexturedQuadFilter::Vert verts[] =
{
{{-radius, 0.f, -radius}, {0.f, 0.f}},
{{radius, 0.f, -radius}, {0.f, 1.f}},
{{-radius, 0.f, radius}, {1.f, 0.f}},
{{radius, 0.f, radius}, {1.f, 1.f}}
};
m_filter->drawVerts(zeus::CColor::skWhite, verts);
}
void CSimpleShadow::Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr)
{
x48_24_collision = false;
float halfHeight = (aabb.max.z - aabb.min.z) * 0.5f;
zeus::CVector3f pos = xf.origin + zeus::CVector3f(0.f, 0.f, halfHeight);
CRayCastResult res = mgr.RayStaticIntersection(pos, zeus::CVector3f::skDown, x40_maxObjHeight,
CMaterialFilter::MakeExclude({EMaterialTypes::SeeThrough}));
float height = x40_maxObjHeight;
if (res.IsValid())
{
x48_24_collision = true;
height = res.GetT();
}
if (height > 0.1f + halfHeight)
{
TUniqueId cid = kInvalidUniqueId;
rstl::reserved_vector<TUniqueId, 1024> nearList;
CRayCastResult resD = CGameCollision::RayDynamicIntersection(mgr, cid, pos,
zeus::CVector3f::skDown, x40_maxObjHeight,
CMaterialFilter::skPassEverything, nearList);
if (resD.IsValid() && resD.GetT() < height)
{
x48_24_collision = true;
height = resD.GetT();
res = resD;
}
}
if (x48_24_collision)
{
x3c_heightAlpha = 1.f - height / x40_maxObjHeight;
x0_xf = zeus::lookAt(res.GetPlane().normal(), zeus::CVector3f::skZero);
x0_xf.origin = res.GetPlane().normal() * x44_displacement + res.GetPoint();
if (x48_25_alwaysCalculateRadius || !x48_26_radiusCalculated)
{
float xExtent = aabb.max.x - aabb.min.x;
float yExtent = aabb.max.y - aabb.min.y;
x34_radius = std::sqrt(xExtent * xExtent + yExtent * yExtent) * 0.5f;
x48_26_radiusCalculated = true;
}
}
}
}
}

View File

@ -1,16 +1,37 @@
#ifndef __URDE_CSIMPLESHADOW_HPP__
#define __URDE_CSIMPLESHADOW_HPP__
#include "zeus/CAABox.hpp"
#include "Graphics/Shaders/CTexturedQuadFilter.hpp"
namespace urde
{
class CTexture;
class CStateManager;
class CSimpleShadow
{
zeus::CTransform x0_xf;
float x30_scale;
float x34_radius = 1.f;
float x38_userAlpha;
float x3c_heightAlpha = 1.f;
float x40_maxObjHeight;
float x44_displacement;
bool x48_24_collision : 1;
bool x48_25_alwaysCalculateRadius : 1;
bool x48_26_radiusCalculated : 1;
mutable std::experimental::optional<CTexturedQuadFilter> m_filter;
public:
CSimpleShadow() = default;
CSimpleShadow(float, float, float, float);
void Render(const CTexture* tex) const;
CSimpleShadow(float scale, float userAlpha, float maxObjHeight, float displacement);
bool Valid() const { return x48_24_collision; }
zeus::CAABox GetMaxShadowBox(const zeus::CAABox& aabb) const;
zeus::CAABox GetBounds() const;
float GetMaxObjectHeight() const { return x40_maxObjHeight; }
void SetUserAlpha(float a) { x38_userAlpha = a; }
const zeus::CTransform& GetTransform() const { return x0_xf; }
void Render(const TLockedToken<CTexture>& tex) const;
void Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr);
};
}

View File

@ -131,7 +131,7 @@ static const char* ThermalPostGLSL =
"};\n"
"vec4 ThermalPostFunc(vec4 colorIn)\n"
"{\n"
" return vec4(texture(extTex7, vtf.extTcgs[0]).rrr * tmulColor.rgb + addColor.rgb, 1.0);\n"
" return vec4(texture(extTex7, vtf.extTcgs[0]).rrr * tmulColor.rgb + addColor.rgb, tmulColor.a + addColor.a);\n"
"}\n"
"\n";
@ -195,7 +195,7 @@ CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
ext.registerExtensionSlot({}, {ThermalPostGLSL, "ThermalPostFunc"}, 3, ThermalBlockNames,
1, ThermalTextures, hecl::Backend::BlendFactor::One,
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
hecl::Backend::CullMode::Backface, false, false, true);
hecl::Backend::CullMode::Backface, false, false, false, true);
/* Forced alpha shading */
ext.registerExtensionSlot({LightingGLSL, "LightingFunc"}, {MainPostGLSL, "MainPostFunc"},
@ -251,7 +251,7 @@ CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
hecl::Backend::BlendFactor::SrcAlpha,
hecl::Backend::BlendFactor::InvSrcAlpha,
hecl::Backend::ZTest::Equal,
hecl::Backend::CullMode::Backface, false, false, true, true);
hecl::Backend::CullMode::Backface, false, false, true, false, true);
/* World shadow shading (modified lighting) */
ext.registerExtensionSlot({LightingShadowGLSL, "LightingShadowFunc"}, {MainPostGLSL, "MainPostFunc"},

View File

@ -127,7 +127,7 @@ static const char* ThermalPostHLSL =
"};\n"
"static float4 ThermalPostFunc(in VertToFrag vtf, float4 colorIn)\n"
"{\n"
" return float4(extTex7.Sample(samp, vtf.extTcgs[0]).rrr * tmulColor.rgb + addColor.rgb, 1.0);\n"
" return float4(extTex7.Sample(samp, vtf.extTcgs[0]).rrr * tmulColor.rgb + addColor.rgb, tmulColor.a + addColor.a);\n"
"}\n"
"\n";
@ -175,7 +175,7 @@ CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat)
ext.registerExtensionSlot({}, {ThermalPostHLSL, "ThermalPostFunc"}, 0, nullptr,
1, ThermalTextures, hecl::Backend::BlendFactor::One,
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
hecl::Backend::CullMode::Backface, false, false, true);
hecl::Backend::CullMode::Backface, false, false, false, true);
/* Forced alpha shading */
ext.registerExtensionSlot({LightingHLSL, "LightingFunc"}, {MainPostHLSL, "MainPostFunc"},
@ -231,7 +231,7 @@ CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat)
hecl::Backend::BlendFactor::SrcAlpha,
hecl::Backend::BlendFactor::InvSrcAlpha,
hecl::Backend::ZTest::Equal,
hecl::Backend::CullMode::Backface, false, false, true, true);
hecl::Backend::CullMode::Backface, false, false, true, false, true);
/* World shadow shading (modified lighting) */
ext.registerExtensionSlot({LightingShadowHLSL, "LightingShadowFunc"}, {MainPostHLSL, "MainPostFunc"},

View File

@ -129,7 +129,9 @@ static const char* ThermalPostMetal =
"static float4 EXTThermalPostFunc(thread VertToFrag& vtf, constant ThermalUniform& lu,\n"
" sampler samp, sampler clampSamp, texture2d<float> extTex7, float4 colorIn)\n"
"{\n"
" return float4(extTex7.sample(samp, vtf.extTcgs0).rrr * lu.tmulColor.rgb + lu.addColor.rgb, 1.0);\n"
" //return float4(vtf.extTcgs0.xy, 0.0, 1.0);\n"
" return float4(extTex7.sample(samp, vtf.extTcgs0).rrr * lu.tmulColor.rgb + lu.addColor.rgb,\n"
" lu.tmulColor.a + lu.addColor.a);\n"
"}\n"
"\n";
@ -183,7 +185,7 @@ CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat
ext.registerExtensionSlot({}, {ThermalPostMetal, "EXTThermalPostFunc"}, 1, ThermalBlockNames,
1, ThermalTextures, hecl::Backend::BlendFactor::One,
hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original,
hecl::Backend::CullMode::Backface, false, false, true);
hecl::Backend::CullMode::Backface, false, false, false, true);
/* Forced alpha shading */
ext.registerExtensionSlot({LightingMetal, "LightingFunc"}, {MainPostMetal, "MainPostFunc"},
@ -239,7 +241,7 @@ CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat
hecl::Backend::BlendFactor::SrcAlpha,
hecl::Backend::BlendFactor::InvSrcAlpha,
hecl::Backend::ZTest::Equal,
hecl::Backend::CullMode::Backface, false, false, true, true);
hecl::Backend::CullMode::Backface, false, false, true, false, true);
/* World shadow shading (modified lighting) */
ext.registerExtensionSlot({LightingShadowMetal, "EXTLightingShadowFunc"}, {MainPostMetal, "MainPostFunc"},

View File

@ -10,8 +10,8 @@ CTexturedQuadFilter::CTexturedQuadFilter(const boo::ObjToken<boo::ITexture>& tex
m_flipRect = CGraphics::g_BooFactory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan;
}
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const boo::ObjToken<boo::ITexture>& tex, bool gequal)
: m_booTex(tex), m_gequal(gequal)
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const boo::ObjToken<boo::ITexture>& tex, ZTest ztest)
: m_booTex(tex), m_zTest(ztest)
{
m_flipRect = CGraphics::g_BooFactory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan;
tex->setClampMode(boo::TextureClampMode::ClampToEdge);
@ -25,8 +25,8 @@ CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const boo::ObjToken<b
}
CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type,
TLockedToken<CTexture> tex)
: CTexturedQuadFilter(type, (tex ? tex->GetBooTexture() : nullptr))
TLockedToken<CTexture> tex, ZTest ztest)
: CTexturedQuadFilter(type, (tex ? tex->GetBooTexture() : nullptr), ztest)
{
m_flipRect = CGraphics::g_BooFactory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan;
m_tex = tex;

View File

@ -22,6 +22,14 @@ class CTexturedQuadFilter
friend struct CTexturedQuadFilterD3DDataBindingFactory;
friend struct CTexturedQuadFilterAlphaD3DDataBindingFactory;
public:
enum class ZTest
{
None,
LEqual,
GEqual
};
protected:
struct Uniform
{
@ -35,7 +43,7 @@ protected:
boo::ObjToken<boo::IGraphicsBufferD> m_uniBuf;
boo::ObjToken<boo::IShaderDataBinding> m_dataBind;
Uniform m_uniform;
bool m_gequal;
ZTest m_zTest;
bool m_flipRect = false;
CTexturedQuadFilter(const boo::ObjToken<boo::ITexture>& tex);
@ -48,8 +56,8 @@ public:
};
static const zeus::CRectangle DefaultRect;
CTexturedQuadFilter(EFilterType type, TLockedToken<CTexture> tex);
CTexturedQuadFilter(EFilterType type, const boo::ObjToken<boo::ITexture>& tex, bool gequal = false);
CTexturedQuadFilter(EFilterType type, TLockedToken<CTexture> tex, ZTest zTest = ZTest::None);
CTexturedQuadFilter(EFilterType type, const boo::ObjToken<boo::ITexture>& tex, ZTest zTest = ZTest::None);
CTexturedQuadFilter(const CTexturedQuadFilter&) = delete;
CTexturedQuadFilter& operator=(const CTexturedQuadFilter&) = delete;
CTexturedQuadFilter(CTexturedQuadFilter&&) = default;

View File

@ -107,17 +107,27 @@ URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilter)
static boo::ObjToken<boo::IVertexFormat> s_VtxFmt;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaGEqualPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaLEqualPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AddPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_MultPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaFlipPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaGEqualFlipPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaLEqualFlipPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AddFlipPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_MultFlipPipeline;
static boo::ObjToken<boo::IShaderPipeline> SelectPipeline(EFilterType type, bool gequal, bool flip)
static boo::ObjToken<boo::IShaderPipeline> SelectPipeline(EFilterType type,
CTexturedQuadFilter::ZTest zTest, bool flip)
{
if (gequal)
switch (zTest)
{
case CTexturedQuadFilter::ZTest::GEqual:
return flip ? s_AlphaGEqualFlipPipeline : s_AlphaGEqualPipeline;
case CTexturedQuadFilter::ZTest::LEqual:
return flip ? s_AlphaLEqualFlipPipeline : s_AlphaLEqualPipeline;
default:
break;
}
switch (type)
{
case EFilterType::Blend:
@ -166,7 +176,7 @@ struct CTexturedQuadFilterGLDataBindingFactory : TMultiBlendShader<CTexturedQuad
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {filter.m_uniBuf.get()};
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
boo::ObjToken<boo::ITexture> texs[] = {filter.m_booTex.get()};
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_gequal,
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_zTest,
filter.m_booTex->type() == boo::TextureType::Render),
ctx.newVertexFormat(2, VtxVmt), filter.m_vbo.get(), nullptr, nullptr,
1, bufs, stages, nullptr, nullptr, 1, texs, nullptr, nullptr);
@ -184,7 +194,7 @@ struct CTexturedQuadFilterVulkanDataBindingFactory : TMultiBlendShader<CTextured
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {filter.m_uniBuf.get()};
boo::ObjToken<boo::ITexture> texs[] = {filter.m_booTex.get()};
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_gequal,
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_zTest,
filter.m_booTex->type() == boo::TextureType::Render), s_VtxFmt,
filter.m_vbo.get(), nullptr, nullptr, 1, bufs,
nullptr, nullptr, nullptr, 1, texs, nullptr, nullptr);
@ -203,6 +213,9 @@ CTexturedQuadFilter::Initialize(boo::GLDataFactory::Context& ctx)
s_AlphaGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::GEqual, true, true, false, boo::CullMode::None);
s_AlphaLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::LEqual, true, true, false, boo::CullMode::None);
s_AddPipeline = ctx.newShaderPipeline(VSNoFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::One, boo::Primitive::TriStrips,
boo::ZTest::None, false, true, false, boo::CullMode::None);
@ -215,6 +228,9 @@ CTexturedQuadFilter::Initialize(boo::GLDataFactory::Context& ctx)
s_AlphaGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::GEqual, true, true, false, boo::CullMode::None);
s_AlphaLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::LEqual, true, true, false, boo::CullMode::None);
s_AddFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, 1, texNames, 1, uniNames, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::One, boo::Primitive::TriStrips,
boo::ZTest::None, false, true, false, boo::CullMode::None);
@ -229,10 +245,12 @@ void CTexturedQuadFilter::Shutdown<boo::GLDataFactory>()
{
s_AlphaPipeline.reset();
s_AlphaGEqualPipeline.reset();
s_AlphaLEqualPipeline.reset();
s_AddPipeline.reset();
s_MultPipeline.reset();
s_AlphaFlipPipeline.reset();
s_AlphaGEqualFlipPipeline.reset();
s_AlphaLEqualFlipPipeline.reset();
s_AddFlipPipeline.reset();
s_MultFlipPipeline.reset();
}
@ -253,6 +271,9 @@ CTexturedQuadFilter::Initialize(boo::VulkanDataFactory::Context& ctx)
s_AlphaGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::GEqual, true, true, false, boo::CullMode::None);
s_AlphaLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::LEqual, true, true, false, boo::CullMode::None);
s_AddPipeline = ctx.newShaderPipeline(VSNoFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::One, boo::Primitive::TriStrips,
boo::ZTest::None, false, true, false, boo::CullMode::None);
@ -265,6 +286,9 @@ CTexturedQuadFilter::Initialize(boo::VulkanDataFactory::Context& ctx)
s_AlphaGEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::GEqual, true, true, false, boo::CullMode::None);
s_AlphaLEqualFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::LEqual, true, true, false, boo::CullMode::None);
s_AddFlipPipeline = ctx.newShaderPipeline(VSFlip, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::One, boo::Primitive::TriStrips,
boo::ZTest::None, false, true, false, boo::CullMode::None);
@ -280,10 +304,12 @@ void CTexturedQuadFilter::Shutdown<boo::VulkanDataFactory>()
s_VtxFmt.reset();
s_AlphaPipeline.reset();
s_AlphaGEqualPipeline.reset();
s_AlphaLEqualPipeline.reset();
s_AddPipeline.reset();
s_MultPipeline.reset();
s_AlphaFlipPipeline.reset();
s_AlphaGEqualFlipPipeline.reset();
s_AlphaLEqualFlipPipeline.reset();
s_AddFlipPipeline.reset();
s_MultFlipPipeline.reset();
}

View File

@ -108,13 +108,21 @@ URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilter)
static boo::ObjToken<boo::IVertexFormat> s_VtxFmt;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaGEqualPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaLEqualPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AddPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_MultPipeline;
static boo::ObjToken<boo::IShaderPipeline> SelectPipeline(EFilterType type, bool gequal)
static boo::ObjToken<boo::IShaderPipeline> SelectPipeline(EFilterType type, CTexturedQuadFilter::ZTest zTest)
{
if (gequal)
switch (zTest)
{
case CTexturedQuadFilter::ZTest::GEqual:
return s_AlphaGEqualPipeline;
case CTexturedQuadFilter::ZTest::LEqual:
return s_AlphaLEqualPipeline;
default:
break;
}
switch (type)
{
case EFilterType::Blend:
@ -138,7 +146,7 @@ struct CTexturedQuadFilterD3DDataBindingFactory : TMultiBlendShader<CTexturedQua
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {filter.m_uniBuf.get()};
boo::ObjToken<boo::ITexture> texs[] = {filter.m_booTex.get()};
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_gequal), s_VtxFmt,
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_zTest), s_VtxFmt,
filter.m_vbo.get(), nullptr, nullptr, 1, bufs,
nullptr, nullptr, nullptr, 1, texs, nullptr, nullptr);
}
@ -161,6 +169,10 @@ CTexturedQuadFilter::Initialize(boo::ID3DDataFactory::Context& ctx)
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::GEqual, true, true, false, boo::CullMode::None);
s_AlphaLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::LEqual, true, true, false, boo::CullMode::None);
s_AddPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::One, boo::Primitive::TriStrips,
@ -178,6 +190,7 @@ void CTexturedQuadFilter::Shutdown<boo::ID3DDataFactory>()
s_VtxFmt.reset();
s_AlphaPipeline.reset();
s_AlphaGEqualPipeline.reset();
s_AlphaLEqualPipeline.reset();
s_AddPipeline.reset();
s_MultPipeline.reset();
}

View File

@ -115,13 +115,21 @@ URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilter)
static boo::ObjToken<boo::IVertexFormat> s_VtxFmt;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaGEqualPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AlphaLEqualPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_AddPipeline;
static boo::ObjToken<boo::IShaderPipeline> s_MultPipeline;
static boo::ObjToken<boo::IShaderPipeline> SelectPipeline(EFilterType type, bool gequal)
static boo::ObjToken<boo::IShaderPipeline> SelectPipeline(EFilterType type, CTexturedQuadFilter::ZTest zTest)
{
if (gequal)
switch (zTest)
{
case CTexturedQuadFilter::ZTest::GEqual:
return s_AlphaGEqualPipeline;
case CTexturedQuadFilter::ZTest::LEqual:
return s_AlphaLEqualPipeline;
default:
break;
}
switch (type)
{
case EFilterType::Blend:
@ -144,7 +152,7 @@ struct CTexturedQuadFilterMetalDataBindingFactory : TMultiBlendShader<CTexturedQ
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {filter.m_uniBuf.get()};
boo::ObjToken<boo::ITexture> texs[] = {filter.m_booTex.get()};
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_gequal), s_VtxFmt,
return cctx.newShaderDataBinding(SelectPipeline(type, filter.m_zTest), s_VtxFmt,
filter.m_vbo.get(), nullptr, nullptr, 1, bufs,
nullptr, nullptr, nullptr, 1, texs, nullptr, nullptr);
}
@ -161,19 +169,28 @@ CTexturedQuadFilter::Initialize(boo::MetalDataFactory::Context& ctx)
s_VtxFmt = ctx.newVertexFormat(2, VtxVmt);
s_AlphaPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, boo::ZTest::None, false,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::None, false,
true, false, boo::CullMode::None);
s_AlphaGEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips, boo::ZTest::GEqual, true,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::GEqual, true,
true, false, boo::CullMode::None);
s_AlphaLEqualPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
boo::ZTest::LEqual, true,
true, false, boo::CullMode::None);
s_AddPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::SrcAlpha,
boo::BlendFactor::One, boo::Primitive::TriStrips, boo::ZTest::None, false,
boo::BlendFactor::One, boo::Primitive::TriStrips,
boo::ZTest::None, false,
true, false, boo::CullMode::None);
s_MultPipeline = ctx.newShaderPipeline(VSNoFlip, FS, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::Zero,
boo::BlendFactor::SrcColor, boo::Primitive::TriStrips, boo::ZTest::None, false,
boo::BlendFactor::SrcColor, boo::Primitive::TriStrips,
boo::ZTest::None, false,
true, false, boo::CullMode::None);
return new CTexturedQuadFilterMetalDataBindingFactory;
}
@ -184,6 +201,7 @@ void CTexturedQuadFilter::Shutdown<boo::MetalDataFactory>()
s_VtxFmt.reset();
s_AlphaPipeline.reset();
s_AlphaGEqualPipeline.reset();
s_AlphaLEqualPipeline.reset();
s_AddPipeline.reset();
s_MultPipeline.reset();
}

View File

@ -47,7 +47,7 @@ BOO_GLSL_BINDING_HEAD
"{\n"
" float sceneSample = dot(texture(sceneTex, vtf.sceneUv), kRGBToYPrime);\n"
" vec4 colorSample = texture(paletteTex, vec2(sceneSample / 17.0, 0.5));\n"
" colorOut = colorSample * sceneSample;\n"
" colorOut = vec4((colorSample * sceneSample).rgb, 0.0);\n"
"}\n";
URDE_DECL_SPECIALIZE_SHADER(CThermalHotFilter)
@ -100,7 +100,7 @@ TShader<CThermalHotFilter>::IDataBindingFactory* CThermalHotFilter::Initialize(b
const char* uniNames[] = {"ThermalHotUniform"};
s_Pipeline = ctx.newShaderPipeline(VS, FS, 2, texNames, 1, uniNames, boo::BlendFactor::DstAlpha,
boo::BlendFactor::InvDstAlpha, boo::Primitive::TriStrips,
boo::ZTest::None, false, true, false, boo::CullMode::None);
boo::ZTest::None, false, true, true, boo::CullMode::None);
return new CThermalHotFilterGLDataBindingFactory;
}

View File

@ -49,7 +49,7 @@ static const char* FS =
"{\n"
" float sceneSample = dot(sceneTex.Sample(samp, vtf.sceneUv), kRGBToYPrime);\n"
" float4 colorSample = paletteTex.Sample(samp, float2(sceneSample / 17.0, 0.5));\n"
" return colorSample * sceneSample;\n"
" return float4((colorSample * sceneSample).rgb, 0.0);\n"
"}\n";
URDE_DECL_SPECIALIZE_SHADER(CThermalHotFilter)
@ -84,7 +84,7 @@ TShader<CThermalHotFilter>::IDataBindingFactory* CThermalHotFilter::Initialize(b
s_Pipeline = ctx.newShaderPipeline(VS, FS, nullptr, nullptr, nullptr,
s_VtxFmt, boo::BlendFactor::DstAlpha, boo::BlendFactor::InvDstAlpha,
boo::Primitive::TriStrips, boo::ZTest::None,
false, true, false, boo::CullMode::None);
false, true, true, boo::CullMode::None);
return new CThermalHotFilterD3DDataBindingFactory;
}

View File

@ -53,7 +53,7 @@ static const char* FS =
"{\n"
" float sceneSample = dot(sceneTex.sample(samp, vtf.sceneUv), kRGBToYPrime);\n"
" float4 colorSample = paletteTex.sample(samp, float2(sceneSample / 17.0, 0.5));\n"
" return colorSample * sceneSample;\n"
" return float4((colorSample * sceneSample).rgb, 0.0);\n"
"}\n";
URDE_DECL_SPECIALIZE_SHADER(CThermalHotFilter)
@ -87,7 +87,7 @@ TShader<CThermalHotFilter>::IDataBindingFactory* CThermalHotFilter::Initialize(b
s_Pipeline = ctx.newShaderPipeline(VS, FS, nullptr, nullptr, s_VtxFmt,
boo::BlendFactor::DstAlpha, boo::BlendFactor::InvDstAlpha,
boo::Primitive::TriStrips, boo::ZTest::None, false,
true, false, boo::CullMode::None);
true, true, boo::CullMode::None);
return new CThermalHotFilterMetalDataBindingFactory;
}

View File

@ -34,6 +34,7 @@ CHudDecoInterfaceCombat::CHudDecoInterfaceCombat(CGuiFrame& selHud)
x78_basewidget_tickdeco0->SetColor(g_tweakGuiColors->GetTickDecoColor());
x38_basePosition = x7c_basewidget_frame->GetLocalPosition();
x44_baseRotation = x7c_basewidget_frame->GetLocalTransform().buildMatrix3f();
UpdateHudAlpha();
}
void CHudDecoInterfaceCombat::UpdateVisibility()

View File

@ -87,9 +87,9 @@ void COrbitPointMarker::Draw(const CStateManager& mgr) const
const CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr);
CGraphics::SetViewPointMatrix(camXf);
zeus::CFrustum frustum;
zeus::CFrustum frustum = mgr.SetupDrawFrustum(g_Viewport);
frustum.updatePlanes(camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()),
curCam->GetAspectRatio(), 1.f, 100.f));
g_Viewport.x8_width / float(g_Viewport.xc_height), 1.f, 100.f));
g_Renderer->SetClippingPlanes(frustum);
g_Renderer->SetPerspective(curCam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height,
curCam->GetNearClipDistance(), curCam->GetFarClipDistance());

View File

@ -31,7 +31,7 @@ void CTargetingManager::Draw(const CStateManager& mgr, bool hideLockon) const
CGraphics::SetViewPointMatrix(camXf);
zeus::CFrustum frustum;
frustum.updatePlanes(camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()),
curCam->GetAspectRatio(), 1.f, 100.f));
g_Viewport.x8_width / float(g_Viewport.xc_height), 1.f, 100.f));
g_Renderer->SetClippingPlanes(frustum);
g_Renderer->SetPerspective(curCam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height,
curCam->GetNearClipDistance(), curCam->GetFarClipDistance());

View File

@ -2015,7 +2015,7 @@ CFrontEndUI::CFrontEndUI()
m_touchBar = NewFrontEndUITouchBar();
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
//x14_phase = EPhase::ExitFrontEnd;
x14_phase = EPhase::ExitFrontEnd;
}
void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue)

View File

@ -81,7 +81,8 @@ bool CPlayerVisor::DrawScanObjectIndicators(const CStateManager& mgr) const
zeus::CTransform camMtx = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr);
CGraphics::SetViewPointMatrix(camMtx);
zeus::CFrustum frustum;
frustum.updatePlanes(camMtx, zeus::CProjection(zeus::SProjPersp(cam->GetFov(), cam->GetAspectRatio(), 1.f, 100.f)));
frustum.updatePlanes(camMtx, zeus::CProjection(zeus::SProjPersp(cam->GetFov(),
g_Viewport.x8_width / float(g_Viewport.xc_height), 1.f, 100.f)));
g_Renderer->SetClippingPlanes(frustum);
g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height,
cam->GetNearClipDistance(), cam->GetFarClipDistance());
@ -176,18 +177,18 @@ void CPlayerVisor::UpdateScanObjectIndicators(const CStateManager& mgr, float dt
{
tgt.xc_inBox = inBox;
if (inBox)
x550_frameColorImpulseInterp = 1.f;
x550_scanFrameColorImpulseInterp = 1.f;
}
inBoxExists |= inBox;
}
}
if (inBoxExists)
x54c_frameColorInterp = std::min(x54c_frameColorInterp + dt2, 1.f);
x54c_scanFrameColorInterp = std::min(x54c_scanFrameColorInterp + dt2, 1.f);
else
x54c_frameColorInterp = std::max(0.f, x54c_frameColorInterp - dt2);
x54c_scanFrameColorInterp = std::max(0.f, x54c_scanFrameColorInterp - dt2);
x550_frameColorImpulseInterp = std::max(0.f, x550_frameColorImpulseInterp - dt);
x550_scanFrameColorImpulseInterp = std::max(0.f, x550_scanFrameColorImpulseInterp - dt);
dt += FLT_EPSILON;
TAreaId playerArea = mgr.GetPlayer().GetAreaIdAlways();
@ -414,12 +415,12 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, const CTargetingMana
zeus::CColor frameColor = zeus::CColor::lerp(
g_tweakGuiColors->GetScanFrameInactiveColor(),
g_tweakGuiColors->GetScanFrameActiveColor(),
x54c_frameColorInterp);
x54c_scanFrameColorInterp);
frameColor.a = transFactor;
CModelFlags flags(5, 0, 0,
frameColor + g_tweakGuiColors->GetScanFrameImpulseColor() *
zeus::CColor(x550_frameColorImpulseInterp, x550_frameColorImpulseInterp));
zeus::CColor(x550_scanFrameColorImpulseInterp, x550_scanFrameColorImpulseInterp));
flags.m_noCull = true;
zeus::CTransform verticalFlip = zeus::CTransform::Scale(1.f, 1.f, -1.f);

View File

@ -70,8 +70,8 @@ class CPlayerVisor
TLockedToken<CModel> x130_scanIconCritical;
rstl::reserved_vector<SScanTarget, 64> x13c_scanTargets;
TLockedToken<CTexture> x540_xrayPalette;
float x54c_frameColorInterp = 0.f;
float x550_frameColorImpulseInterp = 0.f;
float x54c_scanFrameColorInterp = 0.f;
float x550_scanFrameColorImpulseInterp = 0.f;
int FindEmptyInactiveScanTarget() const;
int FindCachedInactiveScanTarget(TUniqueId uid) const;

View File

@ -320,7 +320,7 @@ void CSamusHud::InitializeDamageLight()
parms, CLight::BuildSpot(zeus::CVector3f::skZero, zeus::CVector3f::skForward,
zeus::CColor::skWhite, g_tweakGui->GetHudDamageLightSpotAngle()));
x3d4_damageLight = light.get();
x3d4_damageLight->SetColor(zeus::CColor::skWhite);
x3d4_damageLight->SetColor(zeus::CColor::skBlack);
zeus::CColor lightColor = g_tweakGuiColors->GetHudFrameColor();
lightColor.r *= lightColor.a;

View File

@ -40,7 +40,7 @@ void CDecalManager::AddToRenderer(const zeus::CFrustum& frustum, const CStateMan
for (s32 idx : m_ActiveIndexList)
{
CDecalManager::SDecal& decal = m_DecalPool[idx];
if (decal.x75_flags & 0x2 || mgr.GetParticleFlags())
if (decal.x75_flags & 0x2 || mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot)
{
const zeus::CVector3f& point = decal.x0_decal->xc_transform.origin;
zeus::CAABox aabb(point, point);

View File

@ -328,22 +328,30 @@ void CGunWeapon::Draw(bool drawSuitArm, const CStateManager& mgr, const zeus::CT
if (x1bc_rainSplashGenerator && x1bc_rainSplashGenerator->IsRaining())
CSkinnedModel::SetPointGeneratorFunc(x1bc_rainSplashGenerator, PointGenerator);
if (mgr.GetParticleFlags() == 0 && x200_beamId != CPlayerState::EBeamId::Ice)
if (mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot && x200_beamId != CPlayerState::EBeamId::Ice)
{
zeus::CColor color1(flags.x4_color.a, flags.x4_color.a);
zeus::CColor color2(0.25f, 0.25f);
/* Hot Draw */
zeus::CColor mulColor(flags.x4_color.a, flags.x4_color.a);
zeus::CColor addColor(0.25f, 0.25f);
if (x218_29_drawHologram)
{
DrawHologram(mgr, xf, flags);
}
else
x10_solidModelData->RenderThermal(xf, color1, color2);
{
CModelFlags useFlags(0, 0, 3, zeus::CColor::skWhite);
x10_solidModelData->RenderThermal(xf, mulColor, addColor, useFlags);
}
if (drawSuitArm && xb0_suitArmModelData)
{
xb0_suitArmModelData->RenderThermal(xf, color1, color2);
CModelFlags useFlags(0, 0, 3, zeus::CColor::skWhite);
xb0_suitArmModelData->RenderThermal(xf, mulColor, addColor, useFlags);
}
}
else
{
/* Cold Draw */
if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::XRay && !x218_29_drawHologram)
{
CModelFlags useFlags = flags;

View File

@ -23,7 +23,7 @@ void CIceBeam::PreRenderGunFx(const CStateManager& mgr, const zeus::CTransform&
void CIceBeam::PostRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf)
{
bool subtractBlend = mgr.GetParticleFlags() == 0;
bool subtractBlend = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot;
if (subtractBlend)
CElementGen::SetSubtractBlend(true);
if (x240_smokeGen)

View File

@ -314,7 +314,8 @@ private:
u32 _dummy = 0;
};
mutable CTexturedQuadFilter m_screenQuad = {EFilterType::Blend, CGraphics::g_SpareTexture.get(), true};
mutable CTexturedQuadFilter m_screenQuad = {EFilterType::Blend, CGraphics::g_SpareTexture.get(),
CTexturedQuadFilter::ZTest::GEqual};
mutable CAABoxShader m_aaboxShader = {true};
void InitBeamData();

View File

@ -9,6 +9,10 @@
#include "Camera/CGameCamera.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "CWorld.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "CTimeProvider.hpp"
#include "Graphics/CSkinnedModel.hpp"
namespace urde
{
@ -33,7 +37,7 @@ CActor::CActor(TUniqueId uid, bool active, std::string_view name, const CEntityI
x90_actorLights = mData.IsNull() ? std::unique_ptr<CActorLights>() : params.x0_lightParms.MakeActorLights();
if (mData.x10_animData || mData.x1c_normalModel)
x64_modelData = std::make_unique<CModelData>(std::move(mData));
xd0_ = params.x64_;
xd0_thermalMag = params.x64_;
xd8_nonLoopingSfxHandles.resize(2);
xe4_27_notInSortedLists = true;
xe4_28_ = true;
@ -41,12 +45,12 @@ CActor::CActor(TUniqueId uid, bool active, std::string_view name, const CEntityI
xe4_31_lightsDirty = true;
xe5_27_useInSortedLists = true;
xe5_28_callTouch = true;
xe5_29_ = params.x58_24_;
xe5_29_globalTimeProvider = params.x58_24_;
xe5_30_ = params.x58_26_;
xe6_27_renderVisorFlags = u8(params.x58_25_thermalHeat ? 2 : 1);
xe6_29_ = true;
xe6_29_prePostParticles = true;
xe6_31_targetableVisorFlags = params.GetVisorParameters().GetMask();
xe7_27_ = true;
xe7_27_enableRender = true;
xe7_29_actorActive = active;
xe7_30_doTargetDistanceTest = true;
xe7_31_targetable = true;
@ -123,19 +127,183 @@ void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMana
CEntity::AcceptScriptMsg(msg, uid, mgr);
}
void CActor::PreRender(CStateManager&, const zeus::CFrustum&)
void CActor::PreRender(CStateManager& mgr, const zeus::CFrustum& planes)
{
if (!x64_modelData || x64_modelData->IsNull())
return;
xe4_30_outOfFrustum = !planes.aabbFrustumTest(x9c_renderBounds);
if (!xe4_30_outOfFrustum)
{
bool lightsDirty = false;
if (xe4_29_actorLightsDirty)
{
xe4_29_actorLightsDirty = false;
lightsDirty = true;
xe5_25_shadowDirty = true;
}
else if (xe7_28_worldLightingDirty)
{
lightsDirty = true;
}
else if (x90_actorLights && x90_actorLights->GetIsDirty())
{
lightsDirty = true;
}
if (xe5_25_shadowDirty && xe5_24_shadowEnabled && x94_simpleShadow)
{
x94_simpleShadow->Calculate(x64_modelData->GetBounds(), x34_transform, mgr);
xe5_25_shadowDirty = false;
}
if (xe4_31_lightsDirty && x90_actorLights)
{
zeus::CAABox bounds = x64_modelData->GetBounds(x34_transform);
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal)
{
x90_actorLights->BuildConstantAmbientLighting();
}
else
{
if (lightsDirty && x4_areaId != kInvalidAreaId)
{
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
if (area->IsPostConstructed())
if (x90_actorLights->BuildAreaLightList(mgr, *area, bounds))
xe7_28_worldLightingDirty = false;
}
x90_actorLights->BuildDynamicLightList(mgr, bounds);
}
}
if (x64_modelData->HasAnimData())
x64_modelData->AnimationData()->PreRender();
}
else
{
if (xe4_29_actorLightsDirty)
{
xe4_29_actorLightsDirty = false;
xe5_25_shadowDirty = true;
}
if (xe5_25_shadowDirty && xe5_24_shadowEnabled && x94_simpleShadow)
{
zeus::CAABox bounds = x64_modelData->GetBounds(x34_transform);
if (planes.aabbFrustumTest(x94_simpleShadow->GetMaxShadowBox(bounds)))
{
x94_simpleShadow->Calculate(x64_modelData->GetBounds(), x34_transform, mgr);
xe5_25_shadowDirty = false;
}
}
}
}
void CActor::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const
void CActor::AddToRenderer(const zeus::CFrustum& planes, const CStateManager& mgr) const
{
if (!x64_modelData || x64_modelData->IsNull())
return;
if (xe6_29_prePostParticles)
x64_modelData->RenderParticles(planes);
if (!xe4_30_outOfFrustum)
{
if (CanRenderUnsorted(mgr))
Render(mgr);
else
EnsureRendered(mgr);
}
if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay &&
mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::Thermal &&
xe5_24_shadowEnabled && x94_simpleShadow->Valid() &&
planes.aabbFrustumTest(x94_simpleShadow->GetBounds()))
g_Renderer->AddDrawable(x94_simpleShadow.get(), x94_simpleShadow->GetTransform().origin,
x94_simpleShadow->GetBounds(), 1, CBooRenderer::EDrawableSorting::SortedCallback);
}
void CActor::Render(const CStateManager&) const
void CActor::DrawTouchBounds() const
{
// Empty
}
void CActor::RenderInternal(const CStateManager& mgr) const
{
CModelData::EWhichModel which = CModelData::GetRenderingModel(mgr);
if (which == CModelData::EWhichModel::ThermalHot)
{
if (x64_modelData->GetSortThermal())
{
float addMag;
float mulMag = 1.f;
if (xd0_thermalMag <= 1.f)
{
mulMag = xd0_thermalMag;
addMag = 0.f;
}
else if (xd0_thermalMag < 2.f)
{
addMag = xd0_thermalMag - 1.f;
}
else
{
addMag = 1.f;
}
zeus::CColor mulColor(mulMag * xb4_drawFlags.x4_color.a, xb4_drawFlags.x4_color.a);
zeus::CColor addColor(addMag, xb4_drawFlags.x4_color.a / 4.f);
x64_modelData->RenderThermal(x34_transform, mulColor, addColor, xb4_drawFlags);
return;
}
else if (mgr.GetThermalColdScale2() > 0.00001f && !xb4_drawFlags.x0_blendMode)
{
zeus::CColor color(zeus::clamp(0.f,
std::min((mgr.GetThermalColdScale2() + mgr.GetThermalColdScale1()) * mgr.GetThermalColdScale2(),
mgr.GetThermalColdScale2()), 1.f), 1.f);
CModelFlags flags(2, xb4_drawFlags.x1_matSetIdx, xb4_drawFlags.x2_flags, color);
x64_modelData->Render(mgr, x34_transform, x90_actorLights.get(), flags);
return;
}
}
x64_modelData->Render(which, x34_transform, x90_actorLights.get(), xb4_drawFlags);
}
void CActor::Render(const CStateManager& mgr) const
{
if (x64_modelData && !x64_modelData->IsNull())
{
bool renderPrePostParticles = xe6_29_prePostParticles && x64_modelData && x64_modelData->HasAnimData();
if (renderPrePostParticles)
x64_modelData->AnimationData()->GetParticleDB().RenderSystemsToBeDrawnFirst();
if (xe7_27_enableRender)
{
if (xe5_31_pointGeneratorParticles)
mgr.SetupParticleHook(*this);
if (xe5_29_globalTimeProvider)
{
RenderInternal(mgr);
}
else
{
float timeSince = CGraphics::GetSecondsMod900() - xbc_time;
float tpTime = timeSince - std::floor(timeSince / 900.f) * 900.f;
CTimeProvider tp(tpTime);
RenderInternal(mgr);
}
if (xe5_31_pointGeneratorParticles)
{
CSkinnedModel::ClearPointGeneratorFunc();
mgr.GetActorModelParticles()->Render(*this);
}
}
if (renderPrePostParticles)
x64_modelData->AnimationData()->GetParticleDB().RenderSystemsToBeDrawnLast();
}
DrawTouchBounds();
}
bool CActor::CanRenderUnsorted(const CStateManager&) const
@ -291,10 +459,10 @@ void CActor::CreateShadow(bool b)
if (b)
{
_CreateShadow();
if (!xe5_24_ && x94_simpleShadow)
xe5_25_ = true;
if (!xe5_24_shadowEnabled && x94_simpleShadow)
xe5_25_shadowDirty = true;
}
xe5_24_ = b;
xe5_24_shadowEnabled = b;
}
void CActor::_CreateShadow()
@ -371,7 +539,7 @@ float CActor::GetPitch() const { return zeus::CQuaternion(x34_transform.buildMat
float CActor::GetYaw() const { return zeus::CQuaternion(x34_transform.buildMatrix3f()).yaw(); }
void CActor::EnsureRendered(const CStateManager& mgr)
void CActor::EnsureRendered(const CStateManager& mgr) const
{
zeus::CAABox aabb = GetSortingBounds(mgr);
EnsureRendered(mgr, aabb.closestPointAlongVector(CGraphics::g_ViewMatrix.origin), aabb);

View File

@ -45,7 +45,7 @@ protected:
TUniqueId xc6_nextDrawNode;
int xc8_drawnToken = -1;
int xcc_addedToken = -1;
float xd0_;
float xd0_thermalMag;
float xd4_maxVol = 1.f;
rstl::reserved_vector<CSfxHandle, 2> xd8_nonLoopingSfxHandles;
union
@ -58,20 +58,20 @@ protected:
bool xe4_29_actorLightsDirty : 1;
bool xe4_30_outOfFrustum : 1;
bool xe4_31_lightsDirty : 1;
bool xe5_24_ : 1;
bool xe5_25_ : 1;
bool xe5_24_shadowEnabled : 1;
bool xe5_25_shadowDirty : 1;
bool xe5_26_muted : 1;
bool xe5_27_useInSortedLists : 1;
bool xe5_28_callTouch : 1;
bool xe5_29_ : 1;
bool xe5_29_globalTimeProvider : 1;
bool xe5_30_ : 1;
bool xe5_31_ : 1;
bool xe5_31_pointGeneratorParticles : 1;
u8 xe6_24_fluidCounter : 3;
u8 xe6_27_renderVisorFlags : 2; // 1: thermal cold, 2: thermal hot
bool xe6_29_ : 1;
bool xe6_29_prePostParticles : 1;
bool xe6_30_enablePitchBend : 1;
u8 xe6_31_targetableVisorFlags : 4;
bool xe7_27_ : 1;
bool xe7_27_enableRender : 1;
bool xe7_28_worldLightingDirty : 1;
bool xe7_29_actorActive : 1;
bool xe7_30_doTargetDistanceTest : 1;
@ -81,6 +81,8 @@ protected:
};
void _CreateShadow();
void UpdateSfxEmitters();
void DrawTouchBounds() const;
void RenderInternal(const CStateManager& mgr) const;
public:
enum class EFluidState
@ -169,7 +171,7 @@ public:
float GetYaw() const;
const CModelData* GetModelData() const { return x64_modelData.get(); }
CModelData* ModelData() { return x64_modelData.get(); }
void EnsureRendered(const CStateManager&);
void EnsureRendered(const CStateManager&) const;
void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CAABox&) const;
void ProcessSoundEvent(u32 sfxId, float weight, u32 flags, float falloff, float maxDist,
float minVol, float maxVol, const zeus::CVector3f& toListener,

View File

@ -16,7 +16,7 @@ CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& par
: x0_id(ent.GetUniqueId()), x4_areaId(ent.GetAreaIdAlways()),
xdc_ashy(parent.x48_ashy), x128_parent(parent)
{
x8_.resize(8);
x8_thermalHotParticles.resize(8);
}
u32 GetNextBestPt(s32 start, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn, CRandom16& rnd)
@ -39,7 +39,7 @@ u32 GetNextBestPt(s32 start, const std::vector<std::pair<zeus::CVector3f, zeus::
}
void CActorModelParticles::CItem::GeneratePoints(const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn)
{
for (std::pair<std::unique_ptr<CElementGen>, u32>& pair: x8_)
for (std::pair<std::unique_ptr<CElementGen>, u32>& pair: x8_thermalHotParticles)
{
if (pair.first)
{
@ -84,8 +84,8 @@ void CActorModelParticles::CItem::GeneratePoints(const std::vector<std::pair<zeu
iceGen->SetOrientation(zeus::CTransform::MakeRotationsBasedOnY(zeus::CUnitVector3f(vn[next].second)));
x8c_.push_back(std::move(iceGen));
xb0_ = (x8c_.size() == 4 ? -1 : next);
x8c_thermalColdParticles.push_back(std::move(iceGen));
xb0_ = (x8c_thermalColdParticles.size() == 4 ? -1 : next);
}
// TODO: Verify behavior
if (xc0_particleElectric && xc0_particleElectric->GetParticleEmission())
@ -195,8 +195,8 @@ CActorModelParticles::CActorModelParticles()
void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr)
{
bool isNotOne = mgr.GetParticleFlags() != 1;
bool isNotZero = mgr.GetParticleFlags() != 0;
bool isNotCold = mgr.GetThermalDrawFlag() != EThermalDrawFlag::Cold;
bool isNotHot = mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot;
for (CItem& item : x0_items)
{
@ -210,38 +210,41 @@ void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr)
continue;
}
if (mgr.GetObjectById(item.x0_id) &&
((isNotOne && item.x12c_24_) || (isNotZero && item.x12c_25_)))
((isNotCold && item.x12c_24_thermalCold) || (isNotHot && item.x12c_25_thermalHot)))
{
item.x12c_24_ = false;
item.x12c_25_ = false;
item.x12c_24_thermalCold = false;
item.x12c_25_thermalHot = false;
continue;
}
if (isNotOne)
if (isNotCold)
{
/* Hot Draw */
for (int i=0 ; i<8 ; ++i)
{
std::unique_ptr<CElementGen>& gen = item.x8_[i].first;
std::unique_ptr<CElementGen>& gen = item.x8_thermalHotParticles[i].first;
if (gen)
g_Renderer->AddParticleGen(*gen);
}
if (mgr.GetParticleFlags() && item.x78_)
if (mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot && item.x78_)
g_Renderer->AddParticleGen(*item.x78_);
if (item.xb8_)
g_Renderer->AddParticleGen(*item.xb8_);
if (item.xc0_particleElectric)
g_Renderer->AddParticleGen(*item.xc0_particleElectric);
}
if (isNotZero)
if (isNotHot)
{
for (std::unique_ptr<CElementGen>& gen : item.x8c_)
/* Cold Draw */
for (std::unique_ptr<CElementGen>& gen : item.x8c_thermalColdParticles)
g_Renderer->AddParticleGen(*gen);
if (item.xe4_)
g_Renderer->AddParticleGen(*item.xe4_);
}
if (isNotOne)
if (isNotCold)
{
item.x12c_24_ = false;
item.x12c_25_ = false;
/* Thermal Reset */
item.x12c_24_thermalCold = false;
item.x12c_25_thermalHot = false;
}
}
}
@ -277,4 +280,9 @@ void CActorModelParticles::StartIce(CActor& actor, CStateManager& mgr)
}
void CActorModelParticles::Render(const CActor& actor) const
{
}
}

View File

@ -26,7 +26,7 @@ public:
friend class CActorModelParticles;
TUniqueId x0_id;
TAreaId x4_areaId;
rstl::reserved_vector<std::pair<std::unique_ptr<CElementGen>, u32>, 8> x8_;
rstl::reserved_vector<std::pair<std::unique_ptr<CElementGen>, u32>, 8> x8_thermalHotParticles;
float x6c_ = 0.f;
bool x70_ = false;
CSfxHandle x74_sfx;
@ -34,7 +34,7 @@ public:
u32 x80_ = 0;
u32 x84_ = -1;
u32 x88_seed1 = 99;
rstl::prereserved_vector<std::unique_ptr<CElementGen>, 4> x8c_;
rstl::prereserved_vector<std::unique_ptr<CElementGen>, 4> x8c_thermalColdParticles;
s32 xb0_ = -1;
u32 xb4_seed2 = 99;
std::unique_ptr<CElementGen> xb8_;
@ -52,8 +52,8 @@ public:
{
struct
{
bool x12c_24_ : 1;
bool x12c_25_ : 1;
bool x12c_24_thermalCold : 1;
bool x12c_25_thermalHot : 1;
};
u16 _dummy = 0;
};
@ -94,6 +94,7 @@ public:
void SetupHook(TUniqueId uid);
std::list<CItem>::const_iterator FindSystem(TUniqueId uid) const;
void StartIce(CActor& actor, CStateManager& mgr);
void Render(const CActor& actor) const;
};
}

View File

@ -271,10 +271,10 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
out.kColors[1] = zeus::CColor(x114_reflectionBlend, 1.f);
if (!m_shader || m_cachedDoubleLightmapBlend != doubleLightmapBlend ||
m_cachedAdditive != (mgr.GetParticleFlags() == 0))
m_cachedAdditive != (mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot))
{
m_cachedDoubleLightmapBlend = doubleLightmapBlend;
m_cachedAdditive = mgr.GetParticleFlags() == 0;
m_cachedAdditive = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot;
m_shader.emplace(x44_fluidType,
x10_texPattern1, x20_texPattern2, x30_texColor, xb0_bumpMap, xc0_envMap, xd0_envBumpMap,
xe0_lightmap, m_cachedDoubleLightmapBlend, m_cachedAdditive, m_maxVertCount);

View File

@ -4877,6 +4877,8 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
switch (x304_orbitState)
{
case EPlayerOrbitState::NoOrbit:
/* Disabled transitions directly from NoOrbit to OrbitObject for better keyboard handling */
#if 0
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitObject, input))
{
SetOrbitTargetId(x33c_orbitNextTargetId, mgr);
@ -4890,11 +4892,14 @@ void CPlayer::UpdateOrbitInput(const CFinalInput& input, CStateManager& mgr)
}
else
{
#endif
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitFar, input))
OrbitPoint(EPlayerOrbitType::Far, mgr);
if (ControlMapper::GetPressInput(ControlMapper::ECommands::OrbitClose, input))
OrbitPoint(EPlayerOrbitType::Close, mgr);
#if 0
}
#endif
break;
case EPlayerOrbitState::Grapple:
if (x310_orbitTargetId == kInvalidUniqueId)

2
hecl

@ -1 +1 @@
Subproject commit e46ab0523f0b46992465f2b541d93f7cb49c4c77
Subproject commit 9df3702d957bbb7351aa5b7df2b34853a29c2bc5

2
jbus

@ -1 +1 @@
Subproject commit c06141af1eb303e7a4f3b7e5d0c424a7df6b12b9
Subproject commit 349263a88c736af830c000a29a2710c46d1ff249