CModelShaders vertex & uniform buffers (WIP)

This commit is contained in:
Luke Street 2020-10-21 01:49:38 -04:00
parent 7bffc621b8
commit 07c90c894a
6 changed files with 390 additions and 717 deletions

View File

@ -739,8 +739,8 @@ void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* g
if (search == x1c_areaListItems.end()) {
std::unordered_map<CAssetId, TCachedToken<CTexture>> textures;
std::vector<CBooModel*> models;
if (geometry->size()) {
(*geometry)[0].m_instance->MakeTexturesFromMats(textures, xc_store);
if (!geometry->empty()) {
geometry->at(0).m_instance->MakeTexturesFromMats(textures, xc_store);
models.reserve(geometry->size());
int instIdx = 0;
for (const CMetroidModelInstance& inst : *geometry) {
@ -764,29 +764,11 @@ void CBooRenderer::UpdateAreaUniforms(int areaIdx, EWorldShadowMode shadowMode,
SetupRendererStates();
CModelFlags flags;
int bufIdx;
if (shadowMode == EWorldShadowMode::WorldOnActorShadow) {
flags.m_extendedShader = EExtendedShader::SolidColor;
flags.x4_color = zeus::skBlack;
bufIdx = 1;
} else if (shadowMode == EWorldShadowMode::BallOnWorldShadow) {
flags = *ballShadowFlags;
bufIdx = 2;
} else if (shadowMode == EWorldShadowMode::BallOnWorldIds) {
flags.m_extendedShader = EExtendedShader::SolidColor;
bufIdx = 3;
} else {
flags.m_extendedShader = EExtendedShader::Lighting;
bufIdx = cubeFace == -1 ? 0 : 4 + cubeFace;
}
int bufIdx = 0;
for (CAreaListItem& item : x1c_areaListItems) {
if (areaIdx != -1 && item.x18_areaIdx != areaIdx)
continue;
item.m_shaderSet->m_geomLayout->Update(flags, nullptr, nullptr, &item.m_shaderSet->m_matSet,
item.m_shaderSet->m_geomLayout->GetSharedBuffer(bufIdx), nullptr);
if (shadowMode == EWorldShadowMode::BallOnWorldShadow || shadowMode == EWorldShadowMode::BallOnWorldIds)
continue;
@ -1107,13 +1089,10 @@ void CBooRenderer::CacheReflection(TReflectionCallback cb, void* ctx, bool clear
x2dc_reflectionAge = 0;
BindReflectionDrawTarget();
SViewport backupVp = g_Viewport;
SetViewport(0, 0, 256, 256);
hsh::clear_attachments(true, false);
cb(ctx, CBooModel::g_ReflectViewPos);
x14c_reflectionTex.resolve_color_binding(0, {{}, {256, 256}}, false);
ResolveReflectionDrawTarget();
BindMainDrawTarget();
SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
}
void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) {
@ -1421,4 +1400,22 @@ void CBooRenderer::DrawOverlappingWorldModelShadows(int alphaVal, const std::vec
}
}
void CBooRenderer::BindMainDrawTarget() {
CGraphics::g_SpareTexture.attach();
hsh::set_blend_constants(0.f, 0.f, 0.f, gx_DstAlphaValue);
CachedVP.x0_left = 0;
CachedVP.x4_top = 0;
#ifdef __SWITCH__
hsh::extent2d extent{1280, 720};
#else
hsh::extent2d extent = CGraphics::g_SpareTexture.Owner._VULKAN_SPIRV.Allocation->GetExtent();
#endif
CachedVP.x8_width = extent.w;
CachedVP.xc_height = extent.h;
CachedVP.x10_halfWidth = extent.w / 2.f;
CachedVP.x14_halfHeight = extent.h / 2.f;
CachedVP.aspect = extent.w / float(extent.h);
g_Viewport = CachedVP;
}
} // namespace urde

View File

@ -51,6 +51,7 @@ class CBooRenderer final : public IRenderer {
friend class CModel;
friend class CMorphBallShadow;
friend class CWorldTransManager;
friend class CModelShaders;
public:
struct ScanlinesVert {

View File

@ -62,6 +62,7 @@ runtime_add_hsh(Graphics
Shaders/CFogVolumePlaneShader.cpp
Shaders/CLineRendererShaders.cpp
Shaders/CMapSurfaceShader.cpp
Shaders/CModelShaders.cpp
Shaders/CParticleSwooshShaders.cpp
Shaders/CPhazonSuitFilter.cpp
Shaders/CRadarPaintShader.cpp

View File

@ -21,12 +21,15 @@ class CMetroidModelInstance {
friend class CBooRenderer;
friend class CGameArea;
public:
int x0_visorFlags;
zeus::CTransform x4_xf;
zeus::CAABox x34_aabb;
std::vector<CBooSurface> m_surfaces;
std::unique_ptr<CBooModel> m_instance;
hecl::HMDLMeta m_hmdlMeta;
hsh::owner<hsh::vertex_buffer_typeless> m_staticVbo;
hsh::owner<hsh::index_buffer<u32>> m_staticIbo;
public:
CMetroidModelInstance() = default;

View File

@ -74,25 +74,15 @@ struct CBooSurface {
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
struct GeometryUniformLayout {
mutable std::vector<hsh::dynamic_owner<hsh::uniform_buffer_typeless>> m_sharedBuffer;
size_t m_geomBufferSize = 0;
size_t m_skinBankCount = 0;
size_t m_weightVecCount = 0;
std::vector<size_t> m_skinOffs;
std::vector<size_t> m_skinSizes;
std::vector<size_t> m_uvOffs;
std::vector<size_t> m_uvSizes;
GeometryUniformLayout(const CModel* model, const MaterialSet* matSet);
void Update(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose,
const MaterialSet* matSet, hsh::dynamic_owner<hsh::uniform_buffer_typeless>& buf,
const MaterialSet* matSet, std::vector<hsh::dynamic_owner<hsh::uniform_buffer_typeless>>& buf,
const CBooModel* parent) const;
hsh::dynamic_owner<hsh::uniform_buffer_typeless> AllocateVertUniformBuffer() const;
void ReserveSharedBuffers(size_t size);
hsh::dynamic_owner<hsh::uniform_buffer_typeless>& GetSharedBuffer(size_t idx) const;
};
struct SShader {
@ -100,9 +90,7 @@ struct SShader {
MaterialSet m_matSet;
std::optional<GeometryUniformLayout> m_geomLayout;
int m_matSetIdx;
explicit SShader(int idx) : m_matSetIdx(idx) {
x0_textures.clear();
}
explicit SShader(int idx) : m_matSetIdx(idx) { x0_textures.clear(); }
void InitializeLayout(const CModel* model) { m_geomLayout.emplace(model, &m_matSet); }
void UnlockTextures();
};
@ -124,6 +112,7 @@ class CBooModel {
friend class CSkinnedModel;
friend struct GeometryUniformLayout;
friend class CModelShaders;
friend struct ModelInstance;
public:
enum class ESurfaceSelection { UnsortedOnly, SortedOnly, All };
@ -149,23 +138,16 @@ private:
u32 x44_areaInstanceIdx = UINT32_MAX;
struct UVAnimationBuffer {
static void ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim);
static void PadOutBuffer(u8*& bufStart, u8*& bufOut);
static void Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, const CBooModel* parent);
static void ProcessAnimation(CModelShaders::TCGMatrix& tcg, const MaterialSet::Material::PASS& anim);
static void Update(std::vector<hsh::dynamic_owner<hsh::uniform_buffer<CModelShaders::TCGMatrixUniform>>>& uniforms,
const MaterialSet* matSet, const CModelFlags& flags, const CBooModel* parent);
};
CModelShaders::LightingUniform m_lightingData;
CModelShaders::FragmentUniform m_lightingData{};
bool m_lightsActive = false;
/* urde addition: boo! */
size_t m_uniformDataSize = 0;
struct ModelInstance {
hsh::dynamic_owner<hsh::uniform_buffer_typeless> m_geomUniformBuffer;
hsh::dynamic_owner<hsh::uniform_buffer_typeless> m_uniformBuffer;
std::vector<std::vector<hsh::binding>> m_shaderDataBindings;
hsh::dynamic_owner<hsh::vertex_buffer_typeless> m_dynamicVbo;
hsh::vertex_buffer_typeless GetBooVBO(const CBooModel& model);
};
std::vector<ModelInstance> m_instances;
ModelInstance m_ballShadowInstance;
@ -181,8 +163,7 @@ private:
void DrawNormalSurfaces(const CModelFlags& flags) const;
void DrawSurfaces(const CModelFlags& flags) const;
void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
void WarmupDrawSurfaces() const;
void WarmupDrawSurface(const CBooSurface& surf) const;
void WarmupDrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
static inline zeus::CVector3f g_PlayerPosition;
static inline float g_ModSeconds = 0.0f;
@ -196,13 +177,11 @@ private:
public:
~CBooModel();
CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
hsh::vertex_buffer_typeless vbo,
hsh::index_buffer_typeless ibo,
const zeus::CAABox& aabb, u8 renderMask, int numInsts);
hsh::vertex_buffer_typeless vbo, hsh::index_buffer<u32> ibo, const zeus::CAABox& aabb, u8 renderMask,
int numInsts, VertexFormat vtxFmt);
static void MakeTexturesFromMats(const MaterialSet& matSet,
std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut,
IObjectStore& store);
std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut, IObjectStore& store);
void MakeTexturesFromMats(std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut, IObjectStore& store);
bool IsOpaque() const { return x3c_firstSortedSurface == nullptr; }
@ -216,7 +195,8 @@ public:
void Touch(int shaderIdx);
void VerifyCurrentShader(int shaderIdx);
hsh::dynamic_owner<hsh::vertex_buffer_typeless>* UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr,
const CPoseAsTransforms* pose, int sharedLayoutBuf = -1);
const CPoseAsTransforms* pose,
int sharedLayoutBuf = -1);
void DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose);
void DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose);
void Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose);
@ -237,8 +217,8 @@ public:
static inline zeus::CVector3f g_ReflectViewPos;
static void KillCachedViewDepState();
static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, zeus::CMatrix4f* mtxsOut,
float& alphaOut);
static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf,
hsh::dynamic_owner<hsh::uniform_buffer<CModelShaders::ReflectMtx>>& buf);
static hsh::texture2d g_shadowMap;
static zeus::CTransform g_shadowTexXf;
@ -257,6 +237,7 @@ public:
static void Shutdown();
const zeus::CAABox& GetAABB() const { return x20_aabb; }
void WarmupDrawSurfaces(const CModelFlags& unsortedFlags, const CModelFlags& sortedFlags) const;
};
class CModel {
@ -297,9 +278,7 @@ public:
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
u32 GetNumMaterialSets() const { return x18_matSets.size(); }
size_t GetPoolVertexOffset(size_t idx) const;
zeus::CVector3f GetPoolVertex(size_t idx) const;
size_t GetPoolNormalOffset(size_t idx) const;
zeus::CVector3f GetPoolNormal(size_t idx) const;
void ApplyVerticesCPU(hsh::dynamic_owner<hsh::vertex_buffer_typeless>& vertBuf,
const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn) const;
@ -315,4 +294,42 @@ public:
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag, std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms, CObjectReference* selfRef);
template <typename F>
constexpr auto MapVertData(const hecl::HMDLMeta& meta, F&& Func) {
#define WEIGHT_COUNT(uvs, weights) \
case weights: { \
using VertData = CModelShaders::VertData<0, uvs, weights>; \
assert(sizeof(VertData) == meta.vertStride && "Vert data stride mismatch"); \
return Func.template operator()<VertData>(); \
break; \
}
#define UV_COUNT(uvs) \
case uvs: \
switch (meta.weightCount) { \
WEIGHT_COUNT(uvs, 0); \
WEIGHT_COUNT(uvs, 1); \
WEIGHT_COUNT(uvs, 2); \
WEIGHT_COUNT(uvs, 3); \
WEIGHT_COUNT(uvs, 4); \
WEIGHT_COUNT(uvs, 5); \
default: \
assert(false && "Unhandled weight count"); \
break; \
} \
break;
switch (meta.uvCount) {
UV_COUNT(0)
UV_COUNT(1)
UV_COUNT(2)
UV_COUNT(3)
UV_COUNT(4)
UV_COUNT(5)
#undef UV_COUNT
#undef WEIGHT_COUNT
default:
assert(false && "Unhandled UV count");
}
// fallback
return Func.template operator()<CModelShaders::VertData<0, 0, 0>>();
}
} // namespace urde

File diff suppressed because it is too large Load Diff