mirror of https://github.com/AxioDL/metaforce.git
Async resource build fixes
This commit is contained in:
parent
bc6ba1141d
commit
9fcce94a7a
|
@ -436,6 +436,46 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
||||||
}
|
}
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
|
|
||||||
|
auto asyncSearch = m_asyncLoadList.find(tag);
|
||||||
|
if (asyncSearch != m_asyncLoadList.end())
|
||||||
|
{
|
||||||
|
/* Async spinloop */
|
||||||
|
AsyncTask& task = asyncSearch->second;
|
||||||
|
task.EnsurePath(task.x0_tag, search->second);
|
||||||
|
|
||||||
|
/* Pump load pipeline (cooking if needed) */
|
||||||
|
while (!task.AsyncPump()) {std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
||||||
|
|
||||||
|
if (task.m_complete)
|
||||||
|
{
|
||||||
|
/* Load complete, build resource */
|
||||||
|
std::unique_ptr<IObj> newObj;
|
||||||
|
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
|
||||||
|
{
|
||||||
|
newObj = m_factoryMgr.MakeObjectFromMemory(tag, std::move(task.x10_loadBuffer),
|
||||||
|
task.x14_resSize, false, task.x18_cvXfer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
||||||
|
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
*task.xc_targetPtr = newObj.get();
|
||||||
|
Log.report(logvisor::Warning, "spin-built %.4s %08X",
|
||||||
|
task.x0_tag.type.toString().c_str(),
|
||||||
|
u32(task.x0_tag.id));
|
||||||
|
m_asyncLoadList.erase(asyncSearch);
|
||||||
|
return newObj;
|
||||||
|
}
|
||||||
|
Log.report(logvisor::Error, "unable to spin-build %.4s %08X",
|
||||||
|
task.x0_tag.type.toString().c_str(),
|
||||||
|
u32(task.x0_tag.id));
|
||||||
|
m_asyncLoadList.erase(asyncSearch);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fall-back to sync build */
|
||||||
return BuildSync(tag, search->second, paramXfer);
|
return BuildSync(tag, search->second, paramXfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,8 +585,22 @@ void ProjectResourceFactoryBase::AsyncIdle()
|
||||||
if (task.m_complete)
|
if (task.m_complete)
|
||||||
{
|
{
|
||||||
/* Load complete, build resource */
|
/* Load complete, build resource */
|
||||||
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
std::unique_ptr<IObj> newObj;
|
||||||
*task.xc_targetPtr = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer).release();
|
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
|
||||||
|
{
|
||||||
|
newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer),
|
||||||
|
task.x14_resSize, false, task.x18_cvXfer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
||||||
|
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
*task.xc_targetPtr = newObj.release();
|
||||||
|
Log.report(logvisor::Info, "async-built %.4s %08X",
|
||||||
|
task.x0_tag.type.toString().c_str(),
|
||||||
|
u32(task.x0_tag.id));
|
||||||
}
|
}
|
||||||
it = m_asyncLoadList.erase(it);
|
it = m_asyncLoadList.erase(it);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace urde
|
||||||
ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc)
|
ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc)
|
||||||
: ProjectResourceFactoryBase(clientProc)
|
: ProjectResourceFactoryBase(clientProc)
|
||||||
{
|
{
|
||||||
m_factoryMgr.AddFactory(FOURCC('TXTR'), FFactoryFunc(FTextureFactory));
|
m_factoryMgr.AddFactory(FOURCC('TXTR'), FMemFactoryFunc(FTextureFactory));
|
||||||
m_factoryMgr.AddFactory(FOURCC('PART'), FFactoryFunc(FParticleFactory));
|
m_factoryMgr.AddFactory(FOURCC('PART'), FFactoryFunc(FParticleFactory));
|
||||||
m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame));
|
m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame));
|
||||||
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
|
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace urde
|
||||||
void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
|
void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
|
||||||
{
|
{
|
||||||
m_modelTest = objStore.GetObj("CMDL_GameCube");
|
m_modelTest = objStore.GetObj("CMDL_GameCube");
|
||||||
|
m_modelTest.Lock();
|
||||||
|
|
||||||
//m_partGenDesc = objStore.GetObj({hecl::FOURCC('PART'), 0x972A5CD2});
|
//m_partGenDesc = objStore.GetObj({hecl::FOURCC('PART'), 0x972A5CD2});
|
||||||
m_partGenDesc = objStore.GetObj("BusterSparks");
|
m_partGenDesc = objStore.GetObj("BusterSparks");
|
||||||
|
@ -58,9 +59,16 @@ void ViewManager::ParticleView::resized(const boo::SWindowRect& root, const boo:
|
||||||
|
|
||||||
void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
||||||
{
|
{
|
||||||
if (m_vm.m_modelTest)
|
if (m_vm.m_modelTest.IsLoaded())
|
||||||
{
|
{
|
||||||
CModelFlags flags;
|
CModelFlags flags;
|
||||||
|
|
||||||
|
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||||
|
CGraphics::SetViewPointMatrix(zeus::CTransform::Identity() + zeus::CVector3f(0.f, -10.f, 0.f));
|
||||||
|
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||||
|
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||||
|
CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||||
|
|
||||||
m_vm.m_modelTest->Draw(flags);
|
m_vm.m_modelTest->Draw(flags);
|
||||||
}
|
}
|
||||||
if (m_vm.m_partGen)
|
if (m_vm.m_partGen)
|
||||||
|
@ -70,11 +78,11 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
||||||
if (m_vm.m_partGen->IsSystemDeletable())
|
if (m_vm.m_partGen->IsSystemDeletable())
|
||||||
m_vm.m_partGen->Reset();
|
m_vm.m_partGen->Reset();
|
||||||
|
|
||||||
urde::CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||||
urde::CGraphics::SetViewPointMatrix(zeus::CTransform::Identity() + zeus::CVector3f(0.f, -10.f, 0.f));
|
CGraphics::SetViewPointMatrix(zeus::CTransform::Identity() + zeus::CVector3f(0.f, -10.f, 0.f));
|
||||||
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||||
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||||
urde::CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||||
//gfxQ->clearTarget(false, true);
|
//gfxQ->clearTarget(false, true);
|
||||||
m_vm.m_partGen->Render();
|
m_vm.m_partGen->Render();
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@ class ViewManager : public specter::IViewManager
|
||||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||||
};
|
};
|
||||||
std::unique_ptr<ParticleView> m_particleView;
|
std::unique_ptr<ParticleView> m_particleView;
|
||||||
urde::TLockedToken<CModel> m_modelTest;
|
urde::TCachedToken<CModel> m_modelTest;
|
||||||
urde::TLockedToken<CGenDescription> m_partGenDesc;
|
urde::TCachedToken<CGenDescription> m_partGenDesc;
|
||||||
std::unique_ptr<CElementGen> m_partGen;
|
std::unique_ptr<CElementGen> m_partGen;
|
||||||
std::unique_ptr<CLineRenderer> m_lineRenderer;
|
std::unique_ptr<CLineRenderer> m_lineRenderer;
|
||||||
std::unique_ptr<CMoviePlayer> m_moviePlayer;
|
std::unique_ptr<CMoviePlayer> m_moviePlayer;
|
||||||
|
|
|
@ -19,16 +19,10 @@ CToken CSimplePool::GetObj(const SObjectTag& tag, const CVParamTransfer& paramXf
|
||||||
|
|
||||||
if (iter != x4_resources.end())
|
if (iter != x4_resources.end())
|
||||||
return CToken(iter->second);
|
return CToken(iter->second);
|
||||||
// TODO: There is some logic missing here, need to figure out what it's doing
|
|
||||||
CObjectReference* ret = new CObjectReference(*this, x30_factory.Build(tag, paramXfer), tag, paramXfer);
|
|
||||||
if (ret->GetObject())
|
|
||||||
{
|
|
||||||
x4_resources.push_back(std::make_pair<SObjectTag, CObjectReference*>((SObjectTag)tag, std::move(ret)));
|
|
||||||
return CToken(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete ret;
|
CObjectReference* ret = new CObjectReference(*this, std::unique_ptr<IObj>(), tag, paramXfer);
|
||||||
return CToken();
|
x4_resources.push_back(std::make_pair<SObjectTag, CObjectReference*>((SObjectTag)tag, std::move(ret)));
|
||||||
|
return CToken(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
CToken CSimplePool::GetObj(const SObjectTag& tag)
|
CToken CSimplePool::GetObj(const SObjectTag& tag)
|
||||||
|
|
|
@ -16,6 +16,7 @@ class IObjectStore;
|
||||||
class CObjectReference
|
class CObjectReference
|
||||||
{
|
{
|
||||||
friend class CToken;
|
friend class CToken;
|
||||||
|
friend class CSimplePool;
|
||||||
u16 x0_refCount = 0;
|
u16 x0_refCount = 0;
|
||||||
u16 x2_lockCount = 0;
|
u16 x2_lockCount = 0;
|
||||||
bool x3_loading = false; /* Rightmost bit of lockCount */
|
bool x3_loading = false; /* Rightmost bit of lockCount */
|
||||||
|
@ -23,7 +24,23 @@ class CObjectReference
|
||||||
IObjectStore* xC_objectStore = nullptr;
|
IObjectStore* xC_objectStore = nullptr;
|
||||||
IObj* x10_object = nullptr;
|
IObj* x10_object = nullptr;
|
||||||
CVParamTransfer x14_params;
|
CVParamTransfer x14_params;
|
||||||
public:
|
|
||||||
|
/** Mechanism by which CToken decrements 1st ref-count, indicating CToken invalidation or reset.
|
||||||
|
* Reaching 0 indicates the CToken should delete the CObjectReference */
|
||||||
|
u16 RemoveReference()
|
||||||
|
{
|
||||||
|
--x0_refCount;
|
||||||
|
if (x0_refCount == 0)
|
||||||
|
{
|
||||||
|
if (x10_object)
|
||||||
|
Unload();
|
||||||
|
if (IsLoading())
|
||||||
|
CancelLoad();
|
||||||
|
xC_objectStore->ObjectUnreferenced(x4_objTag);
|
||||||
|
}
|
||||||
|
return x0_refCount;
|
||||||
|
}
|
||||||
|
|
||||||
CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj,
|
CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj,
|
||||||
const SObjectTag& objTag, CVParamTransfer buildParams)
|
const SObjectTag& objTag, CVParamTransfer buildParams)
|
||||||
: x4_objTag(objTag), xC_objectStore(&objStore),
|
: x4_objTag(objTag), xC_objectStore(&objStore),
|
||||||
|
@ -61,21 +78,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mechanism by which CToken decrements 1st ref-count, indicating CToken invalidation or reset.
|
|
||||||
* Reaching 0 indicates the CToken should delete the CObjectReference */
|
|
||||||
u16 RemoveReference()
|
|
||||||
{
|
|
||||||
--x0_refCount;
|
|
||||||
if (x0_refCount == 0)
|
|
||||||
{
|
|
||||||
if (x10_object)
|
|
||||||
Unload();
|
|
||||||
if (IsLoading())
|
|
||||||
CancelLoad();
|
|
||||||
xC_objectStore->ObjectUnreferenced(x4_objTag);
|
|
||||||
}
|
|
||||||
return x0_refCount;
|
|
||||||
}
|
|
||||||
void CancelLoad()
|
void CancelLoad()
|
||||||
{
|
{
|
||||||
if (xC_objectStore && IsLoading())
|
if (xC_objectStore && IsLoading())
|
||||||
|
@ -108,6 +110,8 @@ public:
|
||||||
{
|
{
|
||||||
return x4_objTag;
|
return x4_objTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
~CObjectReference()
|
~CObjectReference()
|
||||||
{
|
{
|
||||||
if (x10_object)
|
if (x10_object)
|
||||||
|
@ -122,8 +126,25 @@ public:
|
||||||
* (default/empty constructor, move constructor/assign) */
|
* (default/empty constructor, move constructor/assign) */
|
||||||
class CToken
|
class CToken
|
||||||
{
|
{
|
||||||
|
friend class CSimplePool;
|
||||||
CObjectReference* x0_objRef = nullptr;
|
CObjectReference* x0_objRef = nullptr;
|
||||||
bool x4_lockHeld = false;
|
bool x4_lockHeld = false;
|
||||||
|
|
||||||
|
void RemoveRef()
|
||||||
|
{
|
||||||
|
if (x0_objRef && x0_objRef->RemoveReference() == 0)
|
||||||
|
{
|
||||||
|
std::default_delete<CObjectReference>()(x0_objRef);
|
||||||
|
x0_objRef = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CToken(CObjectReference* obj)
|
||||||
|
{
|
||||||
|
x0_objRef = obj;
|
||||||
|
++x0_objRef->x0_refCount;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Added to test for non-null state */
|
/* Added to test for non-null state */
|
||||||
operator bool() const {return x0_objRef != nullptr;}
|
operator bool() const {return x0_objRef != nullptr;}
|
||||||
|
@ -150,14 +171,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
return x0_objRef->IsLoaded();
|
return x0_objRef->IsLoaded();
|
||||||
}
|
}
|
||||||
void RemoveRef()
|
|
||||||
{
|
|
||||||
if (x0_objRef && x0_objRef->RemoveReference() == 0)
|
|
||||||
{
|
|
||||||
std::default_delete<CObjectReference>()(x0_objRef);
|
|
||||||
x0_objRef = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IObj* GetObj()
|
IObj* GetObj()
|
||||||
{
|
{
|
||||||
if (!x0_objRef)
|
if (!x0_objRef)
|
||||||
|
@ -217,11 +230,6 @@ public:
|
||||||
++x0_objRef->x0_refCount;
|
++x0_objRef->x0_refCount;
|
||||||
Lock();
|
Lock();
|
||||||
}
|
}
|
||||||
CToken(CObjectReference* obj)
|
|
||||||
{
|
|
||||||
x0_objRef = obj;
|
|
||||||
++x0_objRef->x0_refCount;
|
|
||||||
}
|
|
||||||
const SObjectTag* GetObjectTag() const
|
const SObjectTag* GetObjectTag() const
|
||||||
{
|
{
|
||||||
if (!x0_objRef)
|
if (!x0_objRef)
|
||||||
|
|
|
@ -156,6 +156,7 @@ zeus::CMatrix4f CGraphics::CalculatePerspectiveMatrix(float fovy, float aspect,
|
||||||
|
|
||||||
zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix()
|
zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix()
|
||||||
{
|
{
|
||||||
|
CProjectionState& ref = g_Proj;
|
||||||
float rml = g_Proj.x8_right - g_Proj.x4_left;
|
float rml = g_Proj.x8_right - g_Proj.x4_left;
|
||||||
float rpl = g_Proj.x8_right + g_Proj.x4_left;
|
float rpl = g_Proj.x8_right + g_Proj.x4_left;
|
||||||
float tmb = g_Proj.xc_top - g_Proj.x10_bottom;
|
float tmb = g_Proj.xc_top - g_Proj.x10_bottom;
|
||||||
|
|
|
@ -117,36 +117,26 @@ void CBooModel::UnlockTextures() const
|
||||||
|
|
||||||
void CBooModel::DrawAlphaSurfaces(const CModelFlags& flags) const
|
void CBooModel::DrawAlphaSurfaces(const CModelFlags& flags) const
|
||||||
{
|
{
|
||||||
if (TryLockTextures())
|
const CBooSurface* surf = x3c_firstSortedSurface;
|
||||||
|
while (surf)
|
||||||
{
|
{
|
||||||
const CBooSurface* surf = x3c_firstSortedSurface;
|
DrawSurface(*surf, flags);
|
||||||
while (surf)
|
surf = surf->m_next;
|
||||||
{
|
|
||||||
DrawSurface(*surf, flags);
|
|
||||||
surf = surf->m_next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::DrawNormalSurfaces(const CModelFlags& flags) const
|
void CBooModel::DrawNormalSurfaces(const CModelFlags& flags) const
|
||||||
{
|
{
|
||||||
if (TryLockTextures())
|
const CBooSurface* surf = x38_firstUnsortedSurface;
|
||||||
|
while (surf)
|
||||||
{
|
{
|
||||||
const CBooSurface* surf = x38_firstUnsortedSurface;
|
DrawSurface(*surf, flags);
|
||||||
while (surf)
|
surf = surf->m_next;
|
||||||
{
|
|
||||||
DrawSurface(*surf, flags);
|
|
||||||
surf = surf->m_next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::DrawSurfaces(const CModelFlags& flags) const
|
void CBooModel::DrawSurfaces(const CModelFlags& flags) const
|
||||||
{
|
{
|
||||||
if (!(flags.m_flags & 0x4))
|
|
||||||
if (!TryLockTextures())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const CBooSurface* surf = x38_firstUnsortedSurface;
|
const CBooSurface* surf = x38_firstUnsortedSurface;
|
||||||
while (surf)
|
while (surf)
|
||||||
{
|
{
|
||||||
|
@ -300,20 +290,29 @@ void CBooModel::UpdateUniformData() const
|
||||||
|
|
||||||
void CBooModel::DrawAlpha(const CModelFlags& flags) const
|
void CBooModel::DrawAlpha(const CModelFlags& flags) const
|
||||||
{
|
{
|
||||||
UpdateUniformData();
|
if (TryLockTextures())
|
||||||
DrawAlphaSurfaces(flags);
|
{
|
||||||
|
UpdateUniformData();
|
||||||
|
DrawAlphaSurfaces(flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::DrawNormal(const CModelFlags& flags) const
|
void CBooModel::DrawNormal(const CModelFlags& flags) const
|
||||||
{
|
{
|
||||||
UpdateUniformData();
|
if (TryLockTextures())
|
||||||
DrawNormalSurfaces(flags);
|
{
|
||||||
|
UpdateUniformData();
|
||||||
|
DrawNormalSurfaces(flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::Draw(const CModelFlags& flags) const
|
void CBooModel::Draw(const CModelFlags& flags) const
|
||||||
{
|
{
|
||||||
UpdateUniformData();
|
if (TryLockTextures())
|
||||||
DrawSurfaces(flags);
|
{
|
||||||
|
UpdateUniformData();
|
||||||
|
DrawSurfaces(flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u8* MemoryFromPartData(const u8*& dataCur, const s32*& secSizeCur)
|
static const u8* MemoryFromPartData(const u8*& dataCur, const s32*& secSizeCur)
|
||||||
|
@ -378,7 +377,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
||||||
{
|
{
|
||||||
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
||||||
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
|
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
|
||||||
0, mat.uvAnims.size(), true, true, true);
|
0, mat.uvAnims.size(), false, false, true);
|
||||||
matSet.m_shaders.push_back(CGraphics::g_ShaderCacheMgr->buildShader(tag, mat.heclIr, "CMDL", ctx));
|
matSet.m_shaders.push_back(CGraphics::g_ShaderCacheMgr->buildShader(tag, mat.heclIr, "CMDL", ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,7 +402,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
||||||
hecl::SBig(aabbPtr[3]), hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
hecl::SBig(aabbPtr[3]), hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
||||||
x28_modelInst = std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[0],
|
x28_modelInst = std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[0],
|
||||||
m_vtxFmt, m_vbo, m_ibo,
|
m_vtxFmt, m_vbo, m_ibo,
|
||||||
aabb, flags & 0x2, true);
|
aabb, flags & 0x2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::SShader::UnlockTextures()
|
void CBooModel::SShader::UnlockTextures()
|
||||||
|
@ -465,7 +464,8 @@ CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
||||||
const urde::CVParamTransfer& vparms)
|
const urde::CVParamTransfer& vparms)
|
||||||
{
|
{
|
||||||
IObjectStore* store = static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam();
|
IObjectStore* store = static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam();
|
||||||
return TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store));
|
CFactoryFnReturn ret = TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store));
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,10 @@ class CTexture
|
||||||
void BuildRGB5A3FromGCN(CInputStream& in);
|
void BuildRGB5A3FromGCN(CInputStream& in);
|
||||||
void BuildRGBA8FromGCN(CInputStream& in);
|
void BuildRGBA8FromGCN(CInputStream& in);
|
||||||
void BuildDXT1FromGCN(CInputStream& in);
|
void BuildDXT1FromGCN(CInputStream& in);
|
||||||
void BuildRGBA8(CInputStream& in);
|
void BuildRGBA8(const void* data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTexture(CInputStream& in);
|
CTexture(std::unique_ptr<u8[]>&& in, u32 length);
|
||||||
enum class EClampMode
|
enum class EClampMode
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
@ -50,7 +50,9 @@ public:
|
||||||
boo::ITexture* GetBooTexture() {return m_booTex;}
|
boo::ITexture* GetBooTexture() {return m_booTex;}
|
||||||
};
|
};
|
||||||
|
|
||||||
CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
|
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
|
||||||
|
std::unique_ptr<u8[]>&& in, u32 len,
|
||||||
|
const urde::CVParamTransfer& vparms);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -648,63 +648,64 @@ void CTexture::BuildDXT1FromGCN(CInputStream& in)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTexture::BuildRGBA8(CInputStream& in)
|
void CTexture::BuildRGBA8(const void* data)
|
||||||
{
|
{
|
||||||
size_t texelCount = ComputeMippedTexelCount();
|
size_t texelCount = ComputeMippedTexelCount();
|
||||||
std::unique_ptr<atInt8[]> buf = in.readBytes(texelCount * 4);
|
|
||||||
|
|
||||||
m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8,
|
m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8,
|
||||||
buf.get(), texelCount * 4);
|
data, texelCount * 4);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CTexture::CTexture(CInputStream& in)
|
CTexture::CTexture(std::unique_ptr<u8[]>&& in, u32 length)
|
||||||
{
|
{
|
||||||
x0_fmt = ETexelFormat(in.readUint32Big());
|
std::unique_ptr<u8[]> owned = std::move(in);
|
||||||
x4_w = in.readUint16Big();
|
athena::io::MemoryReader r(owned.get(), length);
|
||||||
x6_h = in.readUint16Big();
|
x0_fmt = ETexelFormat(r.readUint32Big());
|
||||||
x8_mips = in.readUint32Big();
|
x4_w = r.readUint16Big();
|
||||||
|
x6_h = r.readUint16Big();
|
||||||
|
x8_mips = r.readUint32Big();
|
||||||
|
|
||||||
switch (x0_fmt)
|
switch (x0_fmt)
|
||||||
{
|
{
|
||||||
case ETexelFormat::I4:
|
case ETexelFormat::I4:
|
||||||
BuildI4FromGCN(in);
|
BuildI4FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::I8:
|
case ETexelFormat::I8:
|
||||||
BuildI8FromGCN(in);
|
BuildI8FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::IA4:
|
case ETexelFormat::IA4:
|
||||||
BuildIA4FromGCN(in);
|
BuildIA4FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::IA8:
|
case ETexelFormat::IA8:
|
||||||
BuildIA8FromGCN(in);
|
BuildIA8FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::C4:
|
case ETexelFormat::C4:
|
||||||
BuildC4FromGCN(in);
|
BuildC4FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::C8:
|
case ETexelFormat::C8:
|
||||||
BuildC8FromGCN(in);
|
BuildC8FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::C14X2:
|
case ETexelFormat::C14X2:
|
||||||
BuildC14X2FromGCN(in);
|
BuildC14X2FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::RGB565:
|
case ETexelFormat::RGB565:
|
||||||
BuildRGB565FromGCN(in);
|
BuildRGB565FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::RGB5A3:
|
case ETexelFormat::RGB5A3:
|
||||||
BuildRGB5A3FromGCN(in);
|
BuildRGB5A3FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::RGBA8:
|
case ETexelFormat::RGBA8:
|
||||||
BuildRGBA8FromGCN(in);
|
BuildRGBA8FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::CMPR:
|
case ETexelFormat::CMPR:
|
||||||
BuildDXT1FromGCN(in);
|
BuildDXT1FromGCN(r);
|
||||||
break;
|
break;
|
||||||
case ETexelFormat::RGBA8PC:
|
case ETexelFormat::RGBA8PC:
|
||||||
BuildRGBA8(in);
|
BuildRGBA8(owned.get() + 12);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Fatal, "invalid texture type %d for boo", int(x0_fmt));
|
Log.report(logvisor::Fatal, "invalid texture type %d for boo", int(x0_fmt));
|
||||||
|
@ -716,9 +717,11 @@ void CTexture::Load(int slot, EClampMode clamp) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms)
|
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
|
||||||
|
std::unique_ptr<u8[]>&& in, u32 len,
|
||||||
|
const urde::CVParamTransfer& vparms)
|
||||||
{
|
{
|
||||||
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(in));
|
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(std::move(in), len));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue