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

@ -1613,8 +1613,8 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
header.centroid = osurf.centroid; header.centroid = osurf.centroid;
header.matIdx = osurf.materialIdx; header.matIdx = osurf.materialIdx;
header.reflectionNormal = osurf.reflectionNormal; header.reflectionNormal = osurf.reflectionNormal;
header.unk1 = surf.m_start; header.idxStart = surf.m_start;
header.unk2 = surf.m_count; header.idxCount = surf.m_count;
header.write(writer); header.write(writer);
writer.fill(atUint8(0), *padIt); writer.fill(atUint8(0), *padIt);

View File

@ -45,8 +45,8 @@ struct SurfaceHeader_1 : BigDNA
Value<atUint32> matIdx = 0; Value<atUint32> matIdx = 0;
Value<atUint16> qDiv = 0x8000; Value<atUint16> qDiv = 0x8000;
Value<atUint16> dlSize = 0; Value<atUint16> dlSize = 0;
Value<atUint32> unk1 = 0; Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */
Value<atUint32> unk2 = 0; Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */
Value<atUint32> aabbSz = 0; Value<atUint32> aabbSz = 0;
Value<atVec3f> reflectionNormal; Value<atVec3f> reflectionNormal;
Seek<DNA_COUNT(aabbSz), athena::Current> seek2; Seek<DNA_COUNT(aabbSz), athena::Current> seek2;
@ -63,8 +63,8 @@ struct SurfaceHeader_2 : BigDNA
Value<atUint32> matIdx = 0; Value<atUint32> matIdx = 0;
Value<atUint16> qDiv = 0x8000; Value<atUint16> qDiv = 0x8000;
Value<atUint16> dlSize = 0; Value<atUint16> dlSize = 0;
Value<atUint32> unk1 = 0; Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */
Value<atUint32> unk2 = 0; Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */
Value<atUint32> aabbSz = 0; Value<atUint32> aabbSz = 0;
Value<atVec3f> reflectionNormal; Value<atVec3f> reflectionNormal;
Value<atInt16> skinMtxBankIdx; Value<atInt16> skinMtxBankIdx;
@ -83,8 +83,8 @@ struct SurfaceHeader_3 : BigDNA
Value<atUint32> matIdx = 0; Value<atUint32> matIdx = 0;
Value<atUint16> qDiv = 0x8000; Value<atUint16> qDiv = 0x8000;
Value<atUint16> dlSize = 0; Value<atUint16> dlSize = 0;
Value<atUint32> unk1 = 0; Value<atUint32> idxStart = 0; /* Actually used by game to stash CCubeModel pointer */
Value<atUint32> unk2 = 0; Value<atUint32> idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */
Value<atUint32> aabbSz = 0; Value<atUint32> aabbSz = 0;
Value<atVec3f> reflectionNormal; Value<atVec3f> reflectionNormal;
Value<atInt16> skinMtxBankIdx; Value<atInt16> skinMtxBankIdx;

View File

@ -1,4 +1,4 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ./../Runtime) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/DataSpec ${CMAKE_SOURCE_DIR}/Runtime)
add_subdirectory(locale) add_subdirectory(locale)
add_subdirectory(icons) add_subdirectory(icons)
@ -47,8 +47,8 @@ target_link_libraries(urde
RuntimeCommon RuntimeCommon
DNAMP3 DNAMP2 DNAMP1 DNAMP3 DNAMP2 DNAMP1
DNACommon specter specter-fonts freetype ${DATA_SPEC_LIBS} DNACommon specter specter-fonts freetype ${DATA_SPEC_LIBS}
hecl-database hecl-backend hecl-frontend hecl-blender hecl-runtime hecl-common athena-core nod hecl-database hecl-runtime hecl-backend hecl-frontend hecl-hmdl hecl-blender hecl-common
logvisor athena-libyaml boo ${PNG_LIB} libjpeg-turbo squish xxhash zeus athena-core nod logvisor athena-libyaml boo ${PNG_LIB} libjpeg-turbo squish xxhash zeus
${ZLIB_LIBRARIES} ${LZO_LIB} ${ZLIB_LIBRARIES} ${LZO_LIB}
${BOO_SYS_LIBS}) ${BOO_SYS_LIBS})

View File

@ -24,11 +24,11 @@ namespace urde
ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc) ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc)
: ProjectResourceFactoryBase(clientProc) : ProjectResourceFactoryBase(clientProc)
{ {
m_factoryMgr.AddFactory(FOURCC('TXTR'), FFactoryFunc(urde::FTextureFactory)); m_factoryMgr.AddFactory(FOURCC('TXTR'), FFactoryFunc(FTextureFactory));
m_factoryMgr.AddFactory(FOURCC('PART'), FFactoryFunc(urde::FParticleFactory)); m_factoryMgr.AddFactory(FOURCC('PART'), FFactoryFunc(FParticleFactory));
m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(urde::RGuiFrameFactoryInGame)); m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame));
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(urde::FRasterFontFactory)); m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
m_factoryMgr.AddFactory(FOURCC('CMDL'), FMemFactoryFunc(urde::FModelFactory)); m_factoryMgr.AddFactory(FOURCC('CMDL'), FMemFactoryFunc(FModelFactory));
} }
void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj) void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj)

View File

@ -245,6 +245,7 @@ void ViewManager::init(boo::IApplication* app)
float pixelFactor = 1.0; float pixelFactor = 1.0;
boo::IGraphicsDataFactory* gf = m_mainWindow->getMainContextDataFactory(); boo::IGraphicsDataFactory* gf = m_mainWindow->getMainContextDataFactory();
m_shaderCacheManager.emplace(m_fileStoreManager, gf);
m_viewResources.init(gf, &m_fontCache, &m_themeData, pixelFactor); m_viewResources.init(gf, &m_fontCache, &m_themeData, pixelFactor);
m_iconsToken = InitializeIcons(m_viewResources); m_iconsToken = InitializeIcons(m_viewResources);
m_viewResources.prepFontCacheAsync(m_mainWindow.get()); m_viewResources.prepFontCacheAsync(m_mainWindow.get());
@ -256,7 +257,7 @@ void ViewManager::init(boo::IApplication* app)
m_mainWindow->setWaitCursor(false); m_mainWindow->setWaitCursor(false);
m_voiceEngine = boo::NewAudioVoiceEngine(); m_voiceEngine = boo::NewAudioVoiceEngine();
CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex()); CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex(), &*m_shaderCacheManager);
CElementGen::Initialize(); CElementGen::Initialize();
CMoviePlayer::Initialize(); CMoviePlayer::Initialize();
CLineRenderer::Initialize(); CLineRenderer::Initialize();
@ -322,6 +323,7 @@ void ViewManager::stop()
m_iconsToken.doDestroy(); m_iconsToken.doDestroy();
m_viewResources.destroyResData(); m_viewResources.destroyResData();
m_fontCache.destroyAtlases(); m_fontCache.destroyAtlases();
m_shaderCacheManager = std::experimental::nullopt;
m_mainWindow->getCommandQueue()->stopRenderer(); m_mainWindow->getCommandQueue()->stopRenderer();
} }

View File

@ -22,6 +22,7 @@ class ViewManager : public specter::IViewManager
friend class SplitSpace; friend class SplitSpace;
hecl::Runtime::FileStoreManager& m_fileStoreManager; hecl::Runtime::FileStoreManager& m_fileStoreManager;
std::experimental::optional<hecl::Runtime::ShaderCacheManager> m_shaderCacheManager;
hecl::CVarManager& m_cvarManager; hecl::CVarManager& m_cvarManager;
ProjectManager m_projManager; ProjectManager m_projManager;
specter::FontCache m_fontCache; specter::FontCache m_fontCache;

View File

@ -28,14 +28,8 @@ public:
bool CanMakeMemory(const urde::SObjectTag& tag) const; bool CanMakeMemory(const urde::SObjectTag& tag) const;
CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr<u8[]>&& buf, int size, bool compressed, CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr<u8[]>&& buf, int size, bool compressed,
const CVParamTransfer& paramXfer); const CVParamTransfer& paramXfer);
void AddFactory(FourCC key, FFactoryFunc func) void AddFactory(FourCC key, FFactoryFunc func) {m_factories[key] = func;}
{ void AddFactory(FourCC key, FMemFactoryFunc func) {m_memFactories[key] = func;}
m_factories[key] = func;
}
void AddFactory(FourCC key, FMemFactoryFunc func)
{
m_memFactories[key] = func;
}
}; };
} }

View File

@ -1,4 +1,5 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${BOO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${BOO_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/DataSpec)
add_subdirectory(Audio) add_subdirectory(Audio)
add_subdirectory(Character) add_subdirectory(Character)

View File

@ -143,6 +143,7 @@ public:
x4_lockHeld = true; x4_lockHeld = true;
} }
} }
bool IsLocked() const {return x4_lockHeld;}
bool IsLoaded() const bool IsLoaded() const
{ {
if (!x0_objRef) if (!x0_objRef)
@ -210,6 +211,12 @@ public:
++x0_objRef->x0_refCount; ++x0_objRef->x0_refCount;
Lock(); Lock();
} }
CToken(std::unique_ptr<IObj>&& obj)
{
x0_objRef = new CObjectReference(std::move(obj));
++x0_objRef->x0_refCount;
Lock();
}
CToken(CObjectReference* obj) CToken(CObjectReference* obj)
{ {
x0_objRef = obj; x0_objRef = obj;
@ -243,12 +250,17 @@ public:
TToken() = default; TToken() = default;
TToken(const CToken& other) : CToken(other) {} TToken(const CToken& other) : CToken(other) {}
TToken(CToken&& other) : CToken(std::move(other)) {} TToken(CToken&& other) : CToken(std::move(other)) {}
TToken(T* obj) : CToken(GetIObjObjectFor(std::unique_ptr<T>(obj))) {} TToken(std::unique_ptr<T>&& obj) : CToken(GetIObjObjectFor(std::move(obj))) {}
TToken& operator=(T* obj) {*this = CToken(GetIObjObjectFor(obj)); return this;} TToken& operator=(std::unique_ptr<T>&& obj)
{
*this = CToken(GetIObjObjectFor(std::move(obj)));
return this;
}
T* GetObj() T* GetObj()
{ {
if (CToken::GetObj()) TObjOwnerDerivedFromIObj<T>* owner = static_cast<TObjOwnerDerivedFromIObj<T>*>(CToken::GetObj());
return static_cast<TObjOwnerDerivedFromIObj<T>*>(CToken::GetObj())->GetObj(); if (owner)
return owner->GetObj();
return nullptr; return nullptr;
} }
const T* GetObj() const const T* GetObj() const
@ -260,15 +272,38 @@ public:
}; };
template <class T> template <class T>
class TLockedToken : public TToken<T> class TCachedToken : public TToken<T>
{ {
T* m_obj; protected:
T* m_obj = nullptr;
public: public:
TLockedToken() : m_obj(nullptr) {} TCachedToken() = default;
TLockedToken(const CToken& other) : TToken<T>(other) {m_obj = TToken<T>::GetObj();} TCachedToken(const CToken& other) : TToken<T>(other) {}
TLockedToken(CToken&& other) : TToken<T>(std::move(other)) {m_obj = TToken<T>::GetObj();} TCachedToken(CToken&& other) : TToken<T>(std::move(other)) {}
T* GetObj() const {return m_obj;} T* GetObj()
T* operator->() const {return m_obj;} {
if (!m_obj)
m_obj = TToken<T>::GetObj();
return m_obj;
}
const T* GetObj() const
{
return ((TCachedToken<T>*)this)->GetObj();
}
T* operator->() {return GetObj();}
const T* operator->() const {return GetObj();}
void Unlock() {TToken<T>::Unlock(); m_obj = nullptr;}
};
template <class T>
class TLockedToken : public TCachedToken<T>
{
public:
TLockedToken() = default;
TLockedToken(const CToken& other) : TCachedToken<T>(other)
{TCachedToken<T>::m_obj = TToken<T>::GetObj();}
TLockedToken(CToken&& other) : TCachedToken<T>(std::move(other))
{TCachedToken<T>::m_obj = TToken<T>::GetObj();}
}; };
} }

View File

@ -300,5 +300,6 @@ void CGraphics::SetViewportResolution(const zeus::CVector2i& res)
boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr; boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr;
boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr; boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr;
boo::ITextureR* CGraphics::g_SpareTexture = 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/IGraphicsDataFactory.hpp"
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp" #include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
#include "hecl/Runtime.hpp"
namespace urde namespace urde
{ {
class CLight; class CLight;
@ -212,14 +214,17 @@ public:
static boo::IGraphicsDataFactory* g_BooFactory; static boo::IGraphicsDataFactory* g_BooFactory;
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue; static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
static boo::ITextureR* g_SpareTexture; static boo::ITextureR* g_SpareTexture;
static hecl::Runtime::ShaderCacheManager* g_ShaderCacheMgr;
static void InitializeBoo(boo::IGraphicsDataFactory* factory, static void InitializeBoo(boo::IGraphicsDataFactory* factory,
boo::IGraphicsCommandQueue* cc, boo::IGraphicsCommandQueue* cc,
boo::ITextureR* spareTex) boo::ITextureR* spareTex,
hecl::Runtime::ShaderCacheManager* shadCacheMgr)
{ {
g_BooFactory = factory; g_BooFactory = factory;
g_BooMainCommandQueue = cc; g_BooMainCommandQueue = cc;
g_SpareTexture = spareTex; g_SpareTexture = spareTex;
g_ShaderCacheMgr = shadCacheMgr;
} }
static boo::GraphicsDataToken CommitResources(const boo::FactoryCommitFunc& commitFunc) static boo::GraphicsDataToken CommitResources(const boo::FactoryCommitFunc& commitFunc)
@ -243,6 +248,10 @@ public:
{ {
g_BooMainCommandQueue->draw(start, count); 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 "CFactoryMgr.hpp"
#include "CToken.hpp" #include "CToken.hpp"
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
#include "DNACommon/CMDL.hpp"
#include "DNAMP1/CMDLMaterials.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp" #include "boo/graphicsdev/IGraphicsDataFactory.hpp"
@ -22,69 +24,80 @@ struct CModelFlags
zeus::CColor color; /* Set into kcolor slot specified by material */ zeus::CColor color; /* Set into kcolor slot specified by material */
/* depth flags /* depth flags
0x4: render without texture lock
0x8: greater 0x8: greater
0x10: non-inclusive 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 class CBooModel
{ {
public: public:
/* urde addition: doesn't require hacky stashing of struct SShader
* pointers within loaded CMDL buffer */
struct CSurfaceView
{ {
const u8* m_data; std::vector<TCachedToken<CTexture>> x0_textures;
CBooModel* m_parent = nullptr; std::vector<boo::IShaderPipeline*> m_shaders;
CSurfaceView* m_next = nullptr; DataSpec::DNAMP1::HMDLMaterialSet m_matSet;
void UnlockTextures();
}; };
private: private:
std::vector<CSurfaceView>* x0_surfaces; std::vector<CBooSurface>* x0_surfaces;
const u8* x4_matSet; const DataSpec::DNAMP1::HMDLMaterialSet* x4_matSet;
const std::vector<boo::IShaderPipeline*>* m_pipelines;
boo::IVertexFormat* m_vtxFmt;
boo::IGraphicsBufferS* x8_vbo; boo::IGraphicsBufferS* x8_vbo;
boo::IGraphicsBufferS* xc_ibo; boo::IGraphicsBufferS* xc_ibo;
std::vector<TLockedToken<CTexture>>* x1c_textures; std::vector<TCachedToken<CTexture>>* x1c_textures;
zeus::CAABox x20_aabb; zeus::CAABox x20_aabb;
CSurfaceView* x38_firstUnsortedSurface = nullptr; CBooSurface* x38_firstUnsortedSurface = nullptr;
CSurfaceView* x3c_firstSortedSurface = nullptr; CBooSurface* x3c_firstSortedSurface = nullptr;
bool x40_24_ : 1; bool x40_24_texturesLoaded : 1;
bool x40_25_ : 1; bool x40_25_ : 1;
u8 x41_shortNormals; u8 x41_shortNormals;
/* urde addition: boo! */ /* urde addition: boo! */
boo::GraphicsDataToken m_gfxToken; boo::GraphicsDataToken m_gfxToken;
boo::IGraphicsBufferD* m_uniformBuffer; boo::IGraphicsBufferD* m_uniformBuffer;
boo::IShaderDataBinding* m_shaderDataBinding; std::vector<boo::IShaderDataBinding*> m_shaderDataBindings;
void DrawAlphaSurfaces(const CModelFlags& flags) const; void DrawAlphaSurfaces(const CModelFlags& flags) const;
void DrawNormalSurfaces(const CModelFlags& flags) const; void DrawNormalSurfaces(const CModelFlags& flags) const;
void DrawSurfaces(const CModelFlags& flags) const; void DrawSurfaces(const CModelFlags& flags) const;
void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const; void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
public: void BuildGfxToken();
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);
static void MakeTexuresFromMats(const u8* dataIn, public:
std::vector<TLockedToken<CTexture>>& toksOut, 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); IObjectStore& store);
void TryLockTextures() const; void RemapMaterialData(SShader& shader);
bool TryLockTextures() const;
void UnlockTextures() const; void UnlockTextures() const;
void DrawAlpha(const CModelFlags& flags) const; void DrawAlpha(const CModelFlags& flags) const;
void DrawNormal(const CModelFlags& flags) const; void DrawNormal(const CModelFlags& flags) const;
void Draw(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 bool g_DrawingOccluders;
static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;} static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;}
@ -92,17 +105,10 @@ public:
class CModel class CModel
{ {
public:
struct SShader
{
std::vector<TLockedToken<CTexture>> x0_textures;
const u8* x10_data;
};
private:
std::unique_ptr<u8[]> x0_data; std::unique_ptr<u8[]> x0_data;
u32 x4_dataLen; u32 x4_dataLen;
std::vector<CBooModel::CSurfaceView> x8_surfaces; std::vector<CBooSurface> x8_surfaces;
std::vector<SShader> x18_matSets; std::vector<CBooModel::SShader> x18_matSets;
std::unique_ptr<CBooModel> x28_modelInst; std::unique_ptr<CBooModel> x28_modelInst;
CModel* x30_next = nullptr; CModel* x30_next = nullptr;
CModel* x34_prev = nullptr; CModel* x34_prev = nullptr;
@ -111,12 +117,17 @@ private:
boo::GraphicsDataToken m_gfxToken; boo::GraphicsDataToken m_gfxToken;
boo::IGraphicsBufferS* m_vbo; boo::IGraphicsBufferS* m_vbo;
boo::IGraphicsBufferS* m_ibo; boo::IGraphicsBufferS* m_ibo;
boo::IVertexFormat* m_vtxFmt;
void VerifyCurrentShader(int shaderIdx) const;
public: public:
CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store); 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 Draw(const CModelFlags& flags) const;
void Touch(int) const; void Touch(int shaderIdx) const;
bool IsLoaded(int) const; bool IsLoaded(int shaderIdx) const;
}; };
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag, CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,

View File

@ -2,27 +2,36 @@
#include "Graphics/CTexture.hpp" #include "Graphics/CTexture.hpp"
#include "Graphics/CGraphics.hpp" #include "Graphics/CGraphics.hpp"
#include "hecl/HMDLMeta.hpp" #include "hecl/HMDLMeta.hpp"
#include "hecl/Runtime.hpp"
namespace urde namespace urde
{ {
static logvisor::Module Log("urde::CModelBoo"); static logvisor::Module Log("urde::CModelBoo");
bool CBooModel::g_DrawingOccluders = false; bool CBooModel::g_DrawingOccluders = false;
CBooModel::CBooModel(std::vector<CSurfaceView>* surfaces, std::vector<TLockedToken<CTexture>>* textures, struct SUnskinnedUniforms
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)
{ {
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; surf.m_parent = this;
for (auto it=x0_surfaces->rbegin() ; it != x0_surfaces->rend() ; ++it) for (auto it=x0_surfaces->rbegin() ; it != x0_surfaces->rend() ; ++it)
{ {
u32 matId = hecl::SBig(*reinterpret_cast<const u32*>(it->m_data + 0xc)); u32 matId = it->m_data.matIdx;
const u8* matData = GetMaterialByIndex(matId); const DataSpec::DNAMP1::HMDLMaterialSet::Material& matData = GetMaterialByIndex(matId);
u32 matFlags = hecl::SBig(*reinterpret_cast<const u32*>(matData)); if (matData.flags.depthSorting())
if (matFlags & 0x10)
{ {
it->m_next = x3c_firstSortedSurface; it->m_next = x3c_firstSortedSurface;
x3c_firstSortedSurface = &*it; x3c_firstSortedSurface = &*it;
@ -33,71 +42,152 @@ CBooModel::CBooModel(std::vector<CSurfaceView>* surfaces, std::vector<TLockedTok
x38_firstUnsortedSurface = &*it; x38_firstUnsortedSurface = &*it;
} }
} }
if (x40_24_texturesLoaded)
BuildGfxToken();
} }
void CBooModel::MakeTexuresFromMats(const u8* dataIn, void CBooModel::BuildGfxToken()
std::vector<TLockedToken<CTexture>>& toksOut, {
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) IObjectStore& store)
{ {
u32 texCount = hecl::SBig(*reinterpret_cast<const u32*>(dataIn)); toksOut.reserve(matSet.head.textureIDs.size());
dataIn += 4; for (const DataSpec::UniqueID32& id : matSet.head.textureIDs)
toksOut.reserve(texCount); toksOut.emplace_back(store.GetObj({SBIG('TXTR'), id.toUint32()}));
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}));
}
} }
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 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 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 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 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 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 void CBooModel::DrawAlpha(const CModelFlags& flags) const
{ {
DrawAlphaSurfaces(flags);
} }
void CBooModel::DrawNormal(const CModelFlags& flags) const void CBooModel::DrawNormal(const CModelFlags& flags) const
{ {
DrawNormalSurfaces(flags);
} }
void CBooModel::Draw(const CModelFlags& flags) const void CBooModel::Draw(const CModelFlags& flags) const
{ {
} DrawSurfaces(flags);
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;
} }
static const u8* MemoryFromPartData(const u8*& dataCur, const s32*& secSizeCur) 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); const s32* secSizeCur = reinterpret_cast<const s32*>(x0_data.get() + 0x2c);
for (u32 i=0 ; i<matSetCount ; ++i) for (u32 i=0 ; i<matSetCount ; ++i)
{ {
u32 matSetSz = hecl::SBig(*secSizeCur);
const u8* sec = MemoryFromPartData(dataCur, secSizeCur); const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
x18_matSets.emplace_back(); x18_matSets.emplace_back();
SShader& shader = x18_matSets.back(); CBooModel::SShader& shader = x18_matSets.back();
shader.x10_data = sec; athena::io::MemoryReader r(sec, matSetSz);
CBooModel::MakeTexuresFromMats(sec, shader.x0_textures, *store); shader.m_matSet.read(r);
CBooModel::MakeTexuresFromMats(shader.m_matSet, shader.x0_textures, *store);
} }
hecl::HMDLMeta hmdlMeta; hecl::HMDLMeta hmdlMeta;
{ {
u32 hmdlSz = hecl::SBig(*secSizeCur);
const u8* hmdlMetadata = MemoryFromPartData(dataCur, secSizeCur); const u8* hmdlMetadata = MemoryFromPartData(dataCur, secSizeCur);
athena::io::MemoryReader r(hmdlMetadata, *secSizeCur); athena::io::MemoryReader r(hmdlMetadata, hmdlSz);
hmdlMeta.read(r); 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_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vboData, hmdlMeta.vertStride, hmdlMeta.vertCount);
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, iboData, 4, hmdlMeta.indexCount); 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; return true;
}); });
@ -157,30 +264,55 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
x8_surfaces.reserve(surfCount); x8_surfaces.reserve(surfCount);
for (u32 i=0 ; i<surfCount ; ++i) for (u32 i=0 ; i<surfCount ; ++i)
{ {
u32 surfSz = hecl::SBig(*secSizeCur);
const u8* sec = MemoryFromPartData(dataCur, secSizeCur); const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
x8_surfaces.emplace_back(); x8_surfaces.emplace_back();
CBooModel::CSurfaceView& surf = x8_surfaces.back(); CBooSurface& surf = x8_surfaces.back();
surf.m_data = sec; athena::io::MemoryReader r(sec, surfSz);
surf.m_data.read(r);
} }
const float* aabbPtr = reinterpret_cast<const float*>(x0_data.get() + 0x18); 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]), 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])); 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, x28_modelInst = std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[0],
x18_matSets[0].x10_data, m_vbo, m_ibo, m_vtxFmt, m_vbo, m_ibo,
aabb, flags & 0x2, true); 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::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; return false;
} }

View File

@ -44,7 +44,7 @@ public:
ETexelFormat GetTexelFormat() const {return x0_fmt;} ETexelFormat GetTexelFormat() const {return x0_fmt;}
u16 GetWidth() const {return x4_w;} u16 GetWidth() const {return x4_w;}
u16 GetHeight() const {return x6_h;} 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;} 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
{ {
} }

View File

@ -28,7 +28,7 @@ bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const
{ {
if (!xf8_model) if (!xf8_model)
return true; return true;
CModel* model = xf8_model.GetObj(); const CModel* model = xf8_model.GetObj();
if (!model) if (!model)
return false; return false;
model->Touch(0); model->Touch(0);
@ -37,7 +37,7 @@ bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const
void CGuiModel::Touch() const void CGuiModel::Touch() const
{ {
CModel* model = xf8_model.GetObj(); const CModel* model = xf8_model.GetObj();
if (model) if (model)
model->Touch(0); model->Touch(0);
} }
@ -49,7 +49,7 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const
return; return;
if (!GetIsFinishedLoading()) if (!GetIsFinishedLoading())
return; return;
CModel* model = xf8_model.GetObj(); const CModel* model = xf8_model.GetObj();
if (!model) if (!model)
return; return;

2
hecl

@ -1 +1 @@
Subproject commit c8d5866157ceb8a571ea2ba63c7a9306afb32dfa Subproject commit c6feb64383aa84fee18afa423e741bfa3dca4a74