CCubeRenderer: Start getting world rendering implemented

This commit is contained in:
Phillip Stephens 2022-03-05 20:50:54 -08:00
parent 6c3e74b93e
commit 2bdfe96134
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
8 changed files with 163 additions and 32 deletions

View File

@ -426,4 +426,15 @@ void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) {
// CCubeModel::sShadowTexture->Load(texCount, EClampMode::One);
// TODO
}
static GX::TevStageID sCurrentTevStage = GX::NULL_STAGE;
void CCubeMaterial::EnsureTevsDirect() {
if (sCurrentTevStage == GX::NULL_STAGE) {
return;
}
//CGX::SetNumIndStages(0);
//CGX::SetTevDirect(sCurrentTevStage);
sCurrentTevStage = GX::NULL_STAGE;
}
} // namespace metaforce

View File

@ -88,6 +88,7 @@ public:
static void ResetCachedMaterials();
static void EnsureViewDepStateCached(const CCubeSurface* surface);
static void KillCachedViewDepState();
static void EnsureTevsDirect();
private:
void SetCurrentBlack();

View File

@ -91,6 +91,12 @@ public:
void DrawSurfaceWireframe(const CCubeSurface& surface);
void SetArraysCurrent();
void SetUsingPackedLightmaps(bool v);
bool AreaTexturesLoaded() const { return x40_24_texturesLoaded; }
bool IsVisible() const { return x40_25_modelVisible; }
[[nodiscard]] CCubeSurface* GetFirstUnsortedSurface() { return x38_firstUnsortedSurf; }
[[nodiscard]] const CCubeSurface* GetFirstUnsortedSurface() const { return x38_firstUnsortedSurf; }
[[nodiscard]] CCubeSurface* GetFirstSortedSurface() { return x3c_firstSortedSurf; }
[[nodiscard]] const CCubeSurface* GetFirstSortedSurface() const { return x3c_firstSortedSurf; }
[[nodiscard]] TVectorRef GetPositions() const { return x0_modelInstance.GetVertexPointer(); }
[[nodiscard]] TVectorRef GetNormals() const { return x0_modelInstance.GetNormalPointer(); }

View File

@ -2,10 +2,14 @@
#include "Runtime/GameGlobalObjects.hpp"
#include "Runtime/Graphics/CDrawable.hpp"
#include "Runtime/Graphics/CMetroidModelInstance.hpp"
#include "Runtime/Graphics/CDrawablePlaneObject.hpp"
#include "Runtime/Graphics/CLight.hpp"
#include "Runtime/Graphics/CModel.hpp"
#include "Runtime/Particle/CParticleGen.hpp"
#include "Runtime/Graphics/CCubeModel.hpp"
#include "Runtime/Graphics/CCubeSurface.hpp"
#include "Runtime/Graphics/CCubeMaterial.hpp"
namespace metaforce {
static logvisor::Module Log("CCubeRenderer");
@ -169,8 +173,9 @@ void Buckets::Init() {
CCubeRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
const CAreaRenderOctTree* octTree,
std::unordered_map<CAssetId, TCachedToken<CTexture>>&& textures,
std::vector<CCubeModel*>&& models, int areaIdx)
std::unique_ptr<std::vector<TCachedToken<CTexture>>>&& textures,
std::unique_ptr<std::vector<std::unique_ptr<CCubeModel>>>&& models,
int areaIdx)
: x0_geometry(geom)
, x4_octTree(octTree)
, x8_textures(std::move(textures))
@ -178,9 +183,9 @@ CCubeRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInsta
, x18_areaIdx(areaIdx) {}
CCubeRenderer::CCubeRenderer(IObjectStore& store, IFactory& resFac) : x8_factory(resFac), xc_store(store) {
// void* data = xe4_blackTex.GetBitMapData();
// memset(data, 0, 32);
// xe4_blackTex.UnLock();
void* data = xe4_blackTex.Lock();
memset(data, 0, 32);
xe4_blackTex.UnLock();
GenerateReflectionTex();
GenerateFogVolumeRampTex();
GenerateSphereRampTex();
@ -201,8 +206,42 @@ void CCubeRenderer::ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertC
float scale, float offX, float offY) {}
void CCubeRenderer::ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, const CTexture& maskTex) {}
void CCubeRenderer::DoPhazonSuitIndirectAlphaBlur(float blurRadius, float f2, const TLockedToken<CTexture>& indTex) {}
void CCubeRenderer::AddWorldSurfaces(CCubeModel& model) {
for (auto* it = model.GetFirstSortedSurface(); it != nullptr; it = it->GetNextSurface()) {
auto mat = model.GetMaterialByIndex(it->GetMaterialIndex());
auto blend = mat.GetCompressedBlend();
auto bounds = it->GetBounds();
auto pos = bounds.closestPointAlongVector(xb0_viewPlane.normal());
Buckets::Insert(pos, bounds, EDrawableType::WorldSurface, it, xb0_viewPlane, static_cast<u16>(blend == 0x50004));
}
}
void CCubeRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry,
const CAreaRenderOctTree* octTree, int areaIdx) {}
const CAreaRenderOctTree* octTree, int areaIdx) {
auto search = FindStaticGeometry(geometry);
if (search == x1c_areaListItems.end()) {
auto textures = std::make_unique<std::vector<TCachedToken<CTexture>>>();
auto models = std::make_unique<std::vector<std::unique_ptr<CCubeModel>>>();
if (!geometry->empty()) {
CCubeModel::MakeTexturesFromMats((*geometry)[0].GetMaterialPointer(), *textures.get(), &xc_store, false);
models->reserve(geometry->size());
int instIdx = 0;
for (const CMetroidModelInstance& inst : *geometry) {
models->emplace_back(
std::make_unique<CCubeModel>(const_cast<std::vector<CCubeSurface>*>(inst.GetSurfaces()), textures.get(),
const_cast<u8*>(inst.GetMaterialPointer()),
const_cast<std::vector<zeus::CVector3f>*>(inst.GetVertexPointer()),
const_cast<std::vector<zeus::CColor>*>(inst.GetColorPointer()),
const_cast<std::vector<zeus::CVector3f>*>(inst.GetNormalPointer()),
const_cast<std::vector<zeus::CVector2f>*>(inst.GetTCPointer()),
const_cast<std::vector<zeus::CVector2f>*>(inst.GetPackedTCPointer()),
inst.GetBoundingBox(), inst.GetFlags(), false, instIdx));
++instIdx;
}
}
x1c_areaListItems.emplace_back(geometry, octTree, std::move(textures), std::move(models), areaIdx);
}
}
void CCubeRenderer::EnablePVS(const CPVSVisSet& set, u32 areaIdx) {
if (!xdc_) {
@ -220,15 +259,32 @@ void CCubeRenderer::DisablePVS() { xc8_pvs.reset(); }
void CCubeRenderer::RemoveStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) {}
void CCubeRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask, bool shadowRender) {}
void CCubeRenderer::DrawSortedGeometry(int areaIdx, int mask, int targetMask) {
//SetupRenderState();
//TODO: Loop
SetupRendererStates(true);
const CAreaListItem* item = nullptr;
for (const auto& areaListItem : x1c_areaListItems) {
if (areaIdx == -1 || areaIdx == areaListItem.x18_areaIdx) {
if (areaListItem.x4_octTree != nullptr) {
item = &areaListItem;
}
for (const auto& model : *areaListItem.x10_models) {
if (model->IsVisible()) {
AddWorldSurfaces(*model);
}
}
}
}
Buckets::Sort();
//RenderBucketItems(items);
//DrawRenderBucketsDebug();
RenderBucketItems(item);
SetupCGraphicsState();
DrawRenderBucketsDebug();
Buckets::Clear();
}
void CCubeRenderer::DrawStaticGeometry(int areaIdx, int mask, int targetMask) {}
void CCubeRenderer::DrawAreaGeometry(int areaIdx, int mask, int targetMask) {}
void CCubeRenderer::RenderBucketItems(const CAreaListItem* lights) {}
void CCubeRenderer::PostRenderFogs() {}
void CCubeRenderer::SetModelMatrix(const zeus::CTransform& xf) { CGraphics::SetModelMatrix(xf); }
@ -300,7 +356,18 @@ void CCubeRenderer::SetPerspective(float fovy, float width, float height, float
}
std::pair<zeus::CVector2f, zeus::CVector2f> CCubeRenderer::SetViewportOrtho(bool centered, float znear, float zfar) {
return std::pair<zeus::CVector2f, zeus::CVector2f>();
auto left = static_cast<float>(centered ? CGraphics::GetViewportLeft() - CGraphics::GetViewportWidth() / 2
: CGraphics::GetViewportLeft());
auto top = static_cast<float>(centered ? CGraphics::GetViewportTop() - CGraphics::GetViewportHeight() / 2
: CGraphics::GetViewportHeight());
auto right = static_cast<float>(CGraphics::GetViewportLeft() +
(centered ? CGraphics::GetViewportWidth() / 2 : CGraphics::GetViewportWidth()));
auto bottom = static_cast<float>(CGraphics::GetViewportTop() +
(centered ? CGraphics::GetViewportHeight() / 2 : CGraphics::GetViewportHeight()));
CGraphics::SetOrtho(left, right, top, bottom, znear, zfar);
CGraphics::SetViewPointMatrix({});
CGraphics::SetModelMatrix({});
return {{left, top}, {right, bottom}};
}
void CCubeRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) { x44_frustumPlanes = frustum; }
@ -359,18 +426,31 @@ void CCubeRenderer::SetDebugOption(IRenderer::EDebugOption option, int value) {
}
}
void CCubeRenderer::BeginPrimitive(IRenderer::EPrimitiveType, int) {}
void CCubeRenderer::BeginLines(int) {}
void CCubeRenderer::BeginLineStrip(int) {}
void CCubeRenderer::BeginTriangles(int) {}
void CCubeRenderer::BeginTriangleStrip(int) {}
void CCubeRenderer::BeginTriangleFan(int) {}
void CCubeRenderer::PrimVertex(const zeus::CVector3f&) {}
void CCubeRenderer::PrimNormal(const zeus::CVector3f&) {}
void CCubeRenderer::PrimColor(float, float, float, float) {}
void CCubeRenderer::PrimColor(const zeus::CColor&) {}
void CCubeRenderer::EndPrimitive() {}
void CCubeRenderer::SetAmbientColor(const zeus::CColor& color) {}
void CCubeRenderer::BeginPrimitive(IRenderer::EPrimitiveType type, s32 nverts) {
x18_primVertCount = nverts;
CGraphics::StreamBegin(GX::Primitive(type));
}
void CCubeRenderer::BeginLines(s32 nverts) { BeginPrimitive(EPrimitiveType::Lines, nverts); }
void CCubeRenderer::BeginLineStrip(s32 nverts) { BeginPrimitive(EPrimitiveType::LineStrip, nverts); }
void CCubeRenderer::BeginTriangles(s32 nverts) { BeginPrimitive(EPrimitiveType::Triangles, nverts); }
void CCubeRenderer::BeginTriangleStrip(s32 nverts) { BeginPrimitive(EPrimitiveType::TriangleStrip, nverts); }
void CCubeRenderer::BeginTriangleFan(s32 nverts) { BeginPrimitive(EPrimitiveType::TriangleFan, nverts); }
void CCubeRenderer::PrimVertex(const zeus::CVector3f& vertex) {
--x18_primVertCount;
CGraphics::StreamColor(x2e0_primColor);
CGraphics::StreamNormal(x2e4_primNormal);
CGraphics::StreamVertex(vertex);
}
void CCubeRenderer::PrimNormal(const zeus::CVector3f& normal) { x2e4_primNormal = normal; }
void CCubeRenderer::PrimColor(float r, float g, float b, float a) { PrimColor({r, g, b, a}); }
void CCubeRenderer::PrimColor(const zeus::CColor& color) { x2e0_primColor = color; }
void CCubeRenderer::EndPrimitive() {
while (x18_primVertCount > 0) {
PrimVertex(zeus::skZero3f);
}
CGraphics::StreamEnd();
}
void CCubeRenderer::SetAmbientColor(const zeus::CColor& color) { CGraphics::SetAmbientColor(color); }
void CCubeRenderer::DrawString(const char* string, int x, int y) { x10_font.DrawString(string, x, y, zeus::skWhite); }
u32 CCubeRenderer::GetFPS() { return CGraphics::GetFPS(); }
@ -406,6 +486,13 @@ void CCubeRenderer::DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirect
const TLockedToken<CTexture>& indTex, const zeus::CColor& indirectMod,
float blurRadius, float scale, float offX, float offY) {}
void CCubeRenderer::DrawXRayOutline(const zeus::CAABox& aabb) {}
std::list<CCubeRenderer::CAreaListItem>::iterator
CCubeRenderer::FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) {
return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(),
[&](const CAreaListItem& item) { return item.x0_geometry == geometry; });
}
void CCubeRenderer::FindOverlappingWorldModels(std::vector<u32>& modelBits, const zeus::CAABox& aabb) const {}
int CCubeRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector<u32>& modelBits,
const zeus::CAABox& aabb) {
@ -413,4 +500,15 @@ int CCubeRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector<
}
void CCubeRenderer::DrawOverlappingWorldModelShadows(int alphaVal, const std::vector<u32>& modelBits,
const zeus::CAABox& aabb, float alpha) {}
void CCubeRenderer::SetupCGraphicsState() {
CGraphics::DisableAllLights();
CGraphics::SetModelMatrix({});
CTevCombiners::ResetStates();
CGraphics::SetAmbientColor({0.4f});
// CGX::SetChanMatColor(EChannelId::Channel0, GX::Color{0xFFFFFFFF});
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true);
// CGX::SetChanCtrl(EChannelId::Channel1, false, GX::SRC_REG, GX::LIGHT_NULL, GX::DF_NONE, GX::AF_NONE);
CCubeMaterial::EnsureTevsDirect();
}
} // namespace metaforce

View File

@ -23,15 +23,15 @@ class CCubeRenderer final : public IRenderer {
const std::vector<CMetroidModelInstance>* x0_geometry;
const CAreaRenderOctTree* x4_octTree;
/* originally auto_ptrs of vectors */
std::unordered_map<CAssetId, TCachedToken<CTexture>> x8_textures;
std::vector<CCubeModel*> x10_models;
std::unique_ptr<std::vector<TCachedToken<CTexture>>> x8_textures;
std::unique_ptr<std::vector<std::unique_ptr<CCubeModel>>> x10_models;
int x18_areaIdx;
/* Per-area octree-word major, light bits minor */
std::vector<u32> x1c_lightOctreeWords;
CAreaListItem(const std::vector<CMetroidModelInstance>* geom, const CAreaRenderOctTree* octTree,
std::unordered_map<CAssetId, TCachedToken<CTexture>>&& textures, std::vector<CCubeModel*>&& models,
int areaIdx);
std::unique_ptr<std::vector<TCachedToken<CTexture>>>&& textures,
std::unique_ptr<std::vector<std::unique_ptr<CCubeModel>>>&& models, int areaIdx);
};
struct CFogVolumeListItem {
@ -53,7 +53,7 @@ private:
IFactory& x8_factory;
IObjectStore& xc_store;
CFont x10_font{1.f};
// u32 x18_ = 0;
u32 x18_primVertCount = 0;
std::list<CAreaListItem> x1c_areaListItems;
// TODO x34...x40
zeus::CFrustum x44_frustumPlanes; // {zeus::skIdentityMatrix4f, 1.5707964f, 1.f, 1.f, false, 100.f}
@ -74,8 +74,8 @@ private:
std::list<CFogVolumeListItem> x2ac_fogVolumes;
std::list<std::pair<zeus::CVector3f, float>> x2c4_spaceWarps;
u32 x2dc_reflectionAge = 2;
zeus::CColor x2e0_ = zeus::skWhite;
zeus::CVector3f x2e4_ = zeus::skForward;
zeus::CColor x2e0_primColor = zeus::skWhite;
zeus::CVector3f x2e4_primNormal = zeus::skForward;
float x2f0_thermalVisorLevel = 1.f;
zeus::CColor x2f4_thermColor{1.f, 0.f, 1.f, 1.f};
float x2f8_thermColdScale = 0.f; // ??? byte in code
@ -107,6 +107,7 @@ public:
CCubeRenderer(IObjectStore& store, IFactory& resFac);
~CCubeRenderer() override;
void AddWorldSurfaces(CCubeModel& model);
void AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry, const CAreaRenderOctTree* octTree,
int areaIdx) override;
void EnablePVS(const CPVSVisSet& set, u32 areaIdx) override;
@ -203,15 +204,21 @@ public:
const zeus::CColor& indirectMod, float blurRadius, float scale, float offX,
float offY);
void DrawXRayOutline(const zeus::CAABox& aabb);
std::list<CAreaListItem>::iterator FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry);
void FindOverlappingWorldModels(std::vector<u32>& modelBits, const zeus::CAABox& aabb) const;
int DrawOverlappingWorldModelIDs(int alphaVal, const std::vector<u32>& modelBits, const zeus::CAABox& aabb);
void DrawOverlappingWorldModelShadows(int alphaVal, const std::vector<u32>& modelBits, const zeus::CAABox& aabb,
float alpha);
void RenderBucketItems(const CAreaListItem* lights);
void DrawRenderBucketsDebug() {}
void SetupRendererStates(bool b) {}
// Getters
[[nodiscard]] bool IsInAreaDraw() const { return x318_30_inAreaDraw; }
[[nodiscard]] bool IsReflectionDirty() const { return x318_24_refectionDirty; }
void SetReflectionDirty(bool v) { x318_24_refectionDirty = v; }
[[nodiscard]] bool IsThermalVisorActive() const { return x318_29_thermalVisor; }
static void SetupCGraphicsState();
};
} // namespace metaforce

View File

@ -34,6 +34,7 @@ public:
[[nodiscard]] u32 GetFlags() const { return x0_visorFlags; }
[[nodiscard]] const zeus::CAABox& GetBoundingBox() const { return x34_worldAABB; }
[[nodiscard]] std::vector<CCubeSurface>* GetSurfaces() { return &x50_surfaces; }
[[nodiscard]] const std::vector<CCubeSurface>* GetSurfaces() const { return &x50_surfaces; }
[[nodiscard]] const u8* GetMaterialPointer() const { return x4c_materialData; }
[[nodiscard]] TVectorRef GetVertexPointer() const { return &x60_positions; }

View File

@ -476,7 +476,8 @@ enum TevStageID {
TEVSTAGE13,
TEVSTAGE14,
TEVSTAGE15,
MAX_TEVSTAGE
MAX_TEVSTAGE,
NULL_STAGE = -1,
};
enum IndTexFormat {

View File

@ -32,7 +32,13 @@ public:
enum class EDrawableSorting { SortedCallback, UnsortedCallback };
enum class EDebugOption { Invalid = -1, PVSMode, PVSState, FogDisabled };
enum class EPrimitiveType {};
enum class EPrimitiveType {
Triangles = GX::TRIANGLES,
TriangleFan = GX::TRIANGLEFAN,
TriangleStrip = GX::TRIANGLESTRIP,
Lines = GX::LINES,
LineStrip = GX::LINESTRIP,
};
virtual ~IRenderer() = default;
virtual void AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry, const CAreaRenderOctTree* octTree,