From 5c884fec0c95745f7f88191cec67ec2130fcd910 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 2 Mar 2017 21:18:12 -1000 Subject: [PATCH] Work on CStateManager rendering functions --- Runtime/CFluidPlaneManager.cpp | 19 +++ Runtime/CFluidPlaneManager.hpp | 9 ++ Runtime/CObjectList.hpp | 1 + Runtime/CStateManager.cpp | 131 +++++++++++++++++- Runtime/CStateManager.hpp | 14 +- Runtime/Camera/CCameraFilter.cpp | 4 +- Runtime/Camera/CCameraManager.cpp | 2 +- Runtime/Camera/CGameCamera.cpp | 10 -- Runtime/Camera/CGameCamera.hpp | 10 +- Runtime/Graphics/CBooRenderer.cpp | 48 +++++-- Runtime/Graphics/CBooRenderer.hpp | 13 +- Runtime/Graphics/CGraphics.cpp | 26 ++-- Runtime/Graphics/CGraphics.hpp | 4 +- Runtime/Graphics/CModel.hpp | 17 ++- Runtime/Graphics/CModelBoo.cpp | 35 ++++- Runtime/Graphics/IRenderer.hpp | 3 + .../Graphics/Shaders/CCameraBlurFilter.cpp | 12 +- .../Graphics/Shaders/CColoredQuadFilter.cpp | 22 +-- .../Graphics/Shaders/CTexturedQuadFilter.cpp | 8 +- Runtime/GuiSys/CGuiSys.cpp | 2 +- Runtime/GuiSys/CSplashScreen.cpp | 2 +- Runtime/MP1/CFrontEndUI.cpp | 2 +- Runtime/World/CActor.hpp | 1 + Runtime/World/CGameArea.cpp | 6 + Runtime/World/CGameArea.hpp | 2 + Runtime/World/CWorld.cpp | 8 ++ Runtime/World/CWorld.hpp | 2 + Runtime/World/CWorldTransManager.cpp | 6 +- 28 files changed, 326 insertions(+), 93 deletions(-) diff --git a/Runtime/CFluidPlaneManager.cpp b/Runtime/CFluidPlaneManager.cpp index e69de29bb..436bf277f 100644 --- a/Runtime/CFluidPlaneManager.cpp +++ b/Runtime/CFluidPlaneManager.cpp @@ -0,0 +1,19 @@ +#include "CFluidPlaneManager.hpp" + +namespace urde +{ + +CFluidPlaneManager::CFluidProfile CFluidPlaneManager::sProfile = {}; + +void CFluidPlaneManager::CFluidProfile::Clear() +{ + +} + +void CFluidPlaneManager::StartFrame(bool b) +{ + x121_ = b; + sProfile.Clear(); +} + +} diff --git a/Runtime/CFluidPlaneManager.hpp b/Runtime/CFluidPlaneManager.hpp index 23f4a506e..0d357fb11 100644 --- a/Runtime/CFluidPlaneManager.hpp +++ b/Runtime/CFluidPlaneManager.hpp @@ -6,6 +6,15 @@ namespace urde class CFluidPlaneManager { + bool x121_; + class CFluidProfile + { + public: + void Clear(); + }; + static CFluidProfile sProfile; +public: + void StartFrame(bool); }; } diff --git a/Runtime/CObjectList.hpp b/Runtime/CObjectList.hpp index 132ba3b6c..3a5747f7f 100644 --- a/Runtime/CObjectList.hpp +++ b/Runtime/CObjectList.hpp @@ -61,6 +61,7 @@ public: TUniqueId GetFirstObjectIndex() const { return x2008_firstId; } TUniqueId GetNextObjectIndex(TUniqueId prev) const { return x0_list[prev & 0x3ff].next; } virtual bool IsQualified(const CEntity&); + u16 size() const { return x200a_count; } }; } diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index ef4ea40e9..754a43d66 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -2,6 +2,7 @@ #include "Camera/CCameraShakeData.hpp" #include "Camera/CGameCamera.hpp" #include "Graphics/CBooRenderer.hpp" +#include "World/CGameLight.hpp" #include "CSortedLists.hpp" #include "Weapon/CWeaponMgr.hpp" #include "CFluidPlaneManager.hpp" @@ -25,6 +26,10 @@ #include "CMemoryCardSys.hpp" #include "TCastTo.hpp" #include "World/CScriptSpecialFunction.hpp" +#include "CTimeProvider.hpp" +#include "Camera/CBallCamera.hpp" +#include "Collision/CMaterialFilter.hpp" +#include "World/CScriptDock.hpp" #include @@ -288,7 +293,27 @@ bool CStateManager::SpecialSkipCinematic() return true; } -void CStateManager::GetVisAreaId() const {} +TAreaId CStateManager::GetVisAreaId() const +{ + const CGameCamera* cam = static_cast(x870_cameraManager->GetCurrentCamera(*this)); + const CBallCamera* ballCam = x870_cameraManager->GetBallCamera(); + TAreaId curArea = x850_world->x68_curAreaId; + if (cam != ballCam) + return curArea; + + const zeus::CVector3f& camTranslation = ballCam->GetTranslation(); + zeus::CAABox camAABB(camTranslation, camTranslation); + camAABB.accumulateBounds(x84c_player->GetTranslation()); + rstl::reserved_vector nearList; + BuildNearList(nearList, camAABB, CMaterialFilter(EMaterialTypes::AIBlock, CMaterialList(), + CMaterialFilter::EFilterType::One), nullptr); + for (TUniqueId id : nearList) + if (TCastToConstPtr dock = GetObjectById(id)) + if (dock->GetDestinationAreaId() == curArea && dock->HasPointCrossedDock(*this, camTranslation)) + return dock->GetCurrentConnectedAreaId(*this); + + return curArea; +} void CStateManager::GetWeaponIdCount(TUniqueId, EWeaponType) {} @@ -351,7 +376,29 @@ bool CStateManager::CanCreateProjectile(TUniqueId, EWeaponType, int) const { ret const CGameLightList* CStateManager::GetDynamicLightList() const { return nullptr; } -void CStateManager::BuildDynamicLightListForWorld(std::vector& listOut) const {} +void CStateManager::BuildDynamicLightListForWorld() +{ + if (x8b8_playerState->GetActiveVisor(*this) == CPlayerState::EPlayerVisor::Thermal) + { + x8e0_dynamicLights.clear(); + return; + } + + if (x82c_lightObjs->size() == 0) + return; + + x8e0_dynamicLights.clear(); + for (CEntity* ent : *x82c_lightObjs) + { + CGameLight& light = static_cast(*ent); + if (light.GetActive()) + { + CLight l = light.GetLight(); + if (l.GetIntensity() > FLT_EPSILON && l.GetRadius() > FLT_EPSILON) + x8e0_dynamicLights.push_back(l); + } + } +} void CStateManager::DrawDebugStuff() const {} @@ -361,11 +408,87 @@ void CStateManager::DrawE3DeathEffect() const {} void CStateManager::DrawAdditionalFilters() const {} -void CStateManager::DrawWorld() const {} +zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const +{ + const CGameCamera* cam = static_cast(x870_cameraManager->GetCurrentCamera(*this)); + zeus::CTransform camXf = x870_cameraManager->GetCurrentCameraTransform(*this); + g_Renderer->SetWorldViewpoint(camXf); + CBooModel::SetNewPlayerPositionAndTime(x84c_player->GetTranslation()); + 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); + CGraphics::SetDepthRange(0.125f, 1.f); + 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; + g_Renderer->SetPerspective(zeus::radToDeg(fov), width, height, + cam->GetNearClipDistance(), cam->GetFarClipDistance()); + zeus::CFrustum frustum; + zeus::CProjection proj; + proj.setPersp(zeus::SProjPersp{fov, width / height, cam->GetNearClipDistance(), cam->GetFarClipDistance()}); + frustum.updatePlanes(camXf, proj); + g_Renderer->SetClippingPlanes(frustum); + //g_Renderer->PrimColor(zeus::CColor::skWhite); + CGraphics::SetModelMatrix(zeus::CTransform::Identity()); + x87c_fluidPlaneManager->StartFrame(false); + g_Renderer->SetDebugOption(IRenderer::EDebugOption::One, 1); + return frustum; +} + +void CStateManager::DrawWorld() const +{ + CTimeProvider timeProvider(xf14_); + zeus::CFrustum frustum = SetupViewForDraw(g_Viewport); + + GetVisAreaId(); +} void CStateManager::SetupFogForArea(const CGameArea& area) const {} -void CStateManager::PreRender() {} +void CStateManager::PreRender() +{ + if (xf94_24_) + { + x86c_stateManagerContainer->xf370_.clear(); + x86c_stateManagerContainer->xf39c_.clear(); + xf7c_ = 0; + x850_world->PreRender(); + BuildDynamicLightListForWorld(); + CGameCamera* cam = static_cast(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 (CGameArea* area = x850_world->x4c_chainHeads[3]; + area != CWorld::AliveAreasEnd(); + area = area->x130_next) + { + CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded; + if (area->IsPostConstructed()) + occState = area->GetOcclusionState(); + if (occState == CGameArea::EOcclusionState::Occluded) + { + for (CEntity* ent : *area->GetPostConstructed()->x10c0_areaObjs) + { + if (TCastToPtr act = ent) + { + if (act->GetE7_29()) + { + act->CalculateRenderBounds(); + act->PreRender(*this, frustum); + } + } + } + } + } + + CacheReflection(); + g_Renderer->PrepareDynamicLights(x8e0_dynamicLights); + } +} bool CStateManager::GetVisSetForArea(TAreaId a, TAreaId b, CPVSVisSet& setOut) const { diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index f9e827200..53dcb4788 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -107,8 +107,8 @@ class CStateManager CActorModelParticles xf168_actorModelParticles; CRumbleManager xf250_rumbleManager; u32 xf344_ = 0; - u32 xf370_ = 0; - u32 xf39c_ = 0; + rstl::reserved_vector xf370_; + rstl::reserved_vector xf39c_; }; std::unique_ptr x86c_stateManagerContainer; CCameraManager* x870_cameraManager = nullptr; @@ -134,7 +134,7 @@ class CStateManager //u32 x8d4_updateFrameIdx = 0; //u32 x8d8_drawFrameIdx = 0; - std::vector x8dc_dynamicLights; + std::vector x8e0_dynamicLights; TLockedToken x8f0_shadowTex; /* DefaultShadow in MiscData */ CRandom16 x8fc_random; @@ -191,8 +191,7 @@ class CStateManager u32 xf20_ = 0; float xf24_thermColdScale1 = 0.f; float xf28_thermColdScale2 = 0.f; - float xf2c_ = 1.f; - float xf30_ = 1.f; + zeus::CVector2f xf2c_viewportScale = {1.f, 1.f}; u32 xf34_ = 2; TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId; std::list xf3c_; @@ -243,7 +242,7 @@ public: void AddDrawableActorPlane(const CActor& actor, const zeus::CPlane&, const zeus::CAABox& aabb) const; void AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const; bool SpecialSkipCinematic(); - void GetVisAreaId() const; + TAreaId GetVisAreaId() const; void GetWeaponIdCount(TUniqueId, EWeaponType); void RemoveWeaponId(TUniqueId, EWeaponType); void AddWeaponId(TUniqueId, EWeaponType); @@ -261,11 +260,12 @@ public: void CacheReflection(); bool CanCreateProjectile(TUniqueId, EWeaponType, int) const; const CGameLightList* GetDynamicLightList() const; - void BuildDynamicLightListForWorld(std::vector& listOut) const; + void BuildDynamicLightListForWorld(); void DrawDebugStuff() const; void RenderCamerasAndAreaLights() const; void DrawE3DeathEffect() const; void DrawAdditionalFilters() const; + zeus::CFrustum SetupViewForDraw(const SViewport& vp) const; void DrawWorld() const; void SetupFogForArea(const CGameArea& area) const; void PreRender(); diff --git a/Runtime/Camera/CCameraFilter.cpp b/Runtime/Camera/CCameraFilter.cpp index b4a562115..cf5c91e4b 100644 --- a/Runtime/Camera/CCameraFilter.cpp +++ b/Runtime/Camera/CCameraFilter.cpp @@ -37,8 +37,8 @@ void CCameraBlurPass::Draw() return; SClipScreenRect rect = {}; - rect.xc_width = CGraphics::g_ViewportResolution.x; - rect.x10_height = CGraphics::g_ViewportResolution.y; + rect.xc_width = g_Viewport.x8_width; + rect.x10_height = g_Viewport.xc_height; CGraphics::ResolveSpareTexture(rect); if (x10_curType == EBlurType::Xray) diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index 84b773f73..908adab18 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -28,7 +28,7 @@ CCameraManager::CCameraManager(TUniqueId curCameraId) : x0_curCameraId(curCamera { CSfxManager::AddListener(CSfxManager::ESfxChannels::Game, zeus::CVector3f::skZero, zeus::CVector3f::skZero, {1.f, 0.f, 0.f}, {0.f, 0.f, 1.f}, 50.f, 50.f, 1000.f, 1, 0x7f); - sAspect = float(gViewport.x8_width / gViewport.xc_height); + sAspect = float(g_Viewport.x8_width / g_Viewport.xc_height); sFirstPersonFOV = g_tweakGame->GetFirstPersonFOV(); } diff --git a/Runtime/Camera/CGameCamera.cpp b/Runtime/Camera/CGameCamera.cpp index 9017f0e35..e1dfca69d 100644 --- a/Runtime/Camera/CGameCamera.cpp +++ b/Runtime/Camera/CGameCamera.cpp @@ -101,16 +101,6 @@ zeus::CTransform CGameCamera::ValidateCameraTransform(const zeus::CTransform& a, return xfCpy; } -float CGameCamera::GetNearClipDistance() const { return x160_znear; } - -float CGameCamera::GetFarClipDistance() const { return x164_zfar; } - -float CGameCamera::GetAspectRatio() const { return x168_aspect; } - -TUniqueId CGameCamera::GetWatchedObject() const { return xe8_watchedObject; } - -float CGameCamera::GetFov() const { return x15c_currentFov; } - void CGameCamera::UpdatePerspective(float dt) { if (x174_ > 0.f) diff --git a/Runtime/Camera/CGameCamera.hpp b/Runtime/Camera/CGameCamera.hpp index 65483b39a..20c9ed72e 100644 --- a/Runtime/Camera/CGameCamera.hpp +++ b/Runtime/Camera/CGameCamera.hpp @@ -38,11 +38,11 @@ public: zeus::CMatrix4f GetPerspectiveMatrix() const; zeus::CVector3f ConvertToScreenSpace(const zeus::CVector3f&) const; zeus::CTransform ValidateCameraTransform(const zeus::CTransform&, const zeus::CTransform&); - float GetNearClipDistance() const; - float GetFarClipDistance() const; - float GetAspectRatio() const; - TUniqueId GetWatchedObject() const; - float GetFov() const; + float GetNearClipDistance() const { return x160_znear; } + float GetFarClipDistance() const { return x164_zfar; } + float GetAspectRatio() const { return x168_aspect; } + TUniqueId GetWatchedObject() const { return xe8_watchedObject; } + float GetFov() const { return x15c_currentFov; } void GetControllerNumber() const; bool DisablesInput() const; void UpdatePerspective(float); diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 5433d6062..dd8330369 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -141,9 +141,12 @@ void Buckets::Init() } CBooRenderer::CAreaListItem::CAreaListItem -(const std::vector* geom, const CAreaRenderOctTree* octTree, +(const std::vector* geom, + const CAreaRenderOctTree* octTree, + std::vector>&& textures, std::vector&& models, int areaIdx) -: x0_geometry(geom), x4_octTree(octTree), x10_models(std::move(models)), x18_areaIdx(areaIdx) {} + : x0_geometry(geom), x4_octTree(octTree), x8_textures(std::move(textures)), + x10_models(std::move(models)), x18_areaIdx(areaIdx) {} CBooRenderer::CAreaListItem::~CAreaListItem() {} @@ -152,7 +155,7 @@ void CBooRenderer::ActivateLightsForModel(CAreaListItem* item, CBooModel& model) std::vector thisLights; thisLights.reserve(4); - if (x304_lights.size()) + if (x300_dynamicLights.size()) { /* void* unk3 = nullptr; @@ -168,7 +171,7 @@ void CBooRenderer::ActivateLightsForModel(CAreaListItem* item, CBooModel& model) float lightRads[] = {-1.f, -1.f, -1.f, -1.f}; for (int i=0 ; i<4 ; ++i) { - for (CLight& light : x304_lights) + for (CLight& light : x300_dynamicLights) { /* if (unk3) @@ -337,14 +340,16 @@ void CBooRenderer::AddStaticGeometry(const std::vector* g auto search = FindStaticGeometry(geometry); if (search == x1c_areaListItems.end()) { + std::vector> textures; std::vector models; if (geometry->size()) { + (*geometry)[0].m_instance->MakeTexturesFromMats(textures, xc_store); models.reserve(geometry->size()); for (const CMetroidModelInstance& inst : *geometry) models.push_back(inst.m_instance); } - x1c_areaListItems.emplace_back(geometry, octTree, std::move(models), areaIdx); + x1c_areaListItems.emplace_back(geometry, octTree, std::move(textures), std::move(models), areaIdx); } } @@ -532,10 +537,10 @@ void CBooRenderer::SetPerspective(float fovy, float aspect, float znear, float z zeus::CRectangle CBooRenderer::SetViewportOrtho(bool centered, float znear, float zfar) { - float left = centered ? CGraphics::g_ViewportResolutionHalf.x : 0; - float bottom = centered ? CGraphics::g_ViewportResolutionHalf.y : 0; - float top = centered ? CGraphics::g_ViewportResolutionHalf.y : CGraphics::g_ViewportResolution.y; - float right = centered ? CGraphics::g_ViewportResolutionHalf.x : CGraphics::g_ViewportResolution.x; + float left = centered ? g_Viewport.x10_halfWidth : 0; + float bottom = centered ? g_Viewport.x14_halfHeight : 0; + float top = centered ? g_Viewport.x14_halfHeight : g_Viewport.xc_height; + float right = centered ? g_Viewport.x10_halfWidth : g_Viewport.x8_width; CGraphics::SetOrtho(left, right, top, bottom, znear, zfar); CGraphics::SetViewPointMatrix(zeus::CTransform::Identity()); @@ -561,7 +566,7 @@ void CBooRenderer::SetDebugOption(EDebugOption, int) void CBooRenderer::BeginScene() { - CGraphics::SetViewport(0, 0, CGraphics::g_ViewportResolution.x, CGraphics::g_ViewportResolution.y); + 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()); CGraphics::BeginScene(); @@ -699,4 +704,27 @@ u32 CBooRenderer::GetStaticWorldDataSize() return 0; } +void CBooRenderer::PrepareDynamicLights(const std::vector& lights) +{ + x300_dynamicLights = lights; + for (CAreaListItem& area : x1c_areaListItems) + { + if (const CAreaRenderOctTree* arot = area.x4_octTree) + { + area.x1c_lightOctreeWords.clear(); + area.x1c_lightOctreeWords.resize(arot->x14_bitmapWordCount * lights.size()); + u32* wordPtr = area.x1c_lightOctreeWords.data(); + for (const CLight& light : lights) + { + float radius = light.GetRadius(); + zeus::CVector3f vMin = light.GetPosition() - radius; + zeus::CVector3f vMax = light.GetPosition() + radius; + zeus::CAABox aabb(vMin, vMax); + arot->FindOverlappingModels(wordPtr, aabb); + wordPtr += arot->x14_bitmapWordCount; + } + } + } +} + } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 88b3597f0..22425798c 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -54,12 +54,16 @@ class CBooRenderer : public IRenderer { const std::vector* x0_geometry; const CAreaRenderOctTree* x4_octTree; - //std::vector> x8_textures; + /* originally auto_ptrs of vectors */ + std::vector> x8_textures; std::vector x10_models; int x18_areaIdx; - std::vector x20_; + /* Per-area octree-word major, light bits minor */ + std::vector x1c_lightOctreeWords; - CAreaListItem(const std::vector* geom, const CAreaRenderOctTree* octTree, + CAreaListItem(const std::vector* geom, + const CAreaRenderOctTree* octTree, + std::vector>&& textures, std::vector&& models, int areaIdx); ~CAreaListItem(); }; @@ -110,7 +114,7 @@ class CBooRenderer : public IRenderer CThermalColdFilter m_thermColdFilter; std::experimental::optional m_thermHotFilter; - std::vector x304_lights; + std::vector x300_dynamicLights; union { @@ -198,6 +202,7 @@ public: void DoThermalBlendCold(); void DoThermalBlendHot(); u32 GetStaticWorldDataSize(); + void PrepareDynamicLights(const std::vector& lights); boo::ITexture* GetThermoPalette() {return x288_thermoPalette;} diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index 27cbe58d0..0d11040e9 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -25,12 +25,10 @@ zeus::CTransform CGraphics::g_ViewMatrix; zeus::CVector3f CGraphics::g_ViewPoint; zeus::CTransform CGraphics::g_GXViewPointMatrix; zeus::CTransform CGraphics::g_CameraMatrix; -zeus::CVector2i CGraphics::g_ViewportResolution; -zeus::CVector2i CGraphics::g_ViewportResolutionHalf; SClipScreenRect CGraphics::g_CroppedViewport; int CGraphics::g_ViewportSamples = 1; bool CGraphics::g_IsGXModelMatrixIdentity = true; -SViewport gViewport = {0, 0, 640, 480, 640 / 2.f, 480 / 2.f}; +SViewport g_Viewport = {0, 0, 640, 480, 640 / 2.f, 480 / 2.f}; void CGraphics::DisableAllLights() { @@ -380,8 +378,8 @@ void CGraphics::FlushProjection() zeus::CVector2i CGraphics::ProjectPoint(const zeus::CVector3f& point) { zeus::CVector3f projPt = GetPerspectiveProjectionMatrix(false).multiplyOneOverW(point); - return {int(projPt.x * g_ViewportResolutionHalf.x) + g_ViewportResolutionHalf.x, - g_ViewportResolution.y - (int(projPt.y * g_ViewportResolutionHalf.y) + g_ViewportResolutionHalf.y)}; + return {int(projPt.x * g_Viewport.x10_halfWidth) + g_Viewport.x10_halfWidth, + g_Viewport.x14_halfHeight - (int(projPt.y * g_Viewport.x14_halfHeight) + g_Viewport.x14_halfHeight)}; } SClipScreenRect CGraphics::ClipScreenRectFromMS(const zeus::CVector3f& p1, @@ -413,7 +411,7 @@ SClipScreenRect CGraphics::ClipScreenRectFromVS(const zeus::CVector3f& p1, int minY2 = minY & 0xfffffffe; - if (minX2 >= g_ViewportResolution.x) + if (minX2 >= g_Viewport.x8_width) return {}; int maxX = abs(sp1.x - sp2.x) + minX; @@ -422,10 +420,10 @@ SClipScreenRect CGraphics::ClipScreenRectFromVS(const zeus::CVector3f& p1, return {}; int finalMinX = std::max(minX, 0 /* ViewportX origin */); - int finalMaxX = std::min(maxX, g_ViewportResolution.x); + int finalMaxX = std::min(maxX, int(g_Viewport.x8_width)); - if (minY2 >= g_ViewportResolution.y) + if (minY2 >= g_Viewport.xc_height) return {}; int maxY = abs(sp1.y - sp2.y) + minY; @@ -434,13 +432,13 @@ SClipScreenRect CGraphics::ClipScreenRectFromVS(const zeus::CVector3f& p1, return {}; int finalMinY = std::max(minY, 0 /* ViewportY origin */); - int finalMaxY = std::min(maxY, g_ViewportResolution.y); + int finalMaxY = std::min(maxY, int(g_Viewport.xc_height)); int width = maxX2 - minX2; int height = maxY2 - minY2; return {true, minX2, minY2, width, height, width, - minX2 / float(g_ViewportResolution.x), maxX2 / float(g_ViewportResolution.x), - 1.f - maxY2 / float(g_ViewportResolution.y), 1.f - minY2 / float(g_ViewportResolution.y)}; + minX2 / float(g_Viewport.x8_width), maxX2 / float(g_Viewport.x8_width), + 1.f - maxY2 / float(g_Viewport.xc_height), 1.f - minY2 / float(g_Viewport.xc_height)}; } @@ -452,11 +450,13 @@ zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const zeus::CVector3 void CGraphics::SetViewportResolution(const zeus::CVector2i& res) { - g_ViewportResolution = res; + g_Viewport.x8_width = res.x; + g_Viewport.xc_height = res.y; g_CroppedViewport = SClipScreenRect(); g_CroppedViewport.xc_width = res.x; g_CroppedViewport.x10_height = res.y; - g_ViewportResolutionHalf = {res.x / 2, res.y / 2}; + g_Viewport.x10_halfWidth = res.x / 2.f; + g_Viewport.x14_halfHeight = res.y / 2.f; if (g_GuiSys) g_GuiSys->OnViewportResize(); } diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 0b270178a..b28703fdb 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -149,7 +149,7 @@ struct SViewport float x14_halfHeight; }; -extern SViewport gViewport; +extern SViewport g_Viewport; struct SClipScreenRect { @@ -236,8 +236,6 @@ public: static zeus::CVector3f g_ViewPoint; static zeus::CTransform g_GXViewPointMatrix; static zeus::CTransform g_CameraMatrix; - static zeus::CVector2i g_ViewportResolution; - static zeus::CVector2i g_ViewportResolutionHalf; static SClipScreenRect g_CroppedViewport; static int g_ViewportSamples; static bool g_IsGXModelMatrixIdentity; diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index b6b6e3218..b74d8dec9 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -128,15 +128,23 @@ private: void VerifyCurrentShader(int shaderIdx); + static zeus::CVector3f g_PlayerPosition; + static float g_ModSeconds; + static float g_TransformedTime; + static float g_TransformedTime2; + static CBooModel* g_LastModelCached; + public: ~CBooModel(); CBooModel(TToken& token, std::vector* surfaces, SShader& shader, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, int numInsts); - static void MakeTexuresFromMats(const MaterialSet& matSet, - std::vector>& toksOut, - IObjectStore& store); + static void MakeTexturesFromMats(const MaterialSet& matSet, + std::vector>& toksOut, + IObjectStore& store); + void MakeTexturesFromMats(std::vector>& toksOut, + IObjectStore& store); bool IsOpaque() const {return x3c_firstSortedSurface == nullptr;} void ActivateLights(const std::vector& lights); @@ -167,6 +175,9 @@ public: static bool g_DrawingOccluders; static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;} + + static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos); + static void KillCachedViewDepState(); }; class CModel diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 0d562fb71..5843fead9 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -25,6 +25,27 @@ void CBooModel::ClearModelUniformCounters() model->ClearUniformCounter(); } +zeus::CVector3f CBooModel::g_PlayerPosition = {}; +float CBooModel::g_ModSeconds = 0.f; +float CBooModel::g_TransformedTime = 0.f; +float CBooModel::g_TransformedTime2 = 0.f; +void CBooModel::SetNewPlayerPositionAndTime(const zeus::CVector3f& pos) +{ + g_PlayerPosition = pos; + KillCachedViewDepState(); + u32 modMillis = std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch()).count() % u64(100000.f * 4.f * M_PIF / 3.f); + g_ModSeconds = modMillis / 1000.f; + g_TransformedTime = 1.f / -(0.05f * std::sin(g_ModSeconds * 1.5f) - 1.f); + g_TransformedTime2 = 1.f / -(0.015f * std::sin(g_ModSeconds * 1.5f + 1.f) - 1.f); +} + +CBooModel* CBooModel::g_LastModelCached = nullptr; +void CBooModel::KillCachedViewDepState() +{ + g_LastModelCached = nullptr; +} + CBooModel::~CBooModel() { if (m_prev) @@ -213,15 +234,21 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() return &newInst; } -void CBooModel::MakeTexuresFromMats(const MaterialSet& matSet, - std::vector>& toksOut, - IObjectStore& store) +void CBooModel::MakeTexturesFromMats(const MaterialSet& matSet, + std::vector>& toksOut, + IObjectStore& store) { toksOut.reserve(matSet.head.textureIDs.size()); for (const DataSpec::UniqueID32& id : matSet.head.textureIDs) toksOut.emplace_back(store.GetObj({SBIG('TXTR'), id.toUint32()})); } +void CBooModel::MakeTexturesFromMats(std::vector>& toksOut, + IObjectStore& store) +{ + MakeTexturesFromMats(*x4_matSet, toksOut, store); +} + void CBooModel::ActivateLights(const std::vector& lights) { m_lightingData.ambient = zeus::CColor::skBlack; @@ -694,7 +721,7 @@ CModel::CModel(std::unique_ptr&& in, u32 /* dataLen */, IObjectStore* stor CBooModel::SShader& shader = x18_matSets.back(); athena::io::MemoryReader r(sec, matSetSz); shader.m_matSet.read(r); - CBooModel::MakeTexuresFromMats(shader.m_matSet, shader.x0_textures, *store); + CBooModel::MakeTexturesFromMats(shader.m_matSet, shader.x0_textures, *store); } hecl::HMDLMeta hmdlMeta; diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index 3cf5c1a06..c9a69a3f7 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -35,6 +35,8 @@ public: }; enum class EDebugOption { + Zero, + One }; enum class EPrimitiveType { @@ -97,6 +99,7 @@ public: virtual void DoThermalBlendCold()=0; virtual void DoThermalBlendHot()=0; virtual u32 GetStaticWorldDataSize()=0; + virtual void PrepareDynamicLights(const std::vector& lights)=0; }; } diff --git a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp index 86c799dd0..ea17e21ce 100644 --- a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp @@ -21,15 +21,15 @@ void CCameraBlurFilter::draw(float amount) return; SClipScreenRect clipRect = {}; - clipRect.xc_width = CGraphics::g_ViewportResolution.x; - clipRect.x10_height = CGraphics::g_ViewportResolution.y; + clipRect.xc_width = g_Viewport.x8_width; + clipRect.x10_height = g_Viewport.xc_height; CGraphics::ResolveSpareTexture(clipRect); float aspect = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_CroppedViewport.x10_height); - float xFac = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_ViewportResolution.x); - float yFac = CGraphics::g_CroppedViewport.x10_height / float(CGraphics::g_ViewportResolution.y); - float xBias = CGraphics::g_CroppedViewport.x4_left / float(CGraphics::g_ViewportResolution.x); - float yBias = CGraphics::g_CroppedViewport.x8_top / float(CGraphics::g_ViewportResolution.y); + float xFac = CGraphics::g_CroppedViewport.xc_width / float(g_Viewport.x8_width); + float yFac = CGraphics::g_CroppedViewport.x10_height / float(g_Viewport.xc_height); + float xBias = CGraphics::g_CroppedViewport.x4_left / float(g_Viewport.x8_width); + float yBias = CGraphics::g_CroppedViewport.x8_top / float(g_Viewport.xc_height); Vert verts[4] = { diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp b/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp index 266fdfe4d..c3764ec27 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp @@ -39,12 +39,12 @@ void CColoredQuadFilter::draw(const zeus::CColor& color, const zeus::CRectangle& void CWideScreenFilter::draw(const zeus::CColor& color, float t) { - float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float aspect = g_Viewport.x8_width / float(g_Viewport.xc_height); if (aspect < 1.7777f) { - float targetHeight = CGraphics::g_ViewportResolution.x / 1.7777f; - float delta = (CGraphics::g_ViewportResolution.y - targetHeight) * t / 2.f; - delta /= float(CGraphics::g_ViewportResolution.y); + float targetHeight = g_Viewport.x8_width / 1.7777f; + float delta = (g_Viewport.xc_height - targetHeight) * t / 2.f; + delta /= float(g_Viewport.xc_height); zeus::CRectangle rect(0.f, 0.f, 1.f, delta); m_bottom.draw(color, rect); rect.position.y = 1.f - delta; @@ -54,14 +54,14 @@ void CWideScreenFilter::draw(const zeus::CColor& color, float t) float CWideScreenFilter::SetViewportToMatch(float t) { - float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float aspect = g_Viewport.x8_width / float(g_Viewport.xc_height); if (aspect < 1.7777f) { - float targetHeight = CGraphics::g_ViewportResolution.x / 1.7777f; - float delta = (CGraphics::g_ViewportResolution.y - targetHeight) * t / 2.f; + float targetHeight = g_Viewport.x8_width / 1.7777f; + float delta = (g_Viewport.xc_height - targetHeight) * t / 2.f; boo::SWindowRect rect = {}; - rect.size[0] = CGraphics::g_ViewportResolution.x; - rect.size[1] = CGraphics::g_ViewportResolution.y - delta * 2.f; + rect.size[0] = g_Viewport.x8_width; + rect.size[1] = g_Viewport.xc_height - delta * 2.f; rect.location[1] = delta; CGraphics::g_CroppedViewport = rect; CGraphics::g_BooMainCommandQueue->setViewport(rect); @@ -77,8 +77,8 @@ float CWideScreenFilter::SetViewportToMatch(float t) void CWideScreenFilter::SetViewportToFull() { boo::SWindowRect rect = {}; - rect.size[0] = CGraphics::g_ViewportResolution.x; - rect.size[1] = CGraphics::g_ViewportResolution.y; + rect.size[0] = g_Viewport.x8_width; + rect.size[1] = g_Viewport.xc_height; CGraphics::g_CroppedViewport = rect; CGraphics::g_BooMainCommandQueue->setViewport(rect); } diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp index 878454979..9a033f11d 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp @@ -53,10 +53,10 @@ void CTexturedQuadFilter::draw(const zeus::CColor& color, float uvScale, const z void CTexturedQuadFilter::drawCropped(const zeus::CColor& color, float uvScale) { - float xFac = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_ViewportResolution.x); - float yFac = CGraphics::g_CroppedViewport.x10_height / float(CGraphics::g_ViewportResolution.y); - float xBias = CGraphics::g_CroppedViewport.x4_left / float(CGraphics::g_ViewportResolution.x); - float yBias = CGraphics::g_CroppedViewport.x8_top / float(CGraphics::g_ViewportResolution.y); + float xFac = CGraphics::g_CroppedViewport.xc_width / float(g_Viewport.x8_width); + float yFac = CGraphics::g_CroppedViewport.x10_height / float(g_Viewport.xc_height); + float xBias = CGraphics::g_CroppedViewport.x4_left / float(g_Viewport.x8_width); + float yBias = CGraphics::g_CroppedViewport.x8_top / float(g_Viewport.xc_height); Vert verts[4] = { diff --git a/Runtime/GuiSys/CGuiSys.cpp b/Runtime/GuiSys/CGuiSys.cpp index 63075311a..9d92b6025 100644 --- a/Runtime/GuiSys/CGuiSys.cpp +++ b/Runtime/GuiSys/CGuiSys.cpp @@ -77,7 +77,7 @@ void CGuiSys::OnViewportResize() void CGuiSys::ViewportResizeFrame(CGuiFrame* frame) { - float vpAspectRatio = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float vpAspectRatio = g_Viewport.x8_width / float(g_Viewport.xc_height); if (frame->m_aspectConstraint > 0.f) { float hPad, vPad; diff --git a/Runtime/GuiSys/CSplashScreen.cpp b/Runtime/GuiSys/CSplashScreen.cpp index 3a241a1ef..aca019a35 100644 --- a/Runtime/GuiSys/CSplashScreen.cpp +++ b/Runtime/GuiSys/CSplashScreen.cpp @@ -66,7 +66,7 @@ void CSplashScreen::Draw() const color.a = x18_splashTimeout * 2.f; zeus::CRectangle rect; - float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float aspect = g_Viewport.x8_width / float(g_Viewport.xc_height); rect.size.x = m_quad.GetTex()->GetWidth() / (480.f * aspect); rect.size.y = m_quad.GetTex()->GetHeight() / 480.f; rect.position.x = 0.5f - rect.size.x / 2.f; diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index 63d4d8928..6c44b254f 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -2187,7 +2187,7 @@ void CFrontEndUI::Draw() const g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f); /* Correct movie aspect ratio */ - float vpAspectRatio = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float vpAspectRatio = g_Viewport.x8_width / float(g_Viewport.xc_height); float hPad, vPad; if (vpAspectRatio >= 1.78f) { diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index fbb89a1bc..dcb1222ec 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -160,6 +160,7 @@ public: void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CVector3f&); SAdvancementDeltas UpdateAnimation(float, CStateManager&, bool); void SetActorLights(std::unique_ptr); + bool GetE7_29() const { return xe7_29_; } }; } diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index f7ab9d127..875190bbb 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -176,6 +176,12 @@ void CAreaRenderOctTree::FindOverlappingModels(std::vector& out, const zeus RecursiveBuildOverlaps(out.data(), *this, x18_aabb, testAABB); } +void CAreaRenderOctTree::FindOverlappingModels(u32* out, const zeus::CAABox& testAABB) const +{ + reinterpret_cast(x38_entries[x34_indirectionTable[0]])-> + RecursiveBuildOverlaps(out, *this, x18_aabb, testAABB); +} + void CGameArea::CAreaFog::SetCurrent() const { g_Renderer->SetWorldFog(x0_fogMode, x4_rangeCur[0], x4_rangeCur[1], x1c_colorCur); diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 04c6ab2a8..4ebed4d1b 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -74,11 +74,13 @@ struct CAreaRenderOctTree CAreaRenderOctTree(const u8* buf); void FindOverlappingModels(std::vector& out, const zeus::CAABox& testAABB) const; + void FindOverlappingModels(u32* out, const zeus::CAABox& testAABB) const; }; class CGameArea : public IGameArea { friend class CWorld; + friend class CStateManager; int x4_selfIdx; ResId x8_nameSTRG; diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index 64c8c4631..bba70daaf 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -573,4 +573,12 @@ void CWorld::PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGame if (occlusionState == CGameArea::EOcclusionState::NotOccluded) area->SetOcclusionState(CGameArea::EOcclusionState::NotOccluded); } + +void CWorld::PreRender() +{ + for (CGameArea* head = x4c_chainHeads[3] ; head != skGlobalNonConstEnd ; head = head->x130_next) + { + head->PreRender(); + } +} } diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index a389aa49b..202dba97a 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -184,6 +184,8 @@ public: static void PropogateAreaChain(CGameArea::EOcclusionState, CGameArea*, CWorld*); static const CGameArea* GetAliveAreasEnd() { return skGlobalEnd; } static CGameArea* AliveAreasEnd() { return skGlobalNonConstEnd; } + + void PreRender(); }; struct CWorldLayers diff --git a/Runtime/World/CWorldTransManager.cpp b/Runtime/World/CWorldTransManager.cpp index 87b1aa8de..9387bd81f 100644 --- a/Runtime/World/CWorldTransManager.cpp +++ b/Runtime/World/CWorldTransManager.cpp @@ -279,8 +279,8 @@ void CWorldTransManager::DrawEnabled() float t = zeus::clamp(0.f, (x0_curTime - x4_modelData->x1d0_dissolveStartTime) / 2.f, 1.f); DrawFirstPass(); SClipScreenRect rect = {}; - rect.xc_width = CGraphics::g_ViewportResolution.x; - rect.x10_height = CGraphics::g_ViewportResolution.y; + rect.xc_width = g_Viewport.x8_width; + rect.x10_height = g_Viewport.xc_height; CGraphics::ResolveSpareTexture(rect); CGraphics::g_BooMainCommandQueue->clearTarget(true, true); DrawSecondPass(); @@ -308,7 +308,7 @@ void CWorldTransManager::DrawDisabled() void CWorldTransManager::DrawText() { - float vpAspectRatio = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float vpAspectRatio = g_Viewport.x8_width / float(g_Viewport.xc_height); float width = 448.f * vpAspectRatio; CGraphics::SetOrtho(0.f, width, 448.f, 0.f, -4096.f, 4096.f); CGraphics::SetViewPointMatrix(zeus::CTransform::Identity());