diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index a6799bf48..40f95411a 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -1,14 +1,200 @@ #if _WIN32 #include #endif +#include "GameGlobalObjects.hpp" #include "CBooRenderer.hpp" +#include "CTexture.hpp" +#include "CModel.hpp" +#include "Particle/CParticleGen.hpp" + +#define MIRROR_RAMP_RES 32 +#define FOGVOL_RAMP_RES 256 +#define SPHERE_RAMP_RES 32 namespace urde { -CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) -: x8_factory(resFac), xc_store(store) +static rstl::reserved_vector sDataHolder; +static rstl::reserved_vector, 50> sBucketsHolder; +static rstl::reserved_vector sPlaneObjectDataHolder; +static rstl::reserved_vector sPlaneObjectBucketHolder; + +rstl::reserved_vector Buckets::sBucketIndex; +rstl::reserved_vector* Buckets::sData = nullptr; +rstl::reserved_vector, 50>* Buckets::sBuckets = nullptr; +rstl::reserved_vector* Buckets::sPlaneObjectData = nullptr; +rstl::reserved_vector* Buckets::sPlaneObjectBucket = nullptr; +const float Buckets::skWorstMinMaxDistance[2] = {99999.f, -99999.f}; +float Buckets::sMinMaxDistance[2]; + +void Buckets::Clear() { + sData->clear(); + sPlaneObjectData->clear(); + sPlaneObjectBucket->clear(); + for (rstl::reserved_vector& bucket : *sBuckets) + bucket.clear(); + sMinMaxDistance[0] = skWorstMinMaxDistance[0]; + sMinMaxDistance[1] = skWorstMinMaxDistance[1]; +} + +void Buckets::Sort() +{ +} + +void Buckets::InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool b1, + const zeus::CPlane& plane, bool b2, EDrawableType dtype, const void* data) +{ + sPlaneObjectData->push_back(CDrawablePlaneObject(dtype, dist, something, aabb, b1, plane, b2, data)); +} + +void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, + const void* data, const zeus::CPlane& plane, u16 extraSort) +{ + float dist = plane.pointToPlaneDist(pos); + sData->push_back(CDrawable(dtype, extraSort, dist, aabb, data)); + if (sMinMaxDistance[0] > dist) + sMinMaxDistance[0] = dist; + if (sMinMaxDistance[1] < dist) + sMinMaxDistance[1] = dist; +} + +void Buckets::Shutdown() +{ + sData = nullptr; + sBuckets = nullptr; + sPlaneObjectData = nullptr; + sPlaneObjectBucket = nullptr; +} + +void Buckets::Init() +{ + sData = &sDataHolder; + sBuckets = &sBucketsHolder; + sBuckets->resize(50); + sPlaneObjectData = &sPlaneObjectDataHolder; + sPlaneObjectBucket = &sPlaneObjectBucketHolder; + sMinMaxDistance[0] = skWorstMinMaxDistance[0]; + sMinMaxDistance[1] = skWorstMinMaxDistance[1]; +} + +void CBooRenderer::RenderBucketItems(const std::vector& lights) +{ + for (u16 idx : Buckets::sBucketIndex) + { + rstl::reserved_vector& bucket = (*Buckets::sBuckets)[idx]; + for (CDrawable* drawable : bucket) + { + switch (drawable->GetType()) + { + case EDrawableType::Particle: + { + static_cast((void*)drawable->GetData())->Render(); + break; + } + case EDrawableType::World: + { + CBooSurface* surf = static_cast((void*)drawable->GetData()); + CBooModel* model = surf->m_parent; + if (model) + { + model->ActivateLights(lights); + CModelFlags flags; + model->DrawSurface(*surf, flags); + } + break; + } + default: + { + if (xa8_renderCallback) + { + xa8_renderCallback(drawable->GetData(), xac_callbackContext, + int(drawable->GetType()) - 2); + } + break; + } + } + } + } +} + +void CBooRenderer::GenerateMirrorRampTex(boo::IGraphicsDataFactory::Context& ctx) +{ + u8 data[MIRROR_RAMP_RES][MIRROR_RAMP_RES][4] = {}; + float halfRes = MIRROR_RAMP_RES / 2.f; + for (int y=0 ; yGetBooTexture(); +} + +CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) +: x8_factory(resFac), xc_store(store), x2a8_thermalRand(20) +{ + xee_24_ = true; + + m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool + { + GenerateMirrorRampTex(ctx); + GenerateFogVolumeRampTex(ctx); + GenerateSphereRampTex(ctx); + LoadThermoPalette(ctx); + return true; + }); + + Buckets::Init(); } void CBooRenderer::AddStaticGeometry(const std::vector&, const CAreaOctTree*, int) @@ -227,7 +413,26 @@ void CBooRenderer::SetThermalColdScale(float scale) } void CBooRenderer::DoThermalBlendCold() -{ +{ + zeus::CColor a = zeus::CColor::lerp(x2f4_thermColor, zeus::CColor::skWhite, x2f8_thermColdScale); + m_thermColdFilter.setColorA(a); + float bFac = 0.f; + float bAlpha = 1.f; + if (x2f8_thermColdScale < 0.5f) + { + bAlpha = x2f8_thermColdScale * 2.f; + bFac = (1.f - bAlpha) / 8.f; + } + zeus::CColor b{bFac, bFac, bFac, bAlpha}; + m_thermColdFilter.setColorB(b); + zeus::CColor c = zeus::CColor::lerp(zeus::CColor::skBlack, zeus::CColor::skWhite, + (x2f8_thermColdScale - 0.25f) * 4.f / 3.f); + m_thermColdFilter.setColorC(c); + + m_thermColdFilter.setScale(x2f8_thermColdScale); + + m_thermColdFilter.setShift(x2a8_thermalRand.Next() % 32); + m_thermColdFilter.draw(); } void CBooRenderer::DoThermalBlendHot() diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 935ce7b56..932134a68 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -1,25 +1,39 @@ #ifndef __URDE_CBOORENDERER_HPP__ #define __URDE_CBOORENDERER_HPP__ +#include #include "IRenderer.hpp" #include "CDrawable.hpp" +#include "CDrawablePlaneObject.hpp" #include "Shaders/CThermalColdFilter.hpp" +#include "CRandom16.hpp" namespace urde { class IObjectStore; class CMemorySys; class IFactory; +class CTexture; class Buckets { + friend class CBooRenderer; + + static rstl::reserved_vector sBucketIndex; + static rstl::reserved_vector* sData; + static rstl::reserved_vector, 50>* sBuckets; + static rstl::reserved_vector* sPlaneObjectData; + static rstl::reserved_vector* sPlaneObjectBucket; + static const float skWorstMinMaxDistance[2]; + static float sMinMaxDistance[2]; + public: static void Clear(); static void Sort(); - static void InsertPlaneObject(float, float, const zeus::CAABox&, bool, const zeus::CPlane&, - bool, EDrawableType, const void*); - static void Insert(const zeus::CVector3f&, const zeus::CAABox&, EDrawableType, const void*, - const zeus::CPlane&, unsigned short); + static void InsertPlaneObject(float dist, float something, const zeus::CAABox& aabb, bool b1, + const zeus::CPlane& plane, bool b2, EDrawableType dtype, const void* data); + static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, + const void* data, const zeus::CPlane& plane, u16 extraSort); static void Shutdown(); static void Init(); }; @@ -28,15 +42,61 @@ class CBooRenderer : public IRenderer { IFactory& x8_factory; IObjectStore& xc_store; + boo::GraphicsDataToken m_gfxToken; // CFont x10_fnt; u32 x18_ = 0; std::list x1c_; zeus::CFrustum x44_frustumPlanes; - float x2f8_thermColdScale = 0.f; + TDrawableCallback xa8_renderCallback; + const void* xac_callbackContext; + zeus::CVector3f xb0_ = {0.f, 1.f, 0.f}; + float xbc_ = 0; + + //boo::ITextureS* xe4_blackTex = nullptr; + bool xee_24_ : 1; + + boo::ITextureR* x14c_reflectionTex = nullptr; + boo::ITextureS* x150_mirrorRamp = nullptr; + boo::ITextureS* x1b8_fogVolumeRamp = nullptr; + boo::ITextureS* x220_sphereRamp = nullptr; + TLockedToken m_thermoPaletteTex; + boo::ITexture* x288_thermoPalette = nullptr; + + CRandom16 x2a8_thermalRand; + std::list x2b8_; + std::list x2d0_; + zeus::CColor x2e0_ = zeus::CColor::skWhite; + zeus::CVector3f x2e4_ = {0.f, 1.f, 0.f}; + + zeus::CColor x2f4_thermColor; + float x2f8_thermColdScale = 0.f; CThermalColdFilter m_thermColdFilter; + union + { + struct + { + bool x318_24_refectionDirty : 1; + bool x318_25_ : 1; + bool x318_26_ : 1; + bool x318_27_ : 1; + bool x318_28_ : 1; + bool x318_29_ : 1; + bool x318_30_ : 1; + bool x318_31_ : 1; + }; + u16 dummy = 0; + }; + + void GenerateMirrorRampTex(boo::IGraphicsDataFactory::Context& ctx); + void GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx); + void GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx); + void LoadThermoPalette(boo::IGraphicsDataFactory::Context& ctx); + + void RenderBucketItems(const std::vector& lights); + public: CBooRenderer(IObjectStore& store, IFactory& resFac); @@ -96,6 +156,9 @@ public: void DoThermalBlendCold(); void DoThermalBlendHot(); u32 GetStaticWorldDataSize(); + + void BindMainDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture);} + void BindReflectionDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex);} }; } diff --git a/Runtime/Graphics/CDrawable.hpp b/Runtime/Graphics/CDrawable.hpp index b2bd099c9..46d9d1cb0 100644 --- a/Runtime/Graphics/CDrawable.hpp +++ b/Runtime/Graphics/CDrawable.hpp @@ -6,7 +6,7 @@ namespace urde { -enum class EDrawableType +enum class EDrawableType : u16 { World, Particle, @@ -16,14 +16,20 @@ enum class EDrawableType class CDrawable { + EDrawableType x0_type; + u16 x2_extraSort; + const void* x4_data; + zeus::CAABox x8_aabb; + float x20_viewDist; public: - CDrawable(EDrawableType, u16, float, const zeus::CAABox&, const void*); + CDrawable(EDrawableType dtype, u16 extraSort, float planeDot, const zeus::CAABox& aabb, const void* data) + : x0_type(dtype), x2_extraSort(extraSort), x4_data(data), x8_aabb(aabb), x20_viewDist(planeDot) {} - EDrawableType GetType() const; - const zeus::CAABox& GetBounds() const; - float GetDistance() const; - void* GetData() const; - void GetExtraSort() const; + EDrawableType GetType() const {return x0_type;} + const zeus::CAABox& GetBounds() const {return x8_aabb;} + float GetDistance() const {return x20_viewDist;} + const void* GetData() const {return x4_data;} + u16 GetExtraSort() const {return x2_extraSort;} }; } diff --git a/Runtime/Graphics/CDrawablePlaneObject.hpp b/Runtime/Graphics/CDrawablePlaneObject.hpp index 5458426b4..d90a2da20 100644 --- a/Runtime/Graphics/CDrawablePlaneObject.hpp +++ b/Runtime/Graphics/CDrawablePlaneObject.hpp @@ -6,9 +6,18 @@ namespace urde { -class CDrawablePlaneObject +class CDrawablePlaneObject : public CDrawable { - CDrawablePlaneObject(EDrawableType, float, float, const zeus::CAABox&, bool, const zeus::CPlane&, bool, const void*); + u16 x24_extraSort2; + float x28_something; + zeus::CPlane x2c_plane; + bool x3c_24 : 1; + bool x3c_25 : 1; +public: + CDrawablePlaneObject(EDrawableType dtype, float dist, float something, const zeus::CAABox& aabb, + bool b1, const zeus::CPlane& plane, bool b2, const void* data) + : CDrawable(dtype, 0, dist, aabb, data), x24_extraSort2(0), x28_something(something), + x2c_plane(plane) {x3c_24 = b1; x3c_25 = b2;} }; } diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 36731f995..c6054aa8b 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -50,6 +50,7 @@ struct CBooSurface class CBooModel { friend class CModel; + friend class CBooRenderer; public: using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation; diff --git a/specter b/specter index 096472697..8d40a09b7 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 096472697cbcded63e076e9a35332698f903e042 +Subproject commit 8d40a09b7ca4719cef4f54c9ce31ed48bc550b48