mirror of https://github.com/AxioDL/metaforce.git
Initial CLight integration
This commit is contained in:
parent
36ed356886
commit
dae2621d93
|
@ -1606,6 +1606,7 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
|
|||
header.reflectionNormal = osurf.reflectionNormal;
|
||||
header.idxStart = surf.m_start;
|
||||
header.idxCount = surf.m_count;
|
||||
header.skinMtxBankIdx = osurf.skinBankIdx;
|
||||
header.write(writer);
|
||||
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
|
@ -1619,7 +1620,7 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
|
|||
return true;
|
||||
}
|
||||
|
||||
template bool WriteHMDLCMDL<DNAMP1::HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>
|
||||
template bool WriteHMDLCMDL<DNAMP1::HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>
|
||||
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
||||
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ struct CMDL
|
|||
{
|
||||
if (mesh.skins.size())
|
||||
{
|
||||
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
|
||||
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh))
|
||||
return false;
|
||||
|
||||
/* Output skinning intermediate */
|
||||
|
@ -138,7 +138,7 @@ struct CMDL
|
|||
for (const std::string& boneName : mesh.boneNames)
|
||||
writer.writeString(boneName);
|
||||
}
|
||||
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
|
||||
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <athena/DNAYaml.hpp>
|
||||
#include "ProjectResourceFactoryMP1.hpp"
|
||||
#include "Runtime/CSimplePool.hpp"
|
||||
#include "hecl/Runtime.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
|
|
@ -263,7 +263,6 @@ void ViewManager::init(boo::IApplication* app)
|
|||
float pixelFactor = 1.0;
|
||||
|
||||
boo::IGraphicsDataFactory* gf = m_mainWindow->getMainContextDataFactory();
|
||||
m_shaderCacheManager.emplace(m_fileStoreManager, gf);
|
||||
m_viewResources.init(gf, &m_fontCache, &m_themeData, pixelFactor);
|
||||
m_iconsToken = InitializeIcons(m_viewResources);
|
||||
m_viewResources.prepFontCacheAsync(m_mainWindow.get());
|
||||
|
@ -275,7 +274,8 @@ void ViewManager::init(boo::IApplication* app)
|
|||
m_mainWindow->setWaitCursor(false);
|
||||
|
||||
m_voiceEngine = boo::NewAudioVoiceEngine();
|
||||
CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex(), &*m_shaderCacheManager);
|
||||
CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex());
|
||||
CModelShaders::Initialize(m_fileStoreManager, gf);
|
||||
CElementGen::Initialize();
|
||||
CMoviePlayer::Initialize();
|
||||
CLineRenderer::Initialize();
|
||||
|
@ -341,7 +341,6 @@ void ViewManager::stop()
|
|||
m_iconsToken.doDestroy();
|
||||
m_viewResources.destroyResData();
|
||||
m_fontCache.destroyAtlases();
|
||||
m_shaderCacheManager = std::experimental::nullopt;
|
||||
m_mainWindow->getCommandQueue()->stopRenderer();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ class ViewManager : public specter::IViewManager
|
|||
friend class SplitSpace;
|
||||
|
||||
hecl::Runtime::FileStoreManager& m_fileStoreManager;
|
||||
std::experimental::optional<hecl::Runtime::ShaderCacheManager> m_shaderCacheManager;
|
||||
hecl::CVarManager& m_cvarManager;
|
||||
ProjectManager m_projManager;
|
||||
specter::FontCache m_fontCache;
|
||||
|
|
|
@ -379,6 +379,5 @@ boo::IGraphicsDataFactory::Platform CGraphics::g_BooPlatform = boo::IGraphicsDat
|
|||
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;
|
||||
|
||||
}
|
||||
|
|
|
@ -225,18 +225,15 @@ 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,
|
||||
hecl::Runtime::ShaderCacheManager* shadCacheMgr)
|
||||
boo::ITextureR* spareTex)
|
||||
{
|
||||
g_BooPlatform = factory->platform();
|
||||
g_BooFactory = factory;
|
||||
g_BooMainCommandQueue = cc;
|
||||
g_SpareTexture = spareTex;
|
||||
g_ShaderCacheMgr = shadCacheMgr;
|
||||
}
|
||||
|
||||
static boo::GraphicsDataToken CommitResources(const boo::FactoryCommitFunc& commitFunc)
|
||||
|
|
|
@ -39,6 +39,53 @@ float CLight::GetIntensity() const
|
|||
return x48_cachedIntensity;
|
||||
}
|
||||
|
||||
|
||||
CLight::CLight(const zeus::CVector3f& pos,
|
||||
const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color,
|
||||
float distC, float distL, float distQ,
|
||||
float angleC, float angleL, float angleQ)
|
||||
: x0_pos(pos), xc_dir(dir), x18_color(color),
|
||||
x1c_type(ELightType::Custom), x20_spotCutoff(0.f),
|
||||
x24_distC(distC), x28_distL(distL), x2c_distQ(distQ),
|
||||
x30_angleC(angleC), x34_angleL(angleL), x38_angleQ(angleQ),
|
||||
x44_cachedRadius(0.f), x48_cachedIntensity(0.f),
|
||||
x4c_24_intensityDirty(true), x4c_25_radiusDirty(true)
|
||||
{}
|
||||
|
||||
CLight::CLight(ELightType type,
|
||||
const zeus::CVector3f& pos,
|
||||
const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color,
|
||||
float cutoff)
|
||||
: x0_pos(pos), xc_dir(dir), x18_color(color),
|
||||
x1c_type(type), x20_spotCutoff(cutoff),
|
||||
x24_distC(0.f), x28_distL(1.f), x2c_distQ(0.f),
|
||||
x30_angleC(0.f), x34_angleL(1.f), x38_angleQ(0.f),
|
||||
x44_cachedRadius(0.f), x48_cachedIntensity(0.f),
|
||||
x4c_24_intensityDirty(true), x4c_25_radiusDirty(true)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ELightType::Spot:
|
||||
{
|
||||
float cosCutoff = std::cos(cutoff * M_PI / 180.0);
|
||||
x30_angleC = 0.f;
|
||||
x34_angleL = -cosCutoff / (1.0 - cosCutoff);
|
||||
x38_angleQ = 1.f / (1.0 - cosCutoff);
|
||||
break;
|
||||
}
|
||||
case ELightType::Directional:
|
||||
{
|
||||
x24_distC = 1.f;
|
||||
x28_distL = 0.f;
|
||||
x2c_distQ = 0.f;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
CLight CLight::BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color)
|
||||
{
|
||||
return CLight(ELightType::Directional, kDefaultPosition, dir, color, 180.f);
|
||||
|
|
|
@ -26,6 +26,7 @@ enum class EFalloffType
|
|||
class CLight
|
||||
{
|
||||
friend class CGuiLight;
|
||||
friend class CBooModel;
|
||||
|
||||
zeus::CVector3f x0_pos;
|
||||
zeus::CVector3f xc_dir;
|
||||
|
@ -52,27 +53,13 @@ public:
|
|||
const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color,
|
||||
float distC, float distL, float distQ,
|
||||
float angleC, float angleL, float angleQ)
|
||||
: x0_pos(pos), xc_dir(dir), x18_color(color),
|
||||
x1c_type(ELightType::Custom), x20_spotCutoff(0.f),
|
||||
x24_distC(distC), x28_distL(distL), x2c_distQ(distQ),
|
||||
x30_angleC(angleC), x34_angleL(angleL), x38_angleQ(angleQ),
|
||||
x44_cachedRadius(0.f), x48_cachedIntensity(0.f),
|
||||
x4c_24_intensityDirty(true), x4c_25_radiusDirty(true)
|
||||
{}
|
||||
float angleC, float angleL, float angleQ);
|
||||
|
||||
CLight(ELightType type,
|
||||
const zeus::CVector3f& pos,
|
||||
const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color,
|
||||
float cutoff)
|
||||
: x0_pos(pos), xc_dir(dir), x18_color(color),
|
||||
x1c_type(type), x20_spotCutoff(cutoff),
|
||||
x24_distC(0.f), x28_distL(1.f), x2c_distQ(0.f),
|
||||
x30_angleC(0.f), x34_angleL(1.f), x38_angleQ(0.f),
|
||||
x44_cachedRadius(0.f), x48_cachedIntensity(0.f),
|
||||
x4c_24_intensityDirty(true), x4c_25_radiusDirty(true)
|
||||
{}
|
||||
float cutoff);
|
||||
|
||||
void SetPosition(const zeus::CVector3f& pos)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
if(WIN32)
|
||||
set(PLAT_SRCS CLineRendererShadersHLSL.cpp)
|
||||
set(PLAT_SRCS CLineRendererShadersHLSL.cpp CModelShadersHLSL.cpp)
|
||||
elseif(APPLE)
|
||||
set(PLAT_SRCS CLineRendererShadersMetal.cpp)
|
||||
set(PLAT_SRCS CLineRendererShadersMetal.cpp CModelShadersMetal.cpp)
|
||||
endif()
|
||||
|
||||
include_directories(${LIBJPEG_INCLUDE_DIR})
|
||||
|
@ -15,6 +15,7 @@ add_library(RuntimeCommonGraphics
|
|||
CLight.hpp CLight.cpp
|
||||
CTexture.hpp CTextureBoo.cpp
|
||||
CModel.hpp CModelBoo.cpp
|
||||
CModelShaders.hpp CModelShadersGLSL.cpp
|
||||
CMoviePlayer.hpp CMoviePlayer.cpp
|
||||
CGraphicsPalette.hpp CGraphicsPalette.cpp
|
||||
CGraphics.hpp CGraphics.cpp
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "zeus/CAABox.hpp"
|
||||
#include "DNACommon/CMDL.hpp"
|
||||
#include "DNAMP1/CMDLMaterials.hpp"
|
||||
#include "CModelShaders.hpp"
|
||||
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
|
||||
|
@ -15,11 +16,13 @@ namespace urde
|
|||
{
|
||||
class IObjectStore;
|
||||
class CTexture;
|
||||
class CLight;
|
||||
|
||||
struct CModelFlags
|
||||
{
|
||||
u8 m_blendMode = 0; /* Blend state 3/5 enable additive */
|
||||
u8 m_matSetIdx = 0;
|
||||
u8 m_extendedShaderIdx = 0; /* 0 for shadeless, 1 for lighting, others defined in CModelShaders */
|
||||
u16 m_flags = 0; /* Flags */
|
||||
zeus::CColor color; /* Set into kcolor slot specified by material */
|
||||
|
||||
|
@ -38,18 +41,12 @@ struct CModelFlags
|
|||
* pointers within loaded CMDL buffer */
|
||||
struct CBooSurface
|
||||
{
|
||||
DataSpec::DNACMDL::SurfaceHeader_1 m_data;
|
||||
DataSpec::DNACMDL::SurfaceHeader_2 m_data;
|
||||
size_t selfIdx;
|
||||
class CBooModel* m_parent = nullptr;
|
||||
CBooSurface* m_next = nullptr;
|
||||
};
|
||||
|
||||
struct SUnskinnedXf
|
||||
{
|
||||
zeus::CMatrix4f mv;
|
||||
zeus::CMatrix4f mvinv;
|
||||
zeus::CMatrix4f proj;
|
||||
};
|
||||
|
||||
class CBooModel
|
||||
{
|
||||
friend class CModel;
|
||||
|
@ -59,7 +56,7 @@ public:
|
|||
struct SShader
|
||||
{
|
||||
std::vector<TCachedToken<CTexture>> x0_textures;
|
||||
std::vector<boo::IShaderPipeline*> m_shaders;
|
||||
std::vector<std::vector<boo::IShaderPipeline*>> m_shaders;
|
||||
MaterialSet m_matSet;
|
||||
void UnlockTextures();
|
||||
};
|
||||
|
@ -67,10 +64,12 @@ public:
|
|||
private:
|
||||
std::vector<CBooSurface>* x0_surfaces;
|
||||
const MaterialSet* x4_matSet;
|
||||
const std::vector<boo::IShaderPipeline*>* m_pipelines;
|
||||
const std::vector<std::vector<boo::IShaderPipeline*>>* m_pipelines;
|
||||
boo::IVertexFormat* m_vtxFmt;
|
||||
boo::IGraphicsBufferS* x8_vbo;
|
||||
boo::IGraphicsBufferS* xc_ibo;
|
||||
size_t m_weightVecCount;
|
||||
size_t m_skinBankCount;
|
||||
std::vector<TCachedToken<CTexture>>* x1c_textures;
|
||||
zeus::CAABox x20_aabb;
|
||||
CBooSurface* x38_firstUnsortedSurface = nullptr;
|
||||
|
@ -81,19 +80,19 @@ private:
|
|||
|
||||
struct UVAnimationBuffer
|
||||
{
|
||||
std::vector<zeus::CMatrix4f> m_buffer;
|
||||
std::vector<std::pair<size_t,size_t>> m_ranges;
|
||||
void ProcessAnimation(const UVAnimation& anim);
|
||||
void PadOutBuffer();
|
||||
void Update(const MaterialSet* matSet);
|
||||
operator bool() const {return m_buffer.size() != 0;}
|
||||
} m_uvAnimBuffer;
|
||||
static void ProcessAnimation(u8*& bufOut, const UVAnimation& anim);
|
||||
static void PadOutBuffer(u8*& bufStart, u8*& bufOut);
|
||||
static void Update(u8*& bufOut, const MaterialSet* matSet);
|
||||
};
|
||||
|
||||
CModelShaders::LightingUniform m_lightingData;
|
||||
|
||||
/* urde addition: boo! */
|
||||
boo::GraphicsDataToken m_gfxToken;
|
||||
boo::IGraphicsBufferD* m_unskinnedXfBuffer;
|
||||
boo::IGraphicsBufferD* m_uvMtxBuffer;
|
||||
std::vector<boo::IShaderDataBinding*> m_shaderDataBindings;
|
||||
std::unique_ptr<u8[]> m_uniformData;
|
||||
size_t m_uniformDataSize = 0;
|
||||
boo::IGraphicsBufferD* m_uniformBuffer = nullptr;
|
||||
std::vector<std::vector<boo::IShaderDataBinding*>> m_shaderDataBindings;
|
||||
|
||||
void BuildGfxToken();
|
||||
void UpdateUniformData() const;
|
||||
|
@ -105,13 +104,14 @@ private:
|
|||
public:
|
||||
CBooModel(std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
||||
const zeus::CAABox& aabb,
|
||||
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb,
|
||||
u8 shortNormals, bool texturesLoaded);
|
||||
|
||||
static void MakeTexuresFromMats(const MaterialSet& matSet,
|
||||
std::vector<TCachedToken<CTexture>>& toksOut,
|
||||
IObjectStore& store);
|
||||
|
||||
void ActivateLights(const std::vector<CLight>& lights);
|
||||
void RemapMaterialData(SShader& shader);
|
||||
bool TryLockTextures() const;
|
||||
void UnlockTextures() const;
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
#include "Graphics/CModel.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "Graphics/CLight.hpp"
|
||||
#include "hecl/HMDLMeta.hpp"
|
||||
#include "hecl/Runtime.hpp"
|
||||
#include "CModelShaders.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
static logvisor::Module Log("urde::CModelBoo");
|
||||
bool CBooModel::g_DrawingOccluders = false;
|
||||
|
||||
static std::experimental::optional<CModelShaders> g_ModelShaders;
|
||||
|
||||
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)
|
||||
size_t weightVecCount, size_t skinBankCount, 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),
|
||||
m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount),
|
||||
m_skinBankCount(skinBankCount), x1c_textures(&shader.x0_textures), x20_aabb(aabb),
|
||||
x40_24_texturesLoaded(texturesLoaded), x40_25_(0), x41_shortNormals(shortNormals)
|
||||
{
|
||||
for (CBooSurface& surf : *x0_surfaces)
|
||||
|
@ -44,15 +50,81 @@ void CBooModel::BuildGfxToken()
|
|||
m_gfxToken = CGraphics::CommitResources(
|
||||
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
m_unskinnedXfBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform,
|
||||
sizeof(SUnskinnedXf), 1);
|
||||
boo::IGraphicsBuffer* bufs[] = {m_unskinnedXfBuffer};
|
||||
m_shaderDataBindings.clear();
|
||||
m_shaderDataBindings.reserve(x4_matSet->materials.size());
|
||||
auto pipelineIt = m_pipelines->begin();
|
||||
std::vector<boo::ITexture*> texs;
|
||||
/* Determine space required by uniform buffer */
|
||||
std::vector<size_t> skinOffs;
|
||||
std::vector<size_t> skinSizes;
|
||||
skinOffs.reserve(std::max(size_t(1), m_skinBankCount));
|
||||
skinSizes.reserve(std::max(size_t(1), m_skinBankCount));
|
||||
|
||||
std::vector<size_t> uvOffs;
|
||||
std::vector<size_t> uvSizes;
|
||||
uvOffs.reserve(x4_matSet->materials.size());
|
||||
uvSizes.reserve(x4_matSet->materials.size());
|
||||
|
||||
/* Vert transform matrices */
|
||||
size_t uniBufSize = 0;
|
||||
if (m_skinBankCount)
|
||||
{
|
||||
/* Skinned */
|
||||
for (size_t i=0 ; i<m_skinBankCount ; ++i)
|
||||
{
|
||||
size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * (2 * m_weightVecCount * 4 + 1));
|
||||
skinOffs.push_back(uniBufSize);
|
||||
skinSizes.push_back(thisSz);
|
||||
uniBufSize += thisSz;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-Skinned */
|
||||
size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * 3);
|
||||
skinOffs.push_back(uniBufSize);
|
||||
skinSizes.push_back(thisSz);
|
||||
uniBufSize += thisSz;
|
||||
}
|
||||
|
||||
/* Animated UV transform matrices */
|
||||
for (const MaterialSet::Material& mat : x4_matSet->materials)
|
||||
{
|
||||
size_t thisSz = ROUND_UP_256(mat.uvAnims.size() * sizeof(zeus::CMatrix4f));
|
||||
uvOffs.push_back(uniBufSize);
|
||||
uvSizes.push_back(thisSz);
|
||||
uniBufSize += thisSz;
|
||||
}
|
||||
|
||||
/* Lighting uniform */
|
||||
size_t lightOff = 0;
|
||||
size_t lightSz = 0;
|
||||
{
|
||||
size_t thisSz = ROUND_UP_256(sizeof(CModelShaders::LightingUniform));
|
||||
lightOff = uniBufSize;
|
||||
lightSz = thisSz;
|
||||
uniBufSize += thisSz;
|
||||
}
|
||||
|
||||
/* Allocate resident buffer */
|
||||
m_uniformDataSize = uniBufSize;
|
||||
m_uniformData.reset(new u8[uniBufSize]);
|
||||
m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1);
|
||||
|
||||
std::vector<boo::IGraphicsBuffer*> bufs;
|
||||
bufs.resize(3, m_uniformBuffer);
|
||||
|
||||
/* Binding for each surface */
|
||||
m_shaderDataBindings.clear();
|
||||
m_shaderDataBindings.reserve(x0_surfaces->size());
|
||||
|
||||
std::vector<boo::ITexture*> texs;
|
||||
std::vector<size_t> thisOffs;
|
||||
std::vector<size_t> thisSizes;
|
||||
thisOffs.reserve(3);
|
||||
thisSizes.reserve(3);
|
||||
|
||||
/* Enumerate surfaces and build data bindings */
|
||||
for (const CBooSurface& surf : *x0_surfaces)
|
||||
{
|
||||
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
|
||||
|
||||
texs.clear();
|
||||
texs.reserve(mat.textureIdxs.size());
|
||||
for (atUint32 idx : mat.textureIdxs)
|
||||
|
@ -60,11 +132,44 @@ void CBooModel::BuildGfxToken()
|
|||
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;
|
||||
|
||||
size_t thisBufCount = 2;
|
||||
|
||||
if (m_skinBankCount)
|
||||
{
|
||||
thisOffs.push_back(skinOffs[surf.m_data.skinMtxBankIdx]);
|
||||
thisSizes.push_back(skinSizes[surf.m_data.skinMtxBankIdx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
thisOffs.push_back(0);
|
||||
thisSizes.push_back(256);
|
||||
}
|
||||
|
||||
if (mat.uvAnims.size())
|
||||
{
|
||||
thisOffs.push_back(uvOffs[surf.m_data.matIdx]);
|
||||
thisSizes.push_back(uvSizes[surf.m_data.matIdx]);
|
||||
++thisBufCount;
|
||||
}
|
||||
|
||||
thisOffs.push_back(lightOff);
|
||||
thisSizes.push_back(lightSz);
|
||||
|
||||
const std::vector<boo::IShaderPipeline*>& pipelines = m_pipelines->at(surf.m_data.matIdx);
|
||||
|
||||
m_shaderDataBindings.emplace_back();
|
||||
std::vector<boo::IShaderDataBinding*>& extendeds = m_shaderDataBindings.back();
|
||||
extendeds.reserve(pipelines.size());
|
||||
|
||||
for (boo::IShaderPipeline* pipeline : pipelines)
|
||||
extendeds.push_back(
|
||||
ctx.newShaderDataBinding(pipeline, m_vtxFmt,
|
||||
x8_vbo, nullptr, xc_ibo, thisBufCount, bufs.data(),
|
||||
thisOffs.data(), thisSizes.data(), mat.textureIdxs.size(), texs.data()));
|
||||
|
||||
thisOffs.clear();
|
||||
thisSizes.clear();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
@ -79,6 +184,50 @@ void CBooModel::MakeTexuresFromMats(const MaterialSet& matSet,
|
|||
toksOut.emplace_back(store.GetObj({SBIG('TXTR'), id.toUint32()}));
|
||||
}
|
||||
|
||||
void CBooModel::ActivateLights(const std::vector<CLight>& lights)
|
||||
{
|
||||
zeus::CColor ambientAccum = zeus::CColor::skBlack;
|
||||
size_t curLight = 0;
|
||||
|
||||
for (const CLight& light : lights)
|
||||
{
|
||||
switch (light.x1c_type)
|
||||
{
|
||||
case ELightType::LocalAmbient:
|
||||
ambientAccum += light.x18_color;
|
||||
break;
|
||||
case ELightType::Point:
|
||||
case ELightType::Spot:
|
||||
case ELightType::Custom:
|
||||
case ELightType::Directional:
|
||||
{
|
||||
if (curLight >= URDE_MAX_LIGHTS)
|
||||
continue;
|
||||
CModelShaders::Light& lightOut = m_lightingData.lights[curLight++];
|
||||
lightOut.pos = CGraphics::g_CameraMatrix * light.x0_pos;
|
||||
lightOut.dir = CGraphics::g_CameraMatrix.m_basis * light.xc_dir;
|
||||
lightOut.color = light.x18_color;
|
||||
lightOut.linAtt[0] = light.x24_distC;
|
||||
lightOut.linAtt[1] = light.x28_distL;
|
||||
lightOut.linAtt[2] = light.x2c_distQ;
|
||||
lightOut.angAtt[0] = light.x30_angleC;
|
||||
lightOut.angAtt[1] = light.x34_angleL;
|
||||
lightOut.angAtt[2] = light.x38_angleQ;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; curLight<URDE_MAX_LIGHTS ; ++curLight)
|
||||
{
|
||||
CModelShaders::Light& lightOut = m_lightingData.lights[curLight];
|
||||
lightOut.color = zeus::CColor::skClear;
|
||||
lightOut.linAtt[0] = 1.f;
|
||||
lightOut.angAtt[0] = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::RemapMaterialData(SShader& shader)
|
||||
{
|
||||
x4_matSet = &shader.m_matSet;
|
||||
|
@ -158,14 +307,18 @@ void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) c
|
|||
if (data.flags.shadowOccluderMesh() && !g_DrawingOccluders)
|
||||
return;
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_shaderDataBindings[surf.m_data.matIdx]);
|
||||
const std::vector<boo::IShaderDataBinding*>& extendeds = m_shaderDataBindings[surf.selfIdx];
|
||||
boo::IShaderDataBinding* binding = extendeds[0];
|
||||
if (flags.m_extendedShaderIdx < extendeds.size())
|
||||
binding = extendeds[flags.m_extendedShaderIdx];
|
||||
|
||||
CGraphics::SetShaderDataBinding(binding);
|
||||
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, surf.m_data.idxCount);
|
||||
}
|
||||
|
||||
void CBooModel::UVAnimationBuffer::ProcessAnimation(const UVAnimation& anim)
|
||||
void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimation& anim)
|
||||
{
|
||||
m_buffer.emplace_back();
|
||||
zeus::CMatrix4f& matrixOut = m_buffer.back();
|
||||
zeus::CMatrix4f& matrixOut = reinterpret_cast<zeus::CMatrix4f&>(*bufOut);
|
||||
switch (anim.mode)
|
||||
{
|
||||
case UVAnimation::Mode::MvInvNoTranslation:
|
||||
|
@ -230,61 +383,78 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(const UVAnimation& anim)
|
|||
}
|
||||
default: break;
|
||||
}
|
||||
bufOut += sizeof(zeus::CMatrix4f);
|
||||
}
|
||||
|
||||
void CBooModel::UVAnimationBuffer::PadOutBuffer()
|
||||
void CBooModel::UVAnimationBuffer::PadOutBuffer(u8*& bufStart, u8*& bufOut)
|
||||
{
|
||||
size_t curEnd = 0;
|
||||
if (m_ranges.size())
|
||||
curEnd = m_ranges.back().first + m_ranges.back().second;
|
||||
|
||||
size_t bufRem = m_buffer.size() % 4;
|
||||
if (bufRem)
|
||||
for (int i=0 ; i<(4-bufRem) ; ++i)
|
||||
m_buffer.emplace_back();
|
||||
size_t newEnd = m_buffer.size() * 64;
|
||||
|
||||
m_ranges.emplace_back(curEnd, newEnd - curEnd);
|
||||
bufOut = bufStart + ROUND_UP_256(bufOut - bufStart);
|
||||
}
|
||||
|
||||
void CBooModel::UVAnimationBuffer::Update(const MaterialSet* matSet)
|
||||
void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet)
|
||||
{
|
||||
m_buffer.clear();
|
||||
m_ranges.clear();
|
||||
|
||||
size_t bufCount = 0;
|
||||
size_t count = 0;
|
||||
for (const MaterialSet::Material& mat : matSet->materials)
|
||||
{
|
||||
count += mat.uvAnims.size();
|
||||
bufCount += mat.uvAnims.size();
|
||||
bufCount = ROUND_UP_4(bufCount);
|
||||
}
|
||||
m_buffer.reserve(bufCount);
|
||||
m_ranges.reserve(count);
|
||||
u8* start = bufOut;
|
||||
|
||||
for (const MaterialSet::Material& mat : matSet->materials)
|
||||
{
|
||||
for (const UVAnimation& anim : mat.uvAnims)
|
||||
ProcessAnimation(anim);
|
||||
PadOutBuffer();
|
||||
ProcessAnimation(bufOut, anim);
|
||||
PadOutBuffer(start, bufOut);
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::UpdateUniformData() const
|
||||
{
|
||||
SUnskinnedXf unskinnedXf;
|
||||
unskinnedXf.mv = CGraphics::g_GXModelView.toMatrix4f();
|
||||
unskinnedXf.mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||
unskinnedXf.proj = CGraphics::GetPerspectiveProjectionMatrix(true);
|
||||
m_unskinnedXfBuffer->load(&unskinnedXf, sizeof(unskinnedXf));
|
||||
u8* dataOut = m_uniformData.get();
|
||||
|
||||
if (m_uvAnimBuffer)
|
||||
if (m_skinBankCount)
|
||||
{
|
||||
((CBooModel*)this)->m_uvAnimBuffer.Update(x4_matSet);
|
||||
m_uvMtxBuffer->load(m_uvAnimBuffer.m_buffer.data(),
|
||||
m_uvAnimBuffer.m_buffer.size() * 64);
|
||||
/* Skinned */
|
||||
for (size_t i=0 ; i<m_skinBankCount ; ++i)
|
||||
{
|
||||
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
|
||||
{
|
||||
zeus::CMatrix4f& mv = reinterpret_cast<zeus::CMatrix4f&>(*dataOut);
|
||||
mv = CGraphics::g_GXModelView.toMatrix4f();
|
||||
dataOut += sizeof(zeus::CMatrix4f);
|
||||
}
|
||||
for (size_t w=0 ; w<m_weightVecCount*4 ; ++w)
|
||||
{
|
||||
zeus::CMatrix4f& mvinv = reinterpret_cast<zeus::CMatrix4f&>(*dataOut);
|
||||
mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||
dataOut += sizeof(zeus::CMatrix4f);
|
||||
}
|
||||
zeus::CMatrix4f& proj = reinterpret_cast<zeus::CMatrix4f&>(*dataOut);
|
||||
proj = CGraphics::GetPerspectiveProjectionMatrix(true);
|
||||
dataOut += sizeof(zeus::CMatrix4f);
|
||||
|
||||
dataOut = m_uniformData.get() + ROUND_UP_256(dataOut - m_uniformData.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-Skinned */
|
||||
zeus::CMatrix4f& mv = reinterpret_cast<zeus::CMatrix4f&>(*dataOut);
|
||||
mv = CGraphics::g_GXModelView.toMatrix4f();
|
||||
dataOut += sizeof(zeus::CMatrix4f);
|
||||
|
||||
zeus::CMatrix4f& mvinv = reinterpret_cast<zeus::CMatrix4f&>(*dataOut);
|
||||
mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||
dataOut += sizeof(zeus::CMatrix4f);
|
||||
|
||||
zeus::CMatrix4f& proj = reinterpret_cast<zeus::CMatrix4f&>(*dataOut);
|
||||
proj = CGraphics::GetPerspectiveProjectionMatrix(true);
|
||||
dataOut += sizeof(zeus::CMatrix4f);
|
||||
|
||||
dataOut = m_uniformData.get() + ROUND_UP_256(dataOut - m_uniformData.get());
|
||||
}
|
||||
|
||||
UVAnimationBuffer::Update(dataOut, x4_matSet);
|
||||
|
||||
CModelShaders::LightingUniform& lightingOut = reinterpret_cast<CModelShaders::LightingUniform&>(*dataOut);
|
||||
lightingOut = m_lightingData;
|
||||
|
||||
m_uniformBuffer->load(m_uniformData.get(), m_uniformDataSize);
|
||||
}
|
||||
|
||||
void CBooModel::DrawAlpha(const CModelFlags& flags) const
|
||||
|
@ -378,7 +548,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
|||
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
|
||||
0, mat.uvAnims.size(), boo::Primitive(hmdlMeta.topology),
|
||||
true, true, true);
|
||||
matSet.m_shaders.push_back(CGraphics::g_ShaderCacheMgr->buildShader(tag, mat.heclIr, "CMDL", ctx));
|
||||
matSet.m_shaders.push_back(g_ModelShaders->buildExtendedShader(tag, mat.heclIr, "CMDL", ctx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,6 +563,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
|||
const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
|
||||
x8_surfaces.emplace_back();
|
||||
CBooSurface& surf = x8_surfaces.back();
|
||||
surf.selfIdx = i;
|
||||
athena::io::MemoryReader r(sec, surfSz);
|
||||
surf.m_data.read(r);
|
||||
}
|
||||
|
@ -401,7 +572,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
|||
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],
|
||||
m_vtxFmt, m_vbo, m_ibo,
|
||||
m_vtxFmt, m_vbo, m_ibo, 0, 0,
|
||||
aabb, flags & 0x2, false);
|
||||
}
|
||||
|
||||
|
@ -459,6 +630,38 @@ bool CModel::IsLoaded(int shaderIdx) const
|
|||
return loaded;
|
||||
}
|
||||
|
||||
hecl::Runtime::ShaderCacheExtensions
|
||||
CModelShaders::GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat)
|
||||
{
|
||||
switch (plat)
|
||||
{
|
||||
case boo::IGraphicsDataFactory::Platform::OGL:
|
||||
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
||||
return GetShaderExtensionsGLSL(plat);
|
||||
#if _WIN32
|
||||
case boo::IGraphicsDataFactory::Platform::D3D11:
|
||||
case boo::IGraphicsDataFactory::Platform::D3D12:
|
||||
return GetShaderExtensionsHLSL(plat);
|
||||
#endif
|
||||
#if BOO_HAS_METAL
|
||||
case boo::IGraphicsDataFactory::Platform::Metal:
|
||||
return GetShaderExtensionsMetal(plat);
|
||||
#endif
|
||||
default:
|
||||
return {boo::IGraphicsDataFactory::Platform::Null};
|
||||
}
|
||||
}
|
||||
|
||||
CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr,
|
||||
boo::IGraphicsDataFactory* gfxFactory)
|
||||
: m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {}
|
||||
|
||||
void CModelShaders::Initialize(const hecl::Runtime::FileStoreManager& storeMgr,
|
||||
boo::IGraphicsDataFactory* gfxFactory)
|
||||
{
|
||||
g_ModelShaders.emplace(storeMgr, gfxFactory);
|
||||
}
|
||||
|
||||
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
||||
std::unique_ptr<u8[]>&& in, u32 len,
|
||||
const urde::CVParamTransfer& vparms)
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef __PSHAG_CMODELSHADERS_HPP__
|
||||
#define __PSHAG_CMODELSHADERS_HPP__
|
||||
|
||||
#include "hecl/Runtime.hpp"
|
||||
#include "optional.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
#define URDE_MAX_LIGHTS 16
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CModelShaders
|
||||
{
|
||||
hecl::Runtime::ShaderCacheManager m_shaderCache;
|
||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat);
|
||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
|
||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);
|
||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat);
|
||||
public:
|
||||
struct Light
|
||||
{
|
||||
zeus::CVector3f pos;
|
||||
zeus::CVector3f dir;
|
||||
zeus::CColor color = zeus::CColor::skClear;
|
||||
float linAtt[4] = {1.f, 0.f, 0.f};
|
||||
float angAtt[4] = {1.f, 0.f, 0.f};
|
||||
};
|
||||
|
||||
struct LightingUniform
|
||||
{
|
||||
Light lights[URDE_MAX_LIGHTS];
|
||||
zeus::CColor ambient;
|
||||
};
|
||||
|
||||
static void Initialize(const hecl::Runtime::FileStoreManager& storeMgr,
|
||||
boo::IGraphicsDataFactory* gfxFactory);
|
||||
|
||||
CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr,
|
||||
boo::IGraphicsDataFactory* gfxFactory);
|
||||
|
||||
boo::IShaderPipeline* buildShader(const hecl::Runtime::ShaderTag& tag, const std::string& source,
|
||||
const std::string& diagName,
|
||||
boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
return m_shaderCache.buildShader(tag, source, diagName, ctx);
|
||||
}
|
||||
|
||||
boo::IShaderPipeline* buildShader(const hecl::Runtime::ShaderTag& tag, const hecl::Frontend::IR& ir,
|
||||
const std::string& diagName,
|
||||
boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
return m_shaderCache.buildShader(tag, ir, diagName, ctx);
|
||||
}
|
||||
|
||||
std::vector<boo::IShaderPipeline*> buildExtendedShader(const hecl::Runtime::ShaderTag& tag, const std::string& source,
|
||||
const std::string& diagName,
|
||||
boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
return m_shaderCache.buildExtendedShader(tag, source, diagName, ctx);
|
||||
}
|
||||
|
||||
std::vector<boo::IShaderPipeline*> buildExtendedShader(const hecl::Runtime::ShaderTag& tag, const hecl::Frontend::IR& ir,
|
||||
const std::string& diagName,
|
||||
boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
return m_shaderCache.buildExtendedShader(tag, ir, diagName, ctx);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __PSHAG_CMODELSHADERS_HPP__
|
|
@ -0,0 +1,51 @@
|
|||
#include "CModelShaders.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* LightingGLSL =
|
||||
"struct Light\n"
|
||||
"{\n"
|
||||
" vec4 pos;\n"
|
||||
" vec4 dir;\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 linAtt;\n"
|
||||
" vec4 angAtt;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"UBINDING2 uniform LightingUniform\n"
|
||||
"{\n"
|
||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
||||
" vec4 ambient;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vec4 LightingFunc(vec4 mvPosIn, vec4 mvNormIn)\n"
|
||||
"{\n"
|
||||
" vec4 ret = ambient;\n"
|
||||
" \n"
|
||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
||||
" {\n"
|
||||
" vec3 delta = mvPosIn.xyz - lights[i].pos.xyz;\n"
|
||||
" float dist = length(delta);\n"
|
||||
" float angDot = dot(normalize(delta), lights[i].dir.xyz);\n"
|
||||
" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n"
|
||||
" lights[i].linAtt[1] * dist +\n"
|
||||
" lights[i].linAtt[0]);\n"
|
||||
" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n"
|
||||
" lights[i].angAtt[1] * angDot +\n"
|
||||
" lights[i].angAtt[0];\n"
|
||||
" ret += lights[i].color * clamp(angAtt, 0.0, 1.0) * att * dot(normalize(-delta), mvNormIn.xyz);\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return clamp(ret, vec4(0.0,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1.0));\n"
|
||||
"}\n";
|
||||
|
||||
hecl::Runtime::ShaderCacheExtensions
|
||||
CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
|
||||
{
|
||||
hecl::Runtime::ShaderCacheExtensions ext(plat);
|
||||
ext.registerExtensionSlot({LightingGLSL, "LightingFunc"}, {});
|
||||
return ext;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#include "CModelShaders.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
hecl::Runtime::ShaderCacheExtensions
|
||||
CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat)
|
||||
{
|
||||
hecl::Runtime::ShaderCacheExtensions ext(plat);
|
||||
return ext;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#include "CModelShaders.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
hecl::Runtime::ShaderCacheExtensions
|
||||
CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat)
|
||||
{
|
||||
hecl::Runtime::ShaderCacheExtensions ext(plat);
|
||||
return ext;
|
||||
}
|
||||
|
||||
}
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit e53a5a8c8a7d1102a1a95e4e7a27554823f74fed
|
||||
Subproject commit 11c8c744fd62770660506d271ea9eff858ea4138
|
Loading…
Reference in New Issue