2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 22:27:41 +00:00

Much CModel work

This commit is contained in:
Jack Andersen
2016-03-30 16:44:43 -10:00
parent 0f22256d35
commit b373493cf3
17 changed files with 313 additions and 127 deletions

View File

@@ -300,5 +300,6 @@ void CGraphics::SetViewportResolution(const zeus::CVector2i& res)
boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr;
boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr;
boo::ITextureR* CGraphics::g_SpareTexture = nullptr;
hecl::Runtime::ShaderCacheManager* CGraphics::g_ShaderCacheMgr = nullptr;
}

View File

@@ -8,6 +8,8 @@
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
#include "hecl/Runtime.hpp"
namespace urde
{
class CLight;
@@ -212,14 +214,17 @@ public:
static boo::IGraphicsDataFactory* g_BooFactory;
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
static boo::ITextureR* g_SpareTexture;
static hecl::Runtime::ShaderCacheManager* g_ShaderCacheMgr;
static void InitializeBoo(boo::IGraphicsDataFactory* factory,
boo::IGraphicsCommandQueue* cc,
boo::ITextureR* spareTex)
boo::ITextureR* spareTex,
hecl::Runtime::ShaderCacheManager* shadCacheMgr)
{
g_BooFactory = factory;
g_BooMainCommandQueue = cc;
g_SpareTexture = spareTex;
g_ShaderCacheMgr = shadCacheMgr;
}
static boo::GraphicsDataToken CommitResources(const boo::FactoryCommitFunc& commitFunc)
@@ -243,6 +248,10 @@ public:
{
g_BooMainCommandQueue->draw(start, count);
}
static void DrawArrayIndexed(size_t start, size_t count)
{
g_BooMainCommandQueue->drawIndexed(start, count);
}
};
}

View File

@@ -6,6 +6,8 @@
#include "CFactoryMgr.hpp"
#include "CToken.hpp"
#include "zeus/CAABox.hpp"
#include "DNACommon/CMDL.hpp"
#include "DNAMP1/CMDLMaterials.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
@@ -22,69 +24,80 @@ struct CModelFlags
zeus::CColor color; /* Set into kcolor slot specified by material */
/* depth flags
0x4: render without texture lock
0x8: greater
0x10: non-inclusive
*/
};
class CBooSurface
/* urde addition: doesn't require hacky stashing of
* pointers within loaded CMDL buffer */
struct CBooSurface
{
DataSpec::DNACMDL::SurfaceHeader_1 m_data;
class CBooModel* m_parent = nullptr;
CBooSurface* m_next = nullptr;
};
class CBooModel
{
public:
/* urde addition: doesn't require hacky stashing of
* pointers within loaded CMDL buffer */
struct CSurfaceView
struct SShader
{
const u8* m_data;
CBooModel* m_parent = nullptr;
CSurfaceView* m_next = nullptr;
std::vector<TCachedToken<CTexture>> x0_textures;
std::vector<boo::IShaderPipeline*> m_shaders;
DataSpec::DNAMP1::HMDLMaterialSet m_matSet;
void UnlockTextures();
};
private:
std::vector<CSurfaceView>* x0_surfaces;
const u8* x4_matSet;
std::vector<CBooSurface>* x0_surfaces;
const DataSpec::DNAMP1::HMDLMaterialSet* x4_matSet;
const std::vector<boo::IShaderPipeline*>* m_pipelines;
boo::IVertexFormat* m_vtxFmt;
boo::IGraphicsBufferS* x8_vbo;
boo::IGraphicsBufferS* xc_ibo;
std::vector<TLockedToken<CTexture>>* x1c_textures;
std::vector<TCachedToken<CTexture>>* x1c_textures;
zeus::CAABox x20_aabb;
CSurfaceView* x38_firstUnsortedSurface = nullptr;
CSurfaceView* x3c_firstSortedSurface = nullptr;
bool x40_24_ : 1;
CBooSurface* x38_firstUnsortedSurface = nullptr;
CBooSurface* x3c_firstSortedSurface = nullptr;
bool x40_24_texturesLoaded : 1;
bool x40_25_ : 1;
u8 x41_shortNormals;
/* urde addition: boo! */
boo::GraphicsDataToken m_gfxToken;
boo::IGraphicsBufferD* m_uniformBuffer;
boo::IShaderDataBinding* m_shaderDataBinding;
std::vector<boo::IShaderDataBinding*> m_shaderDataBindings;
void DrawAlphaSurfaces(const CModelFlags& flags) const;
void DrawNormalSurfaces(const CModelFlags& flags) const;
void DrawSurfaces(const CModelFlags& flags) const;
void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
public:
CBooModel(std::vector<CSurfaceView>* surfaces,
std::vector<TLockedToken<CTexture>>* textures,
const u8* matSet,
boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
const zeus::CAABox& aabb,
u8 shortNormals, bool unk);
void BuildGfxToken();
static void MakeTexuresFromMats(const u8* dataIn,
std::vector<TLockedToken<CTexture>>& toksOut,
public:
CBooModel(std::vector<CBooSurface>* surfaces, SShader& shader,
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
const zeus::CAABox& aabb,
u8 shortNormals, bool texturesLoaded);
static void MakeTexuresFromMats(const DataSpec::DNAMP1::HMDLMaterialSet& matSet,
std::vector<TCachedToken<CTexture>>& toksOut,
IObjectStore& store);
void TryLockTextures() const;
void RemapMaterialData(SShader& shader);
bool TryLockTextures() const;
void UnlockTextures() const;
void DrawAlpha(const CModelFlags& flags) const;
void DrawNormal(const CModelFlags& flags) const;
void Draw(const CModelFlags& flags) const;
const u8* GetMaterialByIndex(int idx) const;
const DataSpec::DNAMP1::HMDLMaterialSet::Material& GetMaterialByIndex(int idx) const
{
return x4_matSet->materials.at(idx);
}
static bool g_DrawingOccluders;
static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;}
@@ -92,17 +105,10 @@ public:
class CModel
{
public:
struct SShader
{
std::vector<TLockedToken<CTexture>> x0_textures;
const u8* x10_data;
};
private:
std::unique_ptr<u8[]> x0_data;
u32 x4_dataLen;
std::vector<CBooModel::CSurfaceView> x8_surfaces;
std::vector<SShader> x18_matSets;
std::vector<CBooSurface> x8_surfaces;
std::vector<CBooModel::SShader> x18_matSets;
std::unique_ptr<CBooModel> x28_modelInst;
CModel* x30_next = nullptr;
CModel* x34_prev = nullptr;
@@ -111,12 +117,17 @@ private:
boo::GraphicsDataToken m_gfxToken;
boo::IGraphicsBufferS* m_vbo;
boo::IGraphicsBufferS* m_ibo;
boo::IVertexFormat* m_vtxFmt;
void VerifyCurrentShader(int shaderIdx) const;
public:
CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store);
void DrawSortedParts(const CModelFlags& flags) const;
void DrawUnsortedParts(const CModelFlags& flags) const;
void Draw(const CModelFlags& flags) const;
void Touch(int) const;
bool IsLoaded(int) const;
void Touch(int shaderIdx) const;
bool IsLoaded(int shaderIdx) const;
};
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,

View File

@@ -2,27 +2,36 @@
#include "Graphics/CTexture.hpp"
#include "Graphics/CGraphics.hpp"
#include "hecl/HMDLMeta.hpp"
#include "hecl/Runtime.hpp"
namespace urde
{
static logvisor::Module Log("urde::CModelBoo");
bool CBooModel::g_DrawingOccluders = false;
CBooModel::CBooModel(std::vector<CSurfaceView>* surfaces, std::vector<TLockedToken<CTexture>>* textures,
const u8* matSet, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, const zeus::CAABox& aabb,
u8 shortNormals, bool unk)
: x0_surfaces(surfaces), x4_matSet(matSet), x8_vbo(vbo), xc_ibo(ibo), x1c_textures(textures),
x20_aabb(aabb), x40_24_(unk), x40_25_(0), x41_shortNormals(shortNormals)
struct SUnskinnedUniforms
{
for (CSurfaceView& surf : *x0_surfaces)
zeus::CMatrix4f mv;
zeus::CMatrix4f mvinv;
zeus::CMatrix4f proj;
zeus::CMatrix4f tex[8];
};
CBooModel::CBooModel(std::vector<CBooSurface>* surfaces, SShader& shader,
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
const zeus::CAABox& aabb, u8 shortNormals, bool texturesLoaded)
: x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_pipelines(&shader.m_shaders),
m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), x1c_textures(&shader.x0_textures), x20_aabb(aabb),
x40_24_texturesLoaded(texturesLoaded), x40_25_(0), x41_shortNormals(shortNormals)
{
for (CBooSurface& surf : *x0_surfaces)
surf.m_parent = this;
for (auto it=x0_surfaces->rbegin() ; it != x0_surfaces->rend() ; ++it)
{
u32 matId = hecl::SBig(*reinterpret_cast<const u32*>(it->m_data + 0xc));
const u8* matData = GetMaterialByIndex(matId);
u32 matFlags = hecl::SBig(*reinterpret_cast<const u32*>(matData));
if (matFlags & 0x10)
u32 matId = it->m_data.matIdx;
const DataSpec::DNAMP1::HMDLMaterialSet::Material& matData = GetMaterialByIndex(matId);
if (matData.flags.depthSorting())
{
it->m_next = x3c_firstSortedSurface;
x3c_firstSortedSurface = &*it;
@@ -33,71 +42,152 @@ CBooModel::CBooModel(std::vector<CSurfaceView>* surfaces, std::vector<TLockedTok
x38_firstUnsortedSurface = &*it;
}
}
if (x40_24_texturesLoaded)
BuildGfxToken();
}
void CBooModel::MakeTexuresFromMats(const u8* dataIn,
std::vector<TLockedToken<CTexture>>& toksOut,
void CBooModel::BuildGfxToken()
{
m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SUnskinnedUniforms), 1);
boo::IGraphicsBuffer* bufs[] = {m_uniformBuffer};
m_shaderDataBindings.reserve(x4_matSet->materials.size());
auto pipelineIt = m_pipelines->begin();
std::vector<boo::ITexture*> texs;
for (const DataSpec::DNAMP1::HMDLMaterialSet::Material& mat : x4_matSet->materials)
{
texs.clear();
texs.reserve(mat.textureIdxs.size());
for (atUint32 idx : mat.textureIdxs)
{
TCachedToken<CTexture>& tex = (*x1c_textures)[idx];
texs.push_back(tex.GetObj()->GetBooTexture());
}
m_shaderDataBindings.push_back(ctx.newShaderDataBinding(*pipelineIt, m_vtxFmt, x8_vbo, nullptr, xc_ibo, 1, bufs,
mat.textureIdxs.size(), texs.data()));
++pipelineIt;
}
return true;
});
}
void CBooModel::MakeTexuresFromMats(const DataSpec::DNAMP1::HMDLMaterialSet& matSet,
std::vector<TCachedToken<CTexture>>& toksOut,
IObjectStore& store)
{
u32 texCount = hecl::SBig(*reinterpret_cast<const u32*>(dataIn));
dataIn += 4;
toksOut.reserve(texCount);
for (u32 i=0 ; i<texCount ; ++i)
{
u32 id = hecl::SBig(*reinterpret_cast<const u32*>(dataIn));
dataIn += 4;
toksOut.emplace_back(store.GetObj({SBIG('TXTR'), id}));
}
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::TryLockTextures() const
void CBooModel::RemapMaterialData(SShader& shader)
{
x4_matSet = &shader.m_matSet;
x1c_textures = &shader.x0_textures;
m_pipelines = &shader.m_shaders;
x40_24_texturesLoaded = false;
m_gfxToken.doDestroy();
}
bool CBooModel::TryLockTextures() const
{
if (!x40_24_texturesLoaded)
{
bool allLoad = true;
for (TCachedToken<CTexture>& tex : *x1c_textures)
{
tex.Lock();
if (!tex.IsLoaded())
allLoad = false;
}
if (allLoad)
((CBooModel*)this)->BuildGfxToken();
((CBooModel*)this)->x40_24_texturesLoaded = allLoad;
}
return x40_24_texturesLoaded;
}
void CBooModel::UnlockTextures() const
{
for (TCachedToken<CTexture>& tex : *x1c_textures)
tex.Unlock();
((CBooModel*)this)->x40_24_texturesLoaded = false;
}
void CBooModel::DrawAlphaSurfaces(const CModelFlags& flags) const
{
if (TryLockTextures())
{
const CBooSurface* surf = x3c_firstSortedSurface;
while (surf)
{
DrawSurface(*surf, flags);
surf = surf->m_next;
}
}
}
void CBooModel::DrawNormalSurfaces(const CModelFlags& flags) const
{
if (TryLockTextures())
{
const CBooSurface* surf = x38_firstUnsortedSurface;
while (surf)
{
DrawSurface(*surf, flags);
surf = surf->m_next;
}
}
}
void CBooModel::DrawSurfaces(const CModelFlags& flags) const
{
if (!(flags.f3 & 0x4))
if (!TryLockTextures())
return;
const CBooSurface* surf = x38_firstUnsortedSurface;
while (surf)
{
DrawSurface(*surf, flags);
surf = surf->m_next;
}
surf = x3c_firstSortedSurface;
while (surf)
{
DrawSurface(*surf, flags);
surf = surf->m_next;
}
}
void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const
{
const DataSpec::DNAMP1::HMDLMaterialSet::Material& data = GetMaterialByIndex(surf.m_data.matIdx);
if (data.flags.shadowOccluderMesh() && !g_DrawingOccluders)
return;
CGraphics::SetShaderDataBinding(m_shaderDataBindings[surf.m_data.matIdx]);
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, surf.m_data.idxCount);
}
void CBooModel::DrawAlpha(const CModelFlags& flags) const
{
DrawAlphaSurfaces(flags);
}
void CBooModel::DrawNormal(const CModelFlags& flags) const
{
DrawNormalSurfaces(flags);
}
void CBooModel::Draw(const CModelFlags& flags) const
{
}
const u8* CBooModel::GetMaterialByIndex(int idx) const
{
const u32* matOffs = reinterpret_cast<const u32*>(x4_matSet + (x1c_textures->size() + 1) * 4);
u32 matCount = hecl::SBig(*matOffs);
++matOffs;
const u8* materialBase = reinterpret_cast<const u8*>(matOffs + matCount);
if (idx == 0)
return materialBase;
u32 offset = hecl::SBig(matOffs[idx-1]);
return materialBase + offset;
DrawSurfaces(flags);
}
static const u8* MemoryFromPartData(const u8*& dataCur, const s32*& secSizeCur)
@@ -128,17 +218,20 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
const s32* secSizeCur = reinterpret_cast<const s32*>(x0_data.get() + 0x2c);
for (u32 i=0 ; i<matSetCount ; ++i)
{
u32 matSetSz = hecl::SBig(*secSizeCur);
const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
x18_matSets.emplace_back();
SShader& shader = x18_matSets.back();
shader.x10_data = sec;
CBooModel::MakeTexuresFromMats(sec, shader.x0_textures, *store);
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);
}
hecl::HMDLMeta hmdlMeta;
{
u32 hmdlSz = hecl::SBig(*secSizeCur);
const u8* hmdlMetadata = MemoryFromPartData(dataCur, secSizeCur);
athena::io::MemoryReader r(hmdlMetadata, *secSizeCur);
athena::io::MemoryReader r(hmdlMetadata, hmdlSz);
hmdlMeta.read(r);
}
@@ -150,6 +243,20 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
{
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vboData, hmdlMeta.vertStride, hmdlMeta.vertCount);
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, iboData, 4, hmdlMeta.indexCount);
m_vtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, hmdlMeta, m_vbo, m_ibo);
for (CBooModel::SShader& matSet : x18_matSets)
{
matSet.m_shaders.reserve(matSet.m_matSet.materials.size());
for (const DataSpec::DNAMP1::HMDLMaterialSet::Material& mat : matSet.m_matSet.materials)
{
hecl::Runtime::ShaderTag tag(mat.heclIr,
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
0, mat.uvAnims.size(), true, true, true);
matSet.m_shaders.push_back(CGraphics::g_ShaderCacheMgr->buildShader(tag, mat.heclIr, "CMDL", ctx));
}
}
return true;
});
@@ -157,30 +264,55 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
x8_surfaces.reserve(surfCount);
for (u32 i=0 ; i<surfCount ; ++i)
{
u32 surfSz = hecl::SBig(*secSizeCur);
const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
x8_surfaces.emplace_back();
CBooModel::CSurfaceView& surf = x8_surfaces.back();
surf.m_data = sec;
CBooSurface& surf = x8_surfaces.back();
athena::io::MemoryReader r(sec, surfSz);
surf.m_data.read(r);
}
const float* aabbPtr = reinterpret_cast<const float*>(x0_data.get() + 0x18);
zeus::CAABox aabb(hecl::SBig(aabbPtr[0]), hecl::SBig(aabbPtr[1]), hecl::SBig(aabbPtr[2]),
hecl::SBig(aabbPtr[3]), hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
x28_modelInst = std::make_unique<CBooModel>(&x8_surfaces, &x18_matSets[0].x0_textures,
x18_matSets[0].x10_data, m_vbo, m_ibo,
x28_modelInst = std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[0],
m_vtxFmt, m_vbo, m_ibo,
aabb, flags & 0x2, true);
}
void CBooModel::SShader::UnlockTextures()
{
for (TCachedToken<CTexture>& tex : x0_textures)
tex.Unlock();
}
void CModel::VerifyCurrentShader(int shaderIdx) const
{
int idx = 0;
for (const CBooModel::SShader& shader : x18_matSets)
if (idx++ != shaderIdx)
((CBooModel::SShader&)shader).UnlockTextures();
}
void CModel::DrawSortedParts(const CModelFlags& flags) const
{
}
void CModel::DrawUnsortedParts(const CModelFlags& flags) const
{
}
void CModel::Draw(const CModelFlags& flags) const
{
}
void CModel::Touch(int) const
void CModel::Touch(int shaderIdx) const
{
}
bool CModel::IsLoaded(int) const
bool CModel::IsLoaded(int shaderIdx) const
{
VerifyCurrentShader(shaderIdx);
return false;
}

View File

@@ -44,7 +44,7 @@ public:
ETexelFormat GetTexelFormat() const {return x0_fmt;}
u16 GetWidth() const {return x4_w;}
u16 GetHeight() const {return x6_h;}
void Load(int slot, EClampMode clamp);
void Load(int slot, EClampMode clamp) const;
boo::ITexture* GetBooTexture() {return m_booTex;}
};

View File

@@ -692,7 +692,7 @@ CTexture::CTexture(CInputStream& in)
}
}
void CTexture::Load(int slot, EClampMode clamp)
void CTexture::Load(int slot, EClampMode clamp) const
{
}