From 87a22b73fa66280a6c144c36e387de1a19423539 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 5 Mar 2017 20:33:51 -1000 Subject: [PATCH] DrawWorld implementation complete --- Runtime/CFluidPlaneManager.hpp | 1 + Runtime/CStateManager.cpp | 129 +++++++++++++++++++++++++-- Runtime/CStateManager.hpp | 4 +- Runtime/Graphics/CBooRenderer.cpp | 93 +++++++++++++++++-- Runtime/Graphics/CBooRenderer.hpp | 14 +-- Runtime/Graphics/CModel.hpp | 1 + Runtime/Graphics/CModelBoo.cpp | 33 +++++++ Runtime/Graphics/IRenderer.hpp | 7 +- Runtime/World/CEnvFxManager.cpp | 5 ++ Runtime/World/CEnvFxManager.hpp | 1 + Runtime/World/CMorphBall.cpp | 26 ++++++ Runtime/World/CMorphBall.hpp | 3 + Runtime/World/CMorphBallShadow.cpp | 50 ++++++----- Runtime/World/CMorphBallShadow.hpp | 10 +-- Runtime/World/CPlayer.cpp | 4 +- Runtime/World/CPlayer.hpp | 9 +- Runtime/World/CProjectedShadow.cpp | 10 ++- Runtime/World/CProjectedShadow.hpp | 6 +- Runtime/World/CWorld.hpp | 1 + Runtime/World/CWorldTransManager.cpp | 2 +- hecl | 2 +- 21 files changed, 350 insertions(+), 61 deletions(-) diff --git a/Runtime/CFluidPlaneManager.hpp b/Runtime/CFluidPlaneManager.hpp index 0d357fb11..b5f87f7fd 100644 --- a/Runtime/CFluidPlaneManager.hpp +++ b/Runtime/CFluidPlaneManager.hpp @@ -15,6 +15,7 @@ class CFluidPlaneManager static CFluidProfile sProfile; public: void StartFrame(bool); + void EndFrame() { x121_ = false; } }; } diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 22e3e4f8d..dd7fdff4b 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -31,6 +31,7 @@ #include "Collision/CMaterialFilter.hpp" #include "World/CScriptDock.hpp" #include "Particle/CDecalManager.hpp" +#include "World/CProjectedShadow.hpp" #include @@ -465,10 +466,18 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const return frustum; } +void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport, + const zeus::CTransform& backupViewMatrix) const +{ + +} + void CStateManager::DrawWorld() const { CTimeProvider timeProvider(xf14_); + SViewport backupViewport = g_Viewport; zeus::CFrustum frustum = SetupViewForDraw(g_Viewport); + zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix; /* Area camera is in (not necessarily player) */ TAreaId visAreaId = GetVisAreaId(); @@ -551,15 +560,9 @@ void CStateManager::DrawWorld() const SetupFogForArea(*areaArr[areaCount-1]); for (TUniqueId id : x86c_stateManagerContainer->xf370_) - { if (const CActor* ent = static_cast(GetObjectById(id))) - { if (!thermal || ent->xe6_27_ & 0x2) - { ent->Render(*this); - } - } - } bool morphingPlayerVisible = false; int thermalActorCount = 0; @@ -611,9 +614,117 @@ void CStateManager::DrawWorld() const ++const_cast(*this).x8dc_objectDrawToken; - // TODO: Finish - x84c_player->GetMorphBall(); + x84c_player->GetMorphBall()->DrawBallShadow(*this); + + if (xf7c_projectedShadow) + xf7c_projectedShadow->Render(*this); + + g_Renderer->EnablePVS(&pvs, area.x4_selfIdx); + g_Renderer->DrawSortedGeometry(area.x4_selfIdx, mask, targetMask); } + + x880_envFxManager->Render(*this); + + if (morphingPlayerVisible) + x84c_player->Render(*this); + + g_Renderer->PostRenderFogs(); + + if (thermal) + { + if (x86c_stateManagerContainer->xf39c_.size()) + { + CGraphics::SetDepthRange(0.015625f, 0.03125f); + for (TUniqueId id : x86c_stateManagerContainer->xf39c_) + if (const CActor* actor = static_cast(GetObjectById(id))) + if (actor->xe6_27_ & 0x2) + actor->Render(*this); + CGraphics::SetDepthRange(0.125f, 1.f); + } + g_Renderer->DoThermalBlendCold(); + + for (TUniqueId id : x86c_stateManagerContainer->xf370_) + if (const CActor* actor = static_cast(GetObjectById(id))) + if (actor->xe6_27_ & 0x4) + actor->Render(*this); + + for (int i=areaCount-1 ; i>=0 ; --i) + { + CGameArea& area = *areaArr[i]; + CPVSVisSet& pvs = pvsArr[i]; + + g_Renderer->EnablePVS(&pvs, area.x4_selfIdx); + g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, 0x20); + g_Renderer->DrawAreaGeometry(area.x4_selfIdx, mask, 0x10); + } + + ++const_cast(*this).x8dc_objectDrawToken; + + for (int i=0 ; iGetAreaIdAlways() != area.x4_selfIdx) + if (actor->GetAreaIdAlways() != kInvalidAreaId || area.x4_selfIdx != visAreaId) + continue; + actor->AddToRenderer(frustum, *this); + } + + if (areaCount - 1 == i) + { + x884_actorModelParticles->AddStragglersToRenderer(*this); + CDecalManager::AddToRenderer(frustum, *this); + if (x84c_player) + x84c_player->AddToRenderer(frustum, *this); + } + + ++const_cast(*this).x8dc_objectDrawToken; + + g_Renderer->EnablePVS(&pvs, area.x4_selfIdx); + g_Renderer->DrawSortedGeometry(area.x4_selfIdx, mask, 0x10); + } + + g_Renderer->PostRenderFogs(); + } + + x87c_fluidPlaneManager->EndFrame(); + + g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::CColor::skBlack); + +#if 0 + if (false) + CacheReflection(); +#endif + + if (x84c_player) + x84c_player->RenderGun(*this, x870_cameraManager->GetGlobalCameraTranslation(*this)); + + if (x86c_stateManagerContainer->xf39c_.size()) + { + CGraphics::SetDepthRange(0.015625f, 0.03125f); + for (TUniqueId id : x86c_stateManagerContainer->xf39c_) + if (const CActor* actor = static_cast(GetObjectById(id))) + if (actor->xe6_27_ & 0x4) + actor->Render(*this); + CGraphics::SetDepthRange(0.125f, 1.f); + } + + if (thermal) + { + g_Renderer->DoThermalBlendHot(); + g_Renderer->SetThermal(false, 0.f, zeus::CColor::skBlack); + const_cast(*this).xf34_particleFlags = 2; + } + + DrawDebugStuff(); + RenderCamerasAndAreaLights(); + ResetViewAfterDraw(backupViewport, backupViewMatrix); + DrawE3DeathEffect(); + DrawAdditionalFilters(); } void CStateManager::SetupFogForArea(const CGameArea& area) const @@ -662,7 +773,7 @@ void CStateManager::PreRender() { x86c_stateManagerContainer->xf370_.clear(); x86c_stateManagerContainer->xf39c_.clear(); - xf7c_ = 0; + xf7c_projectedShadow = nullptr; x850_world->PreRender(); BuildDynamicLightListForWorld(); CGameCamera* cam = static_cast(x870_cameraManager->GetCurrentCamera(*this)); diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 4c61d5420..50ccfacbe 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -44,6 +44,7 @@ class CPlayer; class CWorld; class CTexture; class CWorldLayerState; +class CProjectedShadow; namespace MP1 { @@ -206,7 +207,7 @@ class CStateManager TUniqueId xf76_lastRelay = kInvalidUniqueId; float xf78_hudMessageTime = 0.f; - u32 xf7c_ = 0; + CProjectedShadow* xf7c_projectedShadow = nullptr; u32 xf80_hudMessageFrameCount = 0; ResId xf84_ = -1; ResId xf88_ = -1; @@ -268,6 +269,7 @@ public: void DrawE3DeathEffect() const; void DrawAdditionalFilters() const; zeus::CFrustum SetupViewForDraw(const SViewport& vp) const; + void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const; void DrawWorld() const; void SetupFogForArea(const CGameArea& area) const; bool SetupFogForDraw() const; diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 6022d9ed6..c4eb88122 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -363,10 +363,10 @@ void CBooRenderer::AddStaticGeometry(const std::vector* g } } -void CBooRenderer::EnablePVS(const CPVSVisSet* set, u32 modelCount) +void CBooRenderer::EnablePVS(const CPVSVisSet* set, u32 areaIdx) { xc8_pvs.emplace(*set); - xe0_pvsModelCount = modelCount; + xe0_pvsAreaIdx = areaIdx; } void CBooRenderer::DisablePVS() @@ -381,6 +381,44 @@ void CBooRenderer::RemoveStaticGeometry(const std::vector x1c_areaListItems.erase(search); } +void CBooRenderer::DrawAreaGeometry(int areaIdx, int mask, int targetMask) +{ + x318_30_inAreaDraw = true; + CModelFlags flags; + + for (CAreaListItem& item : x1c_areaListItems) + { + if (areaIdx != -1 || item.x18_areaIdx == areaIdx) + { + CPVSVisSet* pvs = xc8_pvs ? &*xc8_pvs : nullptr; + if (xe0_pvsAreaIdx != item.x18_areaIdx) + pvs = nullptr; + int modelIdx = 0; + for (auto it = item.x10_models.begin() ; it != item.x10_models.end() ; ++it, ++modelIdx) + { + CBooModel* model = *it; + if (pvs) + { + bool visible = pvs->GetVisible(modelIdx) != EPVSVisSetState::EndOfTree; + if ((xc4_pvsMode == EPVSMode::PVS && !visible) || (xc4_pvsMode == EPVSMode::PVSAndMask && visible)) + continue; + } + if ((model->x41_mask & mask) != targetMask) + continue; + if (!x44_frustumPlanes.aabbFrustumTest(model->x20_aabb)) + continue; + + for (const CBooSurface* surf = model->x38_firstUnsortedSurface ; surf ; surf = surf->m_next) + model->DrawSurface(*surf, flags); + for (const CBooSurface* surf = model->x3c_firstSortedSurface ; surf ; surf = surf->m_next) + model->DrawSurface(*surf, flags); + } + } + } + + x318_30_inAreaDraw = false; +} + void CBooRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask) { //SetupRendererStates(true); @@ -398,7 +436,7 @@ void CBooRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask) CPVSVisSet* pvs = nullptr; if (xc8_pvs) pvs = &*xc8_pvs; - if (xe0_pvsModelCount != item.x10_models.size()) + if (xe0_pvsAreaIdx != item.x10_models.size()) pvs = nullptr; u32 idx = 0; @@ -579,6 +617,10 @@ void CBooRenderer::BeginScene() CGraphics::SetViewport(0, 0, g_Viewport.x8_width, g_Viewport.xc_height); CGraphics::SetPerspective(75.f, CGraphics::g_ProjAspect, 1.f, 4096.f); CGraphics::SetModelMatrix(zeus::CTransform::Identity()); + x318_27_currentRGBA6 = x318_26_requestRGBA6; + if (!x318_31_persistRGBA6) + x318_26_requestRGBA6 = false; + //GXSetPixelFmt(x318_27_currentRGBA6); CGraphics::BeginScene(); } @@ -790,7 +832,7 @@ void CBooRenderer::FindOverlappingWorldModels(std::vector& modelBits, const int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector& modelBits, const zeus::CAABox& aabb) const { - CModelFlags flags(0, 0, 3, zeus::CColor{1.f, 1.f, 1.f, alphaVal / 255.f}); + CModelFlags flags; flags.m_extendedShaderIdx = 5; // Do solid color draw u32 curWord = 0; @@ -812,13 +854,13 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector 255) return alphaVal; + flags.color.a = alphaVal / 255.f; const CBooModel& model = *item.x10_models[wordModel + j]; const_cast(model).VerifyCurrentShader(0); for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) if (surf->GetBounds().intersects(aabb)) model.DrawSurface(*surf, flags); alphaVal += 4; - flags.color.a = alphaVal / 255.f; } } } @@ -829,4 +871,45 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector& modelBits, + const zeus::CAABox& aabb, float alpha) const +{ + CModelFlags flags; + flags.color.a = alpha; + flags.m_extendedShaderIdx = 6; // Do shadow draw + + u32 curWord = 0; + for (const CAreaListItem& item : x1c_areaListItems) + { + if (!item.x4_octTree) + continue; + + u32 wordModel = 0; + for (int i=0 ; ix14_bitmapWordCount ; ++i, wordModel += 32) + { + const u32& word = modelBits[i]; + if (!word) + continue; + for (int j=0 ; j<32 ; ++j) + { + if ((1 << j) & word) + { + if (alphaVal > 255) + return; + + flags.color.r = alphaVal / 255.f; + const CBooModel& model = *item.x10_models[wordModel + j]; + const_cast(model).VerifyCurrentShader(0); + for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) + if (surf->GetBounds().intersects(aabb)) + model.DrawSurface(*surf, flags); + alphaVal += 4; + } + } + } + + curWord += item.x4_octTree->x14_bitmapWordCount; + } +} + } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index e2730a6e3..de9d1cd30 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -49,6 +49,7 @@ class CBooRenderer : public IRenderer { friend class CBooModel; friend class CWorldTransManager; + friend class CMorphBallShadow; struct CAreaListItem { @@ -88,7 +89,7 @@ class CBooRenderer : public IRenderer PVSAndMask } xc4_pvsMode = EPVSMode::Mask; std::experimental::optional xc8_pvs; - u32 xe0_pvsModelCount = 0; + u32 xe0_pvsAreaIdx = 0; //boo::ITextureS* xe4_blackTex = nullptr; bool xee_24_ : 1; @@ -128,12 +129,12 @@ class CBooRenderer : public IRenderer { bool x318_24_refectionDirty : 1; bool x318_25_drawWireframe : 1; - bool x318_26_ : 1; - bool x318_27_ : 1; + bool x318_26_requestRGBA6 : 1; + bool x318_27_currentRGBA6 : 1; bool x318_28_disableFog : 1; bool x318_29_thermalVisor : 1; - bool x318_30_ : 1; - bool x318_31_ : 1; + bool x318_30_inAreaDraw : 1; + bool x318_31_persistRGBA6 : 1; }; u16 dummy = 0; }; @@ -157,6 +158,7 @@ public: void EnablePVS(const CPVSVisSet*, u32); void DisablePVS(); void RemoveStaticGeometry(const std::vector*); + void DrawAreaGeometry(int areaIdx, int mask, int targetMask); void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask); void DrawSortedGeometry(int areaIdx, int mask, int targetMask); void DrawStaticGeometry(int areaIdx, int mask, int targetMask); @@ -233,6 +235,8 @@ public: void FindOverlappingWorldModels(std::vector& modelBits, const zeus::CAABox& aabb) const; int DrawOverlappingWorldModelIDs(int alphaVal, const std::vector& modelBits, const zeus::CAABox& aabb) const; + void DrawOverlappingWorldModelShadows(int alphaVal, const std::vector& modelBits, + const zeus::CAABox& aabb, float alpha) const; }; } diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 9c168613e..4689e9f7d 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -30,6 +30,7 @@ struct CModelFlags zeus::CColor color; /* Set into kcolor slot specified by material */ zeus::CColor addColor = zeus::CColor::skClear; zeus::CColor regColors[3]; + zeus::CAABox mbShadowBox; CModelFlags() = default; CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col) diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 7f33e2364..04a7c2897 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -506,10 +506,43 @@ void CBooModel::UVAnimationBuffer::PadOutBuffer(u8*& bufStart, u8*& bufOut) bufOut = bufStart + ROUND_UP_256(bufOut - bufStart); } +static const zeus::CMatrix4f MBShadowPost0(1.f, 0.f, 0.f, 0.f, + 0.f, -1.f, 0.f, 1.f, + 0.f, 0.f, 0.f, 1.f, + 0.f, 0.f, 0.f, 1.f); + +static const zeus::CMatrix4f MBShadowPost1(0.f, 0.f, 0.f, 1.f, + 0.f, 0.f, 1.f, -0.0625f, + 0.f, 0.f, 0.f, 1.f, + 0.f, 0.f, 0.f, 1.f); + void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags) { u8* start = bufOut; + /* Special matrices for MorphBall shadow rendering */ + if (flags.m_extendedShaderIdx == 6) + { + zeus::CMatrix4f texMtx = + (zeus::CTransform::Scale(1.f / (flags.mbShadowBox.max.x - flags.mbShadowBox.min.x), + 1.f / (flags.mbShadowBox.max.y - flags.mbShadowBox.min.y), + 1.f / (flags.mbShadowBox.max.z - flags.mbShadowBox.min.z)) * + zeus::CTransform::Translate(-flags.mbShadowBox.min.x, + -flags.mbShadowBox.min.y, + -flags.mbShadowBox.min.z) * CGraphics::g_GXModelView).toMatrix4f(); + for (const MaterialSet::Material& mat : matSet->materials) + { + std::array* mtxs = reinterpret_cast*>(bufOut); + mtxs[0][0] = texMtx; + mtxs[0][1] = MBShadowPost0; + mtxs[1][0] = texMtx; + mtxs[1][1] = MBShadowPost1; + bufOut += sizeof(zeus::CMatrix4f) * 2 * 8; + PadOutBuffer(start, bufOut); + } + return; + } + /* Special Mode0 matrix for exclusive Thermal Visor use */ std::experimental::optional> thermalMtxOut; if (flags.m_extendedShaderIdx == 2) diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index 77340ff02..cbfe527d7 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -47,9 +47,10 @@ public: virtual void EnablePVS(const CPVSVisSet*, u32)=0; virtual void DisablePVS()=0; virtual void RemoveStaticGeometry(const std::vector*)=0; - virtual void DrawUnsortedGeometry(int, int, int)=0; - virtual void DrawSortedGeometry(int, int, int)=0; - virtual void DrawStaticGeometry(int, int, int)=0; + virtual void DrawAreaGeometry(int areaIdx, int mask, int targetMask)=0; + virtual void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask)=0; + virtual void DrawSortedGeometry(int areaIdx, int mask, int targetMask)=0; + virtual void DrawStaticGeometry(int areaIdx, int mask, int targetMask)=0; virtual void PostRenderFogs()=0; virtual void AddParticleGen(const CParticleGen&)=0; virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0; diff --git a/Runtime/World/CEnvFxManager.cpp b/Runtime/World/CEnvFxManager.cpp index 48a5c3f56..74b6ce7e7 100644 --- a/Runtime/World/CEnvFxManager.cpp +++ b/Runtime/World/CEnvFxManager.cpp @@ -9,6 +9,11 @@ CEnvFxManager::CEnvFxManager() } +void CEnvFxManager::Render(const CStateManager& mgr) +{ + +} + void CEnvFxManager::AsyncLoadResources(CStateManager& mgr) { } diff --git a/Runtime/World/CEnvFxManager.hpp b/Runtime/World/CEnvFxManager.hpp index 7f782d54f..db3ca9dae 100644 --- a/Runtime/World/CEnvFxManager.hpp +++ b/Runtime/World/CEnvFxManager.hpp @@ -43,6 +43,7 @@ public: void AsyncLoadResources(CStateManager& mgr); void Update(float, float, EEnvFxType, const CStateManager&); + void Render(const CStateManager& mgr); void SetFxDensity(s32, float); void MoveWrapCells(s32, s32); void GetParticleBoundsToWorldScale() const; diff --git a/Runtime/World/CMorphBall.cpp b/Runtime/World/CMorphBall.cpp index b53e769e9..94f422f85 100644 --- a/Runtime/World/CMorphBall.cpp +++ b/Runtime/World/CMorphBall.cpp @@ -1,4 +1,6 @@ #include "CMorphBall.hpp" +#include "CPlayer.hpp" +#include "CMorphBallShadow.hpp" namespace urde { @@ -8,4 +10,28 @@ CMorphBall::CMorphBall(CPlayer& player, float) { } +void CMorphBall::DrawBallShadow(const CStateManager& mgr) +{ + if (!x1e50_shadow) + return; + + float alpha = 1.f; + switch (x0_player.x2f8_morphTransState) + { + case CPlayer::EPlayerMorphBallState::Unmorphed: + return; + case CPlayer::EPlayerMorphBallState::Unmorphing: + alpha = 0.f; + if (x0_player.x578_morphDuration != 0.f) + alpha = zeus::clamp(0.f, x0_player.x574_morphTime / x0_player.x578_morphDuration, 1.f); + alpha = 1.f - alpha; + case CPlayer::EPlayerMorphBallState::Morphing: + alpha = 0.f; + if (x0_player.x578_morphDuration != 0.f) + alpha = zeus::clamp(0.f, x0_player.x574_morphTime / x0_player.x578_morphDuration, 1.f); + default: break; + } + x1e50_shadow->Render(mgr, alpha); +} + } diff --git a/Runtime/World/CMorphBall.hpp b/Runtime/World/CMorphBall.hpp index 4300ac6c8..18751b2a3 100644 --- a/Runtime/World/CMorphBall.hpp +++ b/Runtime/World/CMorphBall.hpp @@ -15,6 +15,7 @@ class CDamageInfo; class CFinalInput; class CScriptWater; class CStateManager; +class CMorphBallShadow; class CMorphBall { @@ -31,6 +32,7 @@ public: private: CPlayer& x0_player; float x1DE8_boostTime = 0.f; + CMorphBallShadow* x1e50_shadow = nullptr; public: CMorphBall(CPlayer& player, float); @@ -129,6 +131,7 @@ public: void GetBombJumpState() const {} void LoadAnimationTokens(const std::string&) {} void TakeDamage(float) {} + void DrawBallShadow(const CStateManager& mgr); }; } diff --git a/Runtime/World/CMorphBallShadow.cpp b/Runtime/World/CMorphBallShadow.cpp index 5bf10262a..a6f500170 100644 --- a/Runtime/World/CMorphBallShadow.cpp +++ b/Runtime/World/CMorphBallShadow.cpp @@ -9,22 +9,10 @@ namespace urde { -static union -{ - struct - { - bool x_24_ : 1; - bool x_25_ : 1; - bool x_26_ : 1; - bool x_27_ : 1; - }; - u16 _dummy = 0; -} s_flags; - -void CMorphBallShadow::GatherAreas(CStateManager& mgr) +void CMorphBallShadow::GatherAreas(const CStateManager& mgr) { x18_areas.clear(); - for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive); + for (const CGameArea* area = mgr.GetWorld()->GetChainHead(EChain::Alive); area != CWorld::GetAliveAreasEnd(); area = area->GetNext()) { @@ -36,15 +24,15 @@ void CMorphBallShadow::GatherAreas(CStateManager& mgr) } } -void CMorphBallShadow::RenderIdBuffer(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player) +void CMorphBallShadow::RenderIdBuffer(const zeus::CAABox& aabb, const CStateManager& mgr, CPlayer& player) { - xb8_ = aabb; + xb8_shadowVolume = aabb; x0_actors.clear(); x18_areas.clear(); x30_worldModelBits.clear(); - s_flags.x_26_ = true; + g_Renderer->x318_26_requestRGBA6 = true; - if (!s_flags.x_27_) + if (!g_Renderer->x318_27_currentRGBA6) { xd0_hasIds = false; return; @@ -113,10 +101,10 @@ void CMorphBallShadow::RenderIdBuffer(const zeus::CAABox& aabb, CStateManager& m xd0_hasIds = alphaVal != 4; } -bool CMorphBallShadow::AreasValid(CStateManager& mgr) const +bool CMorphBallShadow::AreasValid(const CStateManager& mgr) const { auto it = x18_areas.begin(); - for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive); + for (const CGameArea* area = mgr.GetWorld()->GetChainHead(EChain::Alive); area != CWorld::GetAliveAreasEnd(); area = area->GetNext()) { @@ -134,11 +122,31 @@ bool CMorphBallShadow::AreasValid(CStateManager& mgr) const return true; } -void CMorphBallShadow::Render(CStateManager& mgr, float alpha) +void CMorphBallShadow::Render(const CStateManager& mgr, float alpha) { if (!xd0_hasIds || !AreasValid(mgr)) return; + CModelFlags flags; + flags.color.a = alpha; + flags.m_extendedShaderIdx = 6; + + int alphaVal = 4; + for (const CActor* actor : x0_actors) + { + const CModelData* modelData = actor->GetModelData(); + zeus::CTransform modelXf = actor->GetTransform() * zeus::CTransform::Scale(modelData->GetScale()); + CGraphics::SetModelMatrix(modelXf); + + flags.color.r = alphaVal / 255.f; + const CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); + const_cast(model).VerifyCurrentShader(flags.m_matSetIdx); + model.DrawNormal(flags, nullptr, nullptr); + alphaVal += 4; + } + + CGraphics::SetModelMatrix(zeus::CTransform::Identity()); + g_Renderer->DrawOverlappingWorldModelShadows(alphaVal, x30_worldModelBits, xb8_shadowVolume, alpha); } } diff --git a/Runtime/World/CMorphBallShadow.hpp b/Runtime/World/CMorphBallShadow.hpp index 45922efa4..b81ce3776 100644 --- a/Runtime/World/CMorphBallShadow.hpp +++ b/Runtime/World/CMorphBallShadow.hpp @@ -21,13 +21,13 @@ class CMorphBallShadow //TToken xa8_ballFade; //int xb0_idW; //int xb4_idH; - zeus::CAABox xb8_; + zeus::CAABox xb8_shadowVolume; bool xd0_hasIds = false; - void GatherAreas(CStateManager& mgr); - bool AreasValid(CStateManager& mgr) const; + void GatherAreas(const CStateManager& mgr); + bool AreasValid(const CStateManager& mgr) const; public: - void RenderIdBuffer(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player); - void Render(CStateManager& mgr, float alpha); + void RenderIdBuffer(const zeus::CAABox& aabb, const CStateManager& mgr, CPlayer& player); + void Render(const CStateManager& mgr, float alpha); }; } diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index d59f13520..c65ab7bd8 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -99,9 +99,9 @@ bool CPlayer::GetExplorationMode() const { return false; } bool CPlayer::GetCombatMode() const { return false; } -void CPlayer::RenderGun(CStateManager& mgr, const zeus::CVector3f&) const {} +void CPlayer::RenderGun(const CStateManager& mgr, const zeus::CVector3f&) const {} -void CPlayer::Render(CStateManager& mgr) const {} +void CPlayer::Render(const CStateManager& mgr) const {} void CPlayer::RenderReflectedPlayer(CStateManager& mgr) const {} diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index 5fe7c9824..06aa15732 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -26,6 +26,7 @@ class CPlayer : public CPhysicsActor friend class CStateManager; friend class CFirstPersonCamera; friend class CPlayerCameraBob; + friend class CMorphBall; public: enum class EPlayerScanState @@ -173,8 +174,8 @@ private: float x560_ = 0.f; zeus::CVector3f x564_; float x570_ = 0.f; - float x574_ = 0.f; - float x578_ = 0.f; + float x574_morphTime = 0.f; + float x578_morphDuration = 0.f; u32 x57c_ = 0; u32 x580_ = 0; float x588_alpha = 1.f; @@ -314,8 +315,8 @@ public: void SetSpawnedMorphBallState(EPlayerMorphBallState, CStateManager&); bool GetExplorationMode() const; bool GetCombatMode() const; - void RenderGun(CStateManager& mgr, const zeus::CVector3f&) const; - void Render(CStateManager& mgr) const; + void RenderGun(const CStateManager& mgr, const zeus::CVector3f&) const; + void Render(const CStateManager& mgr) const; void RenderReflectedPlayer(CStateManager& mgr) const; void PreRender(CStateManager& mgr, const zeus::CFrustum&); void CalculateRenderBounds(); diff --git a/Runtime/World/CProjectedShadow.cpp b/Runtime/World/CProjectedShadow.cpp index ca5bf4935..3771a84ce 100644 --- a/Runtime/World/CProjectedShadow.cpp +++ b/Runtime/World/CProjectedShadow.cpp @@ -14,8 +14,14 @@ zeus::CAABox CProjectedShadow::CalculateRenderBounds() return {}; } -void CProjectedShadow::Render(CStateManager&, const CModelData&, const zeus::CTransform&, s32, - const zeus::CVector3f&, float, float) +void CProjectedShadow::Render(const CStateManager& mgr) +{ + +} + +void CProjectedShadow::RenderShadowBuffer(const CStateManager&, const CModelData&, + const zeus::CTransform&, s32, + const zeus::CVector3f&, float, float) { } } diff --git a/Runtime/World/CProjectedShadow.hpp b/Runtime/World/CProjectedShadow.hpp index 8ff282882..cdbec191e 100644 --- a/Runtime/World/CProjectedShadow.hpp +++ b/Runtime/World/CProjectedShadow.hpp @@ -25,8 +25,10 @@ public: CProjectedShadow(u32, u32, bool); zeus::CAABox CalculateRenderBounds(); - void Render(CStateManager&, const CModelData&, const zeus::CTransform&, s32, const zeus::CVector3f&, float, - float); + void Render(const CStateManager& mgr); + void RenderShadowBuffer(const CStateManager&, const CModelData&, + const zeus::CTransform&, s32, + const zeus::CVector3f&, float, float); }; } #endif // __URDE_CPROJECTEDSHADOW_HPP__ diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index 21c983790..555c27877 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -156,6 +156,7 @@ public: void MoveAreaToChain3(TAreaId aid); bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId); CGameArea* GetChainHead(EChain chain) { return x4c_chainHeads[int(chain)]; } + const CGameArea* GetChainHead(EChain chain) const { return x4c_chainHeads[int(chain)]; } bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr); void TravelToArea(TAreaId aid, CStateManager& mgr, bool); void SetPauseState(bool paused); diff --git a/Runtime/World/CWorldTransManager.cpp b/Runtime/World/CWorldTransManager.cpp index 9387bd81f..7736917be 100644 --- a/Runtime/World/CWorldTransManager.cpp +++ b/Runtime/World/CWorldTransManager.cpp @@ -268,7 +268,7 @@ void CWorldTransManager::DrawEnabled() wsAspect, CCameraManager::NearPlane(), CCameraManager::FarPlane()); - g_Renderer->x318_26_ = true; + g_Renderer->x318_26_requestRGBA6 = true; if (x0_curTime <= x4_modelData->x1d0_dissolveStartTime) DrawFirstPass(); diff --git a/hecl b/hecl index d45a50ed5..406cff486 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit d45a50ed51093547a18203a9844dcb90ea3ca2ea +Subproject commit 406cff486a82467877dd99fbe01beefd5f0f27a6