mirror of https://github.com/AxioDL/metaforce.git
Initial fog rendering
This commit is contained in:
parent
9b9eed39f4
commit
a910ddd912
|
@ -534,7 +534,7 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
|||
if (asyncSearch != m_asyncLoadList.end())
|
||||
{
|
||||
/* Async spinloop */
|
||||
AsyncTask& task = asyncSearch->second;
|
||||
AsyncTask& task = *asyncSearch->second;
|
||||
task.EnsurePath(task.x0_tag, *resPath);
|
||||
|
||||
/* Pump load pipeline (cooking if needed) */
|
||||
|
@ -574,13 +574,21 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
|||
return BuildSync(tag, *resPath, paramXfer);
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
||||
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
|
||||
const urde::CVParamTransfer& paramXfer,
|
||||
urde::IObj** objOut)
|
||||
{
|
||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
||||
return {};
|
||||
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer))).first->second;
|
||||
}
|
||||
|
||||
void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
|
||||
const urde::CVParamTransfer& paramXfer,
|
||||
urde::IObj** objOut)
|
||||
{
|
||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
||||
return;
|
||||
m_asyncLoadList.emplace(std::make_pair(tag, AsyncTask(*this, tag, objOut, paramXfer)));
|
||||
BuildAsyncInternal(tag, paramXfer, objOut);
|
||||
}
|
||||
|
||||
u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
|
||||
|
@ -598,23 +606,23 @@ u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
|
|||
return fr->length();
|
||||
}
|
||||
|
||||
bool ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag,
|
||||
std::unique_ptr<u8[]>& target)
|
||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
||||
ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag,
|
||||
std::unique_ptr<u8[]>& target)
|
||||
{
|
||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
||||
return false;
|
||||
m_asyncLoadList.emplace(std::make_pair(tag, AsyncTask(*this, tag, target)));
|
||||
return true;
|
||||
return {};
|
||||
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_shared<AsyncTask>(*this, tag, target))).first->second;
|
||||
}
|
||||
|
||||
bool ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
|
||||
u32 size, u32 off,
|
||||
std::unique_ptr<u8[]>& target)
|
||||
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
|
||||
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
|
||||
u32 size, u32 off,
|
||||
std::unique_ptr<u8[]>& target)
|
||||
{
|
||||
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
|
||||
return false;
|
||||
m_asyncLoadList.emplace(std::make_pair(tag, AsyncTask(*this, tag, target, size, off)));
|
||||
return true;
|
||||
return {};
|
||||
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_shared<AsyncTask>(*this, tag, target, size, off))).first->second;
|
||||
}
|
||||
|
||||
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::SObjectTag& tag)
|
||||
|
@ -736,7 +744,7 @@ void ProjectResourceFactoryBase::AsyncIdle()
|
|||
|
||||
/* Ensure requested resource is in the index */
|
||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||
AsyncTask& task = it->second;
|
||||
AsyncTask& task = *it->second;
|
||||
auto search = m_tagToPath.find(task.x0_tag);
|
||||
if (search == m_tagToPath.end())
|
||||
{
|
||||
|
|
|
@ -18,23 +18,8 @@ class ProjectResourceFactoryBase : public urde::IFactory
|
|||
{
|
||||
friend class ProjectResourcePool;
|
||||
hecl::ClientProcess& m_clientProc;
|
||||
protected:
|
||||
std::unordered_map<urde::SObjectTag, hecl::ProjectPath> m_tagToPath;
|
||||
std::unordered_map<std::string, urde::SObjectTag> m_catalogNameToTag;
|
||||
void Clear();
|
||||
|
||||
const hecl::Database::Project* m_proj = nullptr;
|
||||
const hecl::Database::DataSpecEntry* m_origSpec = nullptr;
|
||||
const hecl::Database::DataSpecEntry* m_pcSpec = nullptr;
|
||||
/* Used to resolve cooked paths */
|
||||
std::unique_ptr<hecl::Database::IDataSpec> m_cookSpec;
|
||||
urde::CFactoryMgr m_factoryMgr;
|
||||
|
||||
hecl::BlenderToken m_backgroundBlender;
|
||||
std::thread m_backgroundIndexTh;
|
||||
std::mutex m_backgroundIndexMutex;
|
||||
bool m_backgroundRunning = false;
|
||||
|
||||
public:
|
||||
struct AsyncTask
|
||||
{
|
||||
ProjectResourceFactoryBase& m_parent;
|
||||
|
@ -73,7 +58,25 @@ protected:
|
|||
void CookComplete();
|
||||
bool AsyncPump();
|
||||
};
|
||||
std::unordered_map<SObjectTag, AsyncTask> m_asyncLoadList;
|
||||
|
||||
protected:
|
||||
std::unordered_map<urde::SObjectTag, hecl::ProjectPath> m_tagToPath;
|
||||
std::unordered_map<std::string, urde::SObjectTag> m_catalogNameToTag;
|
||||
void Clear();
|
||||
|
||||
const hecl::Database::Project* m_proj = nullptr;
|
||||
const hecl::Database::DataSpecEntry* m_origSpec = nullptr;
|
||||
const hecl::Database::DataSpecEntry* m_pcSpec = nullptr;
|
||||
/* Used to resolve cooked paths */
|
||||
std::unique_ptr<hecl::Database::IDataSpec> m_cookSpec;
|
||||
urde::CFactoryMgr m_factoryMgr;
|
||||
|
||||
hecl::BlenderToken m_backgroundBlender;
|
||||
std::thread m_backgroundIndexTh;
|
||||
std::mutex m_backgroundIndexMutex;
|
||||
bool m_backgroundRunning = false;
|
||||
|
||||
std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>> m_asyncLoadList;
|
||||
|
||||
bool WaitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut);
|
||||
bool
|
||||
|
@ -107,14 +110,15 @@ public:
|
|||
ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {}
|
||||
std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&);
|
||||
void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**);
|
||||
std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**);
|
||||
void CancelBuild(const urde::SObjectTag&);
|
||||
bool CanBuild(const urde::SObjectTag&);
|
||||
const urde::SObjectTag* GetResourceIdByName(const char*) const;
|
||||
FourCC GetResourceTypeById(ResId id) const;
|
||||
|
||||
u32 ResourceSize(const SObjectTag& tag);
|
||||
bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target);
|
||||
bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target);
|
||||
std::shared_ptr<AsyncTask> LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target);
|
||||
std::shared_ptr<AsyncTask> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target);
|
||||
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
|
||||
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
|
||||
|
||||
|
|
|
@ -91,7 +91,9 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
|||
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||
|
||||
CGraphics::SetPerspective(55.0, aspect, 0.1f, 1000.f);
|
||||
CGraphics::SetPerspective(55.0, aspect, 1.f, 15.f);
|
||||
CGraphics::SetFog(ERglFogMode::PerspExp, 10.f, 15.f, zeus::CColor::skRed);
|
||||
//CGraphics::SetFog(ERglFogMode::PerspExp, 10.f + std::sin(m_theta) * 5.f, 15.f + std::sin(m_theta) * 5.f, zeus::CColor::skRed);
|
||||
zeus::CFrustum frustum;
|
||||
frustum.updatePlanes(CGraphics::g_GXModelView, zeus::SProjPersp(55.0, aspect, 0.1f, 1000.f));
|
||||
g_Renderer->SetClippingPlanes(frustum);
|
||||
|
@ -100,13 +102,14 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
|||
CLight::BuildCustom({5.f, -20.f, 10.f}, {0.f, 1.f, 0.f},
|
||||
{200.f, 200.f, 200.f}, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f)};
|
||||
//lights = {CLight::BuildLocalAmbient({}, {1.0f, 0.0f, 0.0f, 1.f})};
|
||||
//m_vm.m_modelTest->GetInstance().ActivateLights(lights);
|
||||
g_Renderer->SetThermal(true, 1.f, zeus::CColor::skWhite);
|
||||
g_Renderer->SetThermalColdScale(std::sin(m_theta) * 0.5f + 0.5f);
|
||||
g_Renderer->DoThermalBlendCold();
|
||||
flags.m_extendedShaderIdx = 2;
|
||||
m_vm.m_modelTest->GetInstance().ActivateLights(lights);
|
||||
//g_Renderer->SetThermal(true, 1.f, zeus::CColor::skWhite);
|
||||
//g_Renderer->SetThermalColdScale(std::sin(m_theta) * 0.5f + 0.5f);
|
||||
//g_Renderer->DoThermalBlendCold();
|
||||
//flags.m_extendedShaderIdx = 2;
|
||||
flags.m_extendedShaderIdx = 1;
|
||||
m_vm.m_modelTest->Draw(flags);
|
||||
g_Renderer->DoThermalBlendHot();
|
||||
//g_Renderer->DoThermalBlendHot();
|
||||
//m_spaceWarpFilter.setStrength(std::sin(m_theta * 5.f) * 0.5f + 0.5f);
|
||||
//m_spaceWarpFilter.draw(zeus::CVector2f{0.f, 0.f});
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr)
|
|||
// TODO: Finish
|
||||
zeus::CColor tmpColor; // Get from water
|
||||
zeus::CVector2f tmpVector; // Get from camera
|
||||
x3c_fog.SetFogExplicit(ERglFogMode::Four, tmpColor, tmpVector);
|
||||
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, tmpColor, tmpVector);
|
||||
stateMgr.GetCameraFilterPass(4).SetFilter(CCameraFilterPass::EFilterType::One,
|
||||
CCameraFilterPass::EFilterShape::Zero,
|
||||
0.f, tmpColor, -1);
|
||||
|
|
|
@ -636,8 +636,11 @@ void CBooRenderer::SetWireframeFlags(int)
|
|||
{
|
||||
}
|
||||
|
||||
void CBooRenderer::SetWorldFog(ERglFogMode, float, float, const zeus::CColor&)
|
||||
void CBooRenderer::SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color)
|
||||
{
|
||||
if (x318_28_disableFog)
|
||||
mode = ERglFogMode::None;
|
||||
CGraphics::SetFog(mode, startz, endz, color);
|
||||
}
|
||||
|
||||
void CBooRenderer::RenderFogVolume(const zeus::CColor&, const zeus::CAABox&, const TLockedToken<CModel>*, const CSkinnedModel*)
|
||||
|
|
|
@ -119,7 +119,7 @@ class CBooRenderer : public IRenderer
|
|||
bool x318_25_drawWireframe : 1;
|
||||
bool x318_26_ : 1;
|
||||
bool x318_27_ : 1;
|
||||
bool x318_28_ : 1;
|
||||
bool x318_28_disableFog : 1;
|
||||
bool x318_29_thermalVisor : 1;
|
||||
bool x318_30_ : 1;
|
||||
bool x318_31_ : 1;
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace urde
|
|||
{
|
||||
|
||||
CGraphics::CProjectionState CGraphics::g_Proj;
|
||||
CGraphics::CFogState CGraphics::g_Fog;
|
||||
float CGraphics::g_ProjAspect = 1.f;
|
||||
u32 CGraphics::g_NumLightsActive = 0;
|
||||
u32 CGraphics::g_NumBreakpointsWaiting = 0;
|
||||
|
@ -66,6 +67,23 @@ void CGraphics::SetAmbientColor(const zeus::CColor& col)
|
|||
// TODO: set for real
|
||||
}
|
||||
|
||||
void CGraphics::SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color)
|
||||
{
|
||||
if (mode == ERglFogMode::None)
|
||||
{
|
||||
g_Fog.m_start = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float projRange = g_Proj.x18_far - g_Proj.x14_near;
|
||||
float userRange = endz - startz;
|
||||
|
||||
g_Fog.m_color = color;
|
||||
g_Fog.m_start = (startz - g_Proj.x14_near) / projRange;
|
||||
g_Fog.m_rangeScale = projRange / userRange;
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics::SetDepthWriteMode(bool test, ERglEnum comp, bool write)
|
||||
{
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "RetroTypes.hpp"
|
||||
#include "zeus/CTransform.hpp"
|
||||
#include "zeus/CVector2i.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||
|
@ -121,6 +122,23 @@ enum class ERglAlphaOp
|
|||
XNor = 3
|
||||
};
|
||||
|
||||
enum class ERglFogMode
|
||||
{
|
||||
None = 0x00,
|
||||
|
||||
PerspLin = 0x02,
|
||||
PerspExp = 0x04,
|
||||
PerspExp2 = 0x05,
|
||||
PerspRevExp = 0x06,
|
||||
PerspRevExp2 = 0x07,
|
||||
|
||||
OrthoLin = 0x0A,
|
||||
OrthoExp = 0x0C,
|
||||
OrthoExp2 = 0x0D,
|
||||
OrthoRevExp = 0x0E,
|
||||
OrthoRevExp2 = 0x0F
|
||||
};
|
||||
|
||||
struct SClipScreenRect
|
||||
{
|
||||
bool x0_valid;
|
||||
|
@ -166,7 +184,16 @@ public:
|
|||
float x14_near;
|
||||
float x18_far;
|
||||
};
|
||||
|
||||
struct CFogState
|
||||
{
|
||||
zeus::CColor m_color;
|
||||
float m_rangeScale = 4096.f;
|
||||
float m_start = 1.f;
|
||||
};
|
||||
|
||||
static CProjectionState g_Proj;
|
||||
static CFogState g_Fog;
|
||||
static float g_ProjAspect;
|
||||
static u32 g_NumLightsActive;
|
||||
static u32 g_NumBreakpointsWaiting;
|
||||
|
@ -192,6 +219,7 @@ public:
|
|||
static void EnableLight(ERglLight light);
|
||||
static void SetLightState(ERglLightBits lightState);
|
||||
static void SetAmbientColor(const zeus::CColor& col);
|
||||
static void SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color);
|
||||
static void SetDepthWriteMode(bool test, ERglEnum comp, bool write);
|
||||
static void SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp);
|
||||
static void SetCullMode(ERglCullMode);
|
||||
|
|
|
@ -521,6 +521,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags) const
|
|||
lightingOut.colorRegs[0] = flags.regColors[0];
|
||||
lightingOut.colorRegs[1] = flags.regColors[1];
|
||||
lightingOut.colorRegs[2] = flags.regColors[2];
|
||||
lightingOut.fog = CGraphics::g_Fog;
|
||||
}
|
||||
|
||||
m_uniformBuffer->unmap();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "zeus/CPlane.hpp"
|
||||
#include "zeus/CFrustum.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "CGraphics.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -37,9 +38,6 @@ public:
|
|||
enum class EPrimitiveType
|
||||
{
|
||||
};
|
||||
enum class ERglFogMode
|
||||
{
|
||||
};
|
||||
|
||||
virtual ~IRenderer() = default;
|
||||
virtual void AddStaticGeometry(const std::vector<CMetroidModelInstance>*, const CAreaRenderOctTree*, int)=0;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "optional.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
|
||||
#define URDE_MAX_LIGHTS 16
|
||||
|
||||
|
@ -36,6 +37,7 @@ public:
|
|||
Light lights[URDE_MAX_LIGHTS];
|
||||
zeus::CColor ambient;
|
||||
zeus::CColor colorRegs[3];
|
||||
CGraphics::CFogState fog;
|
||||
};
|
||||
|
||||
struct ThermalUniform
|
||||
|
|
|
@ -13,6 +13,12 @@ static const char* LightingGLSL =
|
|||
" vec4 linAtt;\n"
|
||||
" vec4 angAtt;\n"
|
||||
"};\n"
|
||||
"struct Fog\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" float rangeScale;\n"
|
||||
" float start;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"UBINDING2 uniform LightingUniform\n"
|
||||
"{\n"
|
||||
|
@ -21,6 +27,7 @@ static const char* LightingGLSL =
|
|||
" vec4 colorReg0;\n"
|
||||
" vec4 colorReg1;\n"
|
||||
" vec4 colorReg2;\n"
|
||||
" Fog fog;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vec4 LightingFunc(vec4 mvPosIn, vec4 mvNormIn)\n"
|
||||
|
@ -44,6 +51,15 @@ static const char* LightingGLSL =
|
|||
" return clamp(ret, vec4(0.0,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1.0));\n"
|
||||
"}\n";
|
||||
|
||||
static const char* MainPostGLSL =
|
||||
"vec4 MainPostFunc(vec4 colorIn)\n"
|
||||
"{\n"
|
||||
" float fogZ = (vtf.mvPos.z - fog.start) * fog.rangeScale;\n"
|
||||
" return vec4(fogZ, fogZ, fogZ, 1.0);\n"
|
||||
" return mix(fog.color, colorIn, clamp(exp2(-8.0 * fogZ), 0.0, 1.0));\n"
|
||||
"}\n"
|
||||
"\n";
|
||||
|
||||
static const char* ThermalPostGLSL =
|
||||
"UBINDING2 uniform ThermalUniform\n"
|
||||
"{\n"
|
||||
|
@ -70,7 +86,7 @@ CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
|
|||
hecl::Runtime::ShaderCacheExtensions ext(plat);
|
||||
|
||||
/* Normal lit shading */
|
||||
ext.registerExtensionSlot({LightingGLSL, "LightingFunc"}, {}, 3, BlockNames, 0, nullptr,
|
||||
ext.registerExtensionSlot({LightingGLSL, "LightingFunc"}, {MainPostGLSL, "MainPostFunc"}, 3, BlockNames, 0, nullptr,
|
||||
hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original);
|
||||
|
||||
/* Thermal Visor shading */
|
||||
|
|
|
@ -30,8 +30,8 @@ public:
|
|||
|
||||
/* Non-factory versions, replaces CResLoader */
|
||||
virtual u32 ResourceSize(const urde::SObjectTag& tag)=0;
|
||||
virtual bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target)=0;
|
||||
virtual bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target)=0;
|
||||
//virtual bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target)=0;
|
||||
//virtual bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target)=0;
|
||||
virtual std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag)=0;
|
||||
virtual std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off)=0;
|
||||
};
|
||||
|
|
|
@ -177,33 +177,98 @@ void CAreaRenderOctTree::FindOverlappingModels(std::vector<u32>& out, const zeus
|
|||
|
||||
void CGameArea::CAreaFog::SetCurrent() const
|
||||
{
|
||||
g_Renderer->SetWorldFog(x0_fogMode, x4_rangeCur[0], x4_rangeCur[1], x1c_colorCur);
|
||||
}
|
||||
|
||||
void CGameArea::CAreaFog::Update(float dt)
|
||||
{
|
||||
if (x0_fogMode == ERglFogMode::None)
|
||||
return;
|
||||
if (x1c_colorCur == x28_colorTarget && x4_rangeCur == xc_rangeTarget)
|
||||
return;
|
||||
|
||||
float colorDelta = x34_colorDelta * dt;
|
||||
zeus::CVector2f rangeDelta = x14_rangeDelta * dt;
|
||||
|
||||
for (int i=0 ; i<3 ; ++i)
|
||||
{
|
||||
float delta = x28_colorTarget[i] - x1c_colorCur[i];
|
||||
if (std::fabs(delta) <= colorDelta)
|
||||
{
|
||||
x1c_colorCur[i] = x28_colorTarget[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta < 0.f)
|
||||
x1c_colorCur[i] -= colorDelta;
|
||||
else
|
||||
x1c_colorCur[i] += colorDelta;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0 ; i<2 ; ++i)
|
||||
{
|
||||
float delta = xc_rangeTarget[i] - x4_rangeCur[i];
|
||||
if (std::fabs(delta) <= rangeDelta[i])
|
||||
{
|
||||
x4_rangeCur[i] = xc_rangeTarget[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta < 0.f)
|
||||
x4_rangeCur[i] -= rangeDelta[i];
|
||||
else
|
||||
x4_rangeCur[i] += rangeDelta[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameArea::CAreaFog::RollFogOut(float, float, const zeus::CColor& color)
|
||||
void CGameArea::CAreaFog::RollFogOut(float rangeDelta, float colorDelta, const zeus::CColor& color)
|
||||
{
|
||||
x14_rangeDelta = {rangeDelta, rangeDelta * 2.f};
|
||||
xc_rangeTarget = {4096.f, 4096.f};
|
||||
x34_colorDelta = colorDelta;
|
||||
x28_colorTarget = color;
|
||||
}
|
||||
|
||||
void CGameArea::CAreaFog::FadeFog(ERglFogMode,
|
||||
void CGameArea::CAreaFog::FadeFog(ERglFogMode mode,
|
||||
const zeus::CColor& color, const zeus::CVector2f& vec1,
|
||||
float, const zeus::CVector2f& vec2)
|
||||
float speed, const zeus::CVector2f& vec2)
|
||||
{
|
||||
if (x0_fogMode == ERglFogMode::None)
|
||||
{
|
||||
x1c_colorCur = color;
|
||||
x28_colorTarget = color;
|
||||
x4_rangeCur = {vec1[1], vec1[1]};
|
||||
xc_rangeTarget = vec1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x28_colorTarget = color;
|
||||
xc_rangeTarget = vec1;
|
||||
}
|
||||
x0_fogMode = mode;
|
||||
x34_colorDelta = speed;
|
||||
x14_rangeDelta = vec2;
|
||||
}
|
||||
|
||||
void CGameArea::CAreaFog::SetFogExplicit(ERglFogMode, const zeus::CColor& color, const zeus::CVector2f& vec)
|
||||
void CGameArea::CAreaFog::SetFogExplicit(ERglFogMode mode, const zeus::CColor& color, const zeus::CVector2f& range)
|
||||
{
|
||||
x0_fogMode = mode;
|
||||
x1c_colorCur = color;
|
||||
x28_colorTarget = color;
|
||||
x4_rangeCur = range;
|
||||
xc_rangeTarget = range;
|
||||
}
|
||||
|
||||
bool CGameArea::CAreaFog::IsFogDisabled() const
|
||||
{
|
||||
return true;
|
||||
return x0_fogMode == ERglFogMode::None;
|
||||
}
|
||||
|
||||
void CGameArea::CAreaFog::DisableFog()
|
||||
{
|
||||
x0_fogMode = ERglFogMode::None;
|
||||
}
|
||||
|
||||
static std::vector<SObjectTag> ReadDependencyList(CInputStream& in)
|
||||
|
@ -257,38 +322,37 @@ bool CDummyGameArea::IGetScriptingMemoryAlways() const
|
|||
|
||||
TAreaId CDummyGameArea::IGetAreaId() const
|
||||
{
|
||||
return 0;
|
||||
return x10_areaId;
|
||||
}
|
||||
|
||||
ResId CDummyGameArea::IGetAreaAssetId() const
|
||||
{
|
||||
return 0;
|
||||
return xc_mrea;
|
||||
}
|
||||
|
||||
bool CDummyGameArea::IIsActive() const
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
TAreaId CDummyGameArea::IGetAttachedAreaId(int) const
|
||||
TAreaId CDummyGameArea::IGetAttachedAreaId(int idx) const
|
||||
{
|
||||
return 0;
|
||||
return x44_attachedAreaIndices[idx];
|
||||
}
|
||||
|
||||
u32 CDummyGameArea::IGetNumAttachedAreas() const
|
||||
{
|
||||
return 0;
|
||||
return x44_attachedAreaIndices.size();
|
||||
}
|
||||
|
||||
ResId CDummyGameArea::IGetStringTableAssetId() const
|
||||
{
|
||||
return 0;
|
||||
return x8_nameSTRG;
|
||||
}
|
||||
|
||||
static zeus::CTransform identityXf(zeus::CMatrix3f::skIdentityMatrix3f);
|
||||
const zeus::CTransform& CDummyGameArea::IGetTM() const
|
||||
{
|
||||
return identityXf;
|
||||
return x14_transform;
|
||||
}
|
||||
|
||||
CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
|
||||
|
@ -357,24 +421,24 @@ bool CGameArea::IIsActive() const
|
|||
return false;
|
||||
}
|
||||
|
||||
TAreaId CGameArea::IGetAttachedAreaId(int) const
|
||||
TAreaId CGameArea::IGetAttachedAreaId(int idx) const
|
||||
{
|
||||
return 0;
|
||||
return x8c_attachedAreaIndices[idx];
|
||||
}
|
||||
|
||||
u32 CGameArea::IGetNumAttachedAreas() const
|
||||
{
|
||||
return 0;
|
||||
return x8c_attachedAreaIndices.size();
|
||||
}
|
||||
|
||||
ResId CGameArea::IGetStringTableAssetId() const
|
||||
{
|
||||
return 0;
|
||||
return x8_nameSTRG;
|
||||
}
|
||||
|
||||
const zeus::CTransform& CGameArea::IGetTM() const
|
||||
{
|
||||
return identityXf;
|
||||
return xc_transform;
|
||||
}
|
||||
|
||||
bool CGameArea::DoesAreaNeedEnvFx() const
|
||||
|
@ -469,17 +533,93 @@ void CGameArea::SetChain(CGameArea* other, int)
|
|||
{
|
||||
}
|
||||
|
||||
void CGameArea::StartStreamingMainArea()
|
||||
bool CGameArea::StartStreamingMainArea()
|
||||
{
|
||||
if (xf0_24_postConstructed)
|
||||
return false;
|
||||
|
||||
switch (xf4_phase)
|
||||
{
|
||||
case Phase::LoadHeader:
|
||||
{
|
||||
x110_mreaSecBufs.reserve(3);
|
||||
AllocNewAreaData(0, 96);
|
||||
x12c_postConstructed.reset(new CPostConstructed());
|
||||
xf4_phase = Phase::LoadSecSizes;
|
||||
break;
|
||||
}
|
||||
case Phase::LoadSecSizes:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
break;
|
||||
MREAHeader header = VerifyHeader();
|
||||
AllocNewAreaData(x110_mreaSecBufs[0].second, ROUND_UP_32(header.secCount * 4));
|
||||
xf4_phase = Phase::ReserveSections;
|
||||
break;
|
||||
}
|
||||
case Phase::ReserveSections:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
break;
|
||||
x110_mreaSecBufs.reserve(GetNumPartSizes() + 2);
|
||||
x124_secCount = 0;
|
||||
x128_mreaDataOffset = x110_mreaSecBufs[0].second + x110_mreaSecBufs[1].second;
|
||||
xf4_phase = Phase::LoadDataSections;
|
||||
break;
|
||||
}
|
||||
case Phase::LoadDataSections:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
|
||||
u32 totalSz = 0;
|
||||
u32 secCount = GetNumPartSizes();
|
||||
for (int i=2 ; i<secCount ; ++i)
|
||||
totalSz += hecl::SBig(reinterpret_cast<u32*>(x110_mreaSecBufs[1].first.get())[i]);
|
||||
|
||||
AllocNewAreaData(x128_mreaDataOffset, totalSz);
|
||||
|
||||
m_resolvedBufs.reserve(secCount);
|
||||
m_resolvedBufs.emplace_back(x110_mreaSecBufs[0].first.get(), x110_mreaSecBufs[0].second);
|
||||
m_resolvedBufs.emplace_back(x110_mreaSecBufs[1].first.get(), x110_mreaSecBufs[1].second);
|
||||
|
||||
u32 curOff = 0;
|
||||
for (int i=2 ; i<secCount ; ++i)
|
||||
{
|
||||
u32 size = hecl::SBig(reinterpret_cast<u32*>(x110_mreaSecBufs[1].first.get())[i]);
|
||||
m_resolvedBufs.emplace_back(x110_mreaSecBufs[2].first.get() + curOff, size);
|
||||
curOff += size;
|
||||
}
|
||||
|
||||
xf4_phase = Phase::WaitForFinish;
|
||||
break;
|
||||
}
|
||||
case Phase::WaitForFinish:
|
||||
{
|
||||
CullDeadAreaRequests();
|
||||
if (xf8_loadTransactions.size())
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CGameArea::GetNumPartSizes() const
|
||||
{
|
||||
return 0;
|
||||
return hecl::SBig(*reinterpret_cast<u32*>(x110_mreaSecBufs[0].first.get() + 60));
|
||||
}
|
||||
|
||||
void CGameArea::AllocNewAreaData(int, int)
|
||||
void CGameArea::AllocNewAreaData(int offset, int size)
|
||||
{
|
||||
x110_mreaSecBufs.emplace_back(new u8[size], size);
|
||||
xf8_loadTransactions.push_back(
|
||||
static_cast<ProjectResourceFactoryBase*>(g_ResFactory)->
|
||||
LoadResourcePartAsync(SObjectTag{FOURCC('MREA'), x84_mrea}, size, offset,
|
||||
x110_mreaSecBufs.back().first));
|
||||
}
|
||||
|
||||
void CGameArea::Invalidate(CStateManager& mgr)
|
||||
|
@ -488,6 +628,15 @@ void CGameArea::Invalidate(CStateManager& mgr)
|
|||
|
||||
void CGameArea::CullDeadAreaRequests()
|
||||
{
|
||||
for (auto it = xf8_loadTransactions.begin() ; it != xf8_loadTransactions.end() ;)
|
||||
{
|
||||
if ((*it)->m_complete)
|
||||
{
|
||||
it = xf8_loadTransactions.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameArea::StartStreamIn(CStateManager& mgr)
|
||||
|
@ -629,6 +778,8 @@ void CGameArea::PostConstructArea()
|
|||
|
||||
void CGameArea::FillInStaticGeometry()
|
||||
{
|
||||
x12c_postConstructed->x4c_insts.clear();
|
||||
|
||||
}
|
||||
|
||||
void CGameArea::VerifyTokenList(CStateManager& stateMgr)
|
||||
|
|
|
@ -13,16 +13,13 @@
|
|||
#include "CObjectList.hpp"
|
||||
#include "CWorldLight.hpp"
|
||||
#include "Graphics/CPVSAreaSet.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "CPathFindArea.hpp"
|
||||
#include "Editor/ProjectResourceFactoryBase.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CStateManager;
|
||||
class CPFArea;
|
||||
|
||||
enum class ERglFogMode
|
||||
{
|
||||
Four = 4
|
||||
};
|
||||
|
||||
class CDummyGameArea : public IGameArea
|
||||
{
|
||||
|
@ -113,24 +110,34 @@ class CGameArea : public IGameArea
|
|||
u8 _dummy = 0;
|
||||
};
|
||||
|
||||
std::list<std::shared_ptr<const hecl::ClientProcess::BufferTransaction>> xf8_loadTransactions;
|
||||
enum class Phase
|
||||
{
|
||||
LoadHeader,
|
||||
LoadSecSizes,
|
||||
ReserveSections,
|
||||
LoadDataSections,
|
||||
WaitForFinish
|
||||
} xf4_phase = Phase::LoadHeader;
|
||||
|
||||
std::list<std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>> xf8_loadTransactions;
|
||||
|
||||
public:
|
||||
class CAreaFog
|
||||
{
|
||||
zeus::CVector2f x4_ = {0.f, 1024.f};
|
||||
zeus::CVector2f xc_ = {0.f, 1024.f};
|
||||
zeus::CVector2f x14_;
|
||||
zeus::CVector3f x1c_ = {0.5f};
|
||||
zeus::CVector3f x28_ = {0.5f};
|
||||
float x34_ = 0.f;
|
||||
ERglFogMode x0_fogMode = ERglFogMode::None;
|
||||
zeus::CVector2f x4_rangeCur = {0.f, 1024.f};
|
||||
zeus::CVector2f xc_rangeTarget = {0.f, 1024.f};
|
||||
zeus::CVector2f x14_rangeDelta;
|
||||
zeus::CColor x1c_colorCur = {0.5f, 0.5f, 0.5f, 1.f};
|
||||
zeus::CColor x28_colorTarget = {0.5f, 0.5f, 0.5f, 1.f};
|
||||
float x34_colorDelta = 0.f;
|
||||
public:
|
||||
void SetCurrent() const;
|
||||
void Update(float dt);
|
||||
void RollFogOut(float, float, const zeus::CColor& color);
|
||||
void RollFogOut(float rangeDelta, float colorDelta, const zeus::CColor& color);
|
||||
void FadeFog(ERglFogMode, const zeus::CColor& color, const zeus::CVector2f& vec1,
|
||||
float, const zeus::CVector2f& vec2);
|
||||
void SetFogExplicit(ERglFogMode, const zeus::CColor& color, const zeus::CVector2f& vec);
|
||||
void SetFogExplicit(ERglFogMode mode, const zeus::CColor& color, const zeus::CVector2f& range);
|
||||
bool IsFogDisabled() const;
|
||||
void DisableFog();
|
||||
};
|
||||
|
@ -154,7 +161,7 @@ public:
|
|||
TUniqueId x4_uid = kInvalidUniqueId;
|
||||
} xa8_map[1024];
|
||||
u32 x10a8_pvsVersion = 0;
|
||||
TLockedToken<CPFArea> x10ac_path;
|
||||
TLockedToken<CPathFindArea> x10ac_path;
|
||||
// bool x10b8_ = 0; optional flag for CToken
|
||||
u32 x10bc_ = 0;
|
||||
std::unique_ptr<CObjectList> x10c0_areaObjs;
|
||||
|
@ -197,6 +204,9 @@ public:
|
|||
};
|
||||
private:
|
||||
std::vector<std::pair<std::unique_ptr<u8[]>, int>> x110_mreaSecBufs;
|
||||
std::vector<std::pair<u8*, int>> m_resolvedBufs;
|
||||
u32 x124_secCount = 0;
|
||||
u32 x128_mreaDataOffset = 0;
|
||||
std::unique_ptr<CPostConstructed> x12c_postConstructed;
|
||||
|
||||
void UpdateFog(float dt);
|
||||
|
@ -256,7 +266,7 @@ public:
|
|||
//void TransferTokensToARAM();
|
||||
//void TransferARAMTokensOver();
|
||||
void SetChain(CGameArea* other, int);
|
||||
void StartStreamingMainArea();
|
||||
bool StartStreamingMainArea();
|
||||
//void UnloadAllLoadedTextures();
|
||||
//void ReloadAllLoadedTextures();
|
||||
u32 GetNumPartSizes() const;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "CStateManager.hpp"
|
||||
#include "CInGameTweakManagerBase.hpp"
|
||||
#include "Audio/CAudioGroupSet.hpp"
|
||||
#include "Editor/ProjectResourceFactoryBase.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -19,7 +20,7 @@ CDummyWorld::CDummyWorld(ResId mlvlId, bool loadMap)
|
|||
: x4_loadMap(loadMap)
|
||||
{
|
||||
SObjectTag tag{FOURCC('MLVL'), mlvlId};
|
||||
g_ResFactory->LoadResourceAsync(tag, x34_loadBuf);
|
||||
static_cast<ProjectResourceFactoryBase*>(g_ResFactory)->LoadResourceAsync(tag, x34_loadBuf);
|
||||
}
|
||||
|
||||
ResId CDummyWorld::IGetWorldAssetId() const
|
||||
|
@ -198,7 +199,7 @@ CWorld::CWorld(IObjectStore& objStore, IFactory& resFactory, ResId mlvlId)
|
|||
: x60_objectStore(objStore), x64_resFactory(resFactory)
|
||||
{
|
||||
SObjectTag tag{FOURCC('MLVL'), mlvlId};
|
||||
resFactory.LoadResourceAsync(tag, x40_loadBuf);
|
||||
static_cast<ProjectResourceFactoryBase&>(resFactory).LoadResourceAsync(tag, x40_loadBuf);
|
||||
}
|
||||
|
||||
ResId CWorld::IGetWorldAssetId() const
|
||||
|
|
Loading…
Reference in New Issue