Initial CLight integration

This commit is contained in:
Jack Andersen 2016-04-03 16:32:57 -10:00
parent 36ed356886
commit dae2621d93
17 changed files with 495 additions and 109 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -5,6 +5,7 @@
#include <athena/DNAYaml.hpp>
#include "ProjectResourceFactoryMP1.hpp"
#include "Runtime/CSimplePool.hpp"
#include "hecl/Runtime.hpp"
namespace urde
{

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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__

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

@ -1 +1 @@
Subproject commit e53a5a8c8a7d1102a1a95e4e7a27554823f74fed
Subproject commit 11c8c744fd62770660506d271ea9eff858ea4138