mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-13 03:26:07 +00:00
More CCubeRenderer
This commit is contained in:
@@ -1,14 +1,32 @@
|
||||
#include "MetaRender/CCubeRenderer.hpp"
|
||||
|
||||
#include "Kyoto/Animation/CSkinnedModel.hpp"
|
||||
#include "Kyoto/Graphics/CColor.hpp"
|
||||
#include "Kyoto/Graphics/CCubeModel.hpp"
|
||||
#include "Kyoto/Graphics/CCubeSurface.hpp"
|
||||
#include "Kyoto/Graphics/CDrawable.hpp"
|
||||
#include "Kyoto/Graphics/CDrawablePlaneObject.hpp"
|
||||
#include "Kyoto/Graphics/CGX.hpp"
|
||||
#include "Kyoto/Graphics/CGraphics.hpp"
|
||||
#include "Kyoto/Graphics/CGraphicsPalette.hpp"
|
||||
#include "Kyoto/Graphics/CLight.hpp" // IWYU pragma: keep
|
||||
#include "Kyoto/Graphics/CModelFlags.hpp"
|
||||
#include "Kyoto/Graphics/CTexture.hpp"
|
||||
#include "Kyoto/IObjectStore.hpp"
|
||||
#include "Kyoto/Math/CFrustumPlanes.hpp"
|
||||
#include "Kyoto/Math/CPlane.hpp"
|
||||
#include "Kyoto/Math/CTransform4f.hpp"
|
||||
#include "Kyoto/Math/CUnitVector3f.hpp"
|
||||
#include "Kyoto/Math/CVector2f.hpp"
|
||||
#include "Kyoto/Math/CVector3f.hpp"
|
||||
#include "MetaRender/IRenderer.hpp"
|
||||
#include "Weapons/IWeaponRenderer.hpp"
|
||||
#include "WorldFormat/CMetroidModelInstance.hpp"
|
||||
#include "dolphin/gx/GXEnum.h"
|
||||
#include "dolphin/gx/GXGeometry.h"
|
||||
#include "dolphin/gx/GXVert.h"
|
||||
#include "dolphin/types.h"
|
||||
#include "rstl/auto_ptr.hpp"
|
||||
#include "rstl/math.hpp"
|
||||
#include "rstl/pair.hpp"
|
||||
#include "rstl/reserved_vector.hpp"
|
||||
@@ -34,7 +52,7 @@ static rstl::reserved_vector< ushort, 8 >* sPlaneObjectBucket;
|
||||
|
||||
void Init() {
|
||||
#define HOLDER(var) \
|
||||
static uchar var##Holder[sizeof(__typeof__(*var))]; \
|
||||
static uchar var##Holder[sizeof(__typeof__(*var)) + 4]; \
|
||||
var = new (var##Holder) std::type_identity< __typeof__(*var) >::type();
|
||||
|
||||
HOLDER(sData);
|
||||
@@ -42,7 +60,7 @@ void Init() {
|
||||
HOLDER(sPlaneObjectData);
|
||||
HOLDER(sPlaneObjectBucket);
|
||||
|
||||
sBuckets->resize(50, BucketHolderType());
|
||||
sBuckets->resize(50);
|
||||
sMinMaxDistance = skWorstMinMaxDistance;
|
||||
}
|
||||
|
||||
@@ -54,13 +72,14 @@ void Shutdown() {
|
||||
}
|
||||
|
||||
// TODO non-matching
|
||||
void Insert(const CVector3f& pos, const CAABox& aabb, EDrawableType dtype, const void* data,
|
||||
void Insert(const CVector3f& pos, const CAABox& aabb, ushort dtype, const void* data,
|
||||
const CPlane& plane, ushort extraSort) {
|
||||
if (sData->size() == sData->capacity()) {
|
||||
return;
|
||||
}
|
||||
float dist = plane.GetHeight(pos);
|
||||
sData->push_back(CDrawable(dtype, extraSort, dist, aabb, const_cast< void* >(data)));
|
||||
const CDrawable& drawable = CDrawable(dtype, extraSort, dist, aabb, const_cast< void* >(data));
|
||||
sData->push_back(drawable);
|
||||
sMinMaxDistance.first = rstl::min_val(dist, sMinMaxDistance.first);
|
||||
sMinMaxDistance.second = rstl::max_val(dist, sMinMaxDistance.second);
|
||||
#ifdef __MWERKS__
|
||||
@@ -90,13 +109,9 @@ void Clear() {
|
||||
} // namespace Buckets
|
||||
|
||||
CCubeRenderer::CAreaListItem::CAreaListItem(
|
||||
const rstl::vector< CMetroidModelInstance, rstl::rmemory_allocator >* geometry,
|
||||
const CAreaOctTree* octTree,
|
||||
const rstl::auto_ptr< rstl::vector< TCachedToken< CTexture >, rstl::rmemory_allocator > >&
|
||||
textures,
|
||||
const rstl::auto_ptr< rstl::vector< rstl::auto_ptr< CCubeModel >, rstl::rmemory_allocator > >&
|
||||
models,
|
||||
int areaIdx)
|
||||
const rstl::vector< CMetroidModelInstance >* geometry, const CAreaOctTree* octTree,
|
||||
const rstl::auto_ptr< rstl::vector< TCachedToken< CTexture > > >& textures,
|
||||
const rstl::auto_ptr< rstl::vector< rstl::auto_ptr< CCubeModel > > >& models, int areaIdx)
|
||||
: x0_geometry(geometry)
|
||||
, x4_octTree(octTree)
|
||||
, x8_textures(textures)
|
||||
@@ -114,12 +129,7 @@ CCubeRenderer::CCubeRenderer(IObjectStore& objStore, COsContext& osContext, CMem
|
||||
, x10_font(1.f)
|
||||
, x18_primVertCount(0)
|
||||
, x1c_areaListItems()
|
||||
#if NONMATCHING
|
||||
, x34_unk1(0)
|
||||
#endif
|
||||
, x38_unk2(0)
|
||||
, x3c_unk3(0)
|
||||
, x40_unk4(0)
|
||||
, x34_surfaces()
|
||||
, x44_frustumPlanes(CTransform4f::Identity(), 1.5707964f, 1.f, 1.f, false, 100.f)
|
||||
, xa8_drawableCallback(nullptr)
|
||||
#if NONMATCHING
|
||||
@@ -170,3 +180,305 @@ CCubeRenderer::CCubeRenderer(IObjectStore& objStore, COsContext& osContext, CMem
|
||||
Buckets::Init();
|
||||
fn_80352740();
|
||||
}
|
||||
|
||||
void CCubeRenderer::GenerateReflectionTex() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::GenerateFogVolumeRampTex() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::GenerateSphereRampTex() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::LoadThermoPalette() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
CCubeRenderer::~CCubeRenderer() {
|
||||
sRenderer = nullptr;
|
||||
Buckets::Shutdown();
|
||||
CSkinnedModel::RemoveDummySkinnedModelRef();
|
||||
if (!x314_phazonSuitMask.null()) {
|
||||
x314_phazonSuitMask->fn_8030E10C();
|
||||
}
|
||||
}
|
||||
|
||||
void CCubeRenderer::AddStaticGeometry(const rstl::vector< CMetroidModelInstance >* geometry,
|
||||
const CAreaOctTree* octTree, int areaIdx) {
|
||||
if (FindStaticGeometry(geometry) == x1c_areaListItems.end()) {
|
||||
rstl::auto_ptr< rstl::vector< rstl::auto_ptr< CCubeModel > > > models =
|
||||
rs_new rstl::vector< rstl::auto_ptr< CCubeModel > >();
|
||||
rstl::auto_ptr< rstl::vector< TCachedToken< CTexture > > > textures =
|
||||
rs_new rstl::vector< TCachedToken< CTexture > >();
|
||||
if (!geometry->empty()) {
|
||||
CCubeModel::MakeTexturesFromMats(geometry->front().GetMaterialPointer(), *textures,
|
||||
xc_objStore, false);
|
||||
models->reserve(geometry->size());
|
||||
for (int i = 0; i < geometry->size(); ++i) {
|
||||
const CMetroidModelInstance* it = &geometry->at(i);
|
||||
models->push_back(rs_new CCubeModel(
|
||||
const_cast< rstl::vector< void* >* >(&it->GetSurfaces()), textures.get(),
|
||||
it->GetMaterialPointer(), it->GetVertexPointer(), it->GetColorPointer(),
|
||||
it->GetNormalPointer(), it->GetTCPointer(), it->GetPackedTCPointer(),
|
||||
it->GetBoundingBox(), it->GetFlags(), false, i));
|
||||
}
|
||||
}
|
||||
x1c_areaListItems.push_back(CAreaListItem(geometry, octTree, textures, models, areaIdx));
|
||||
GXInvalidateVtxCache();
|
||||
}
|
||||
}
|
||||
|
||||
rstl::list< CCubeRenderer::CAreaListItem >::iterator
|
||||
CCubeRenderer::FindStaticGeometry(const rstl::vector< CMetroidModelInstance >* geometry) {
|
||||
for (AUTO(it, x1c_areaListItems.begin()); it != x1c_areaListItems.end(); ++it) {
|
||||
if (it->x0_geometry == geometry) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return x1c_areaListItems.end();
|
||||
}
|
||||
|
||||
void CCubeRenderer::RemoveStaticGeometry(const rstl::vector< CMetroidModelInstance >* geometry) {
|
||||
AUTO(search, FindStaticGeometry(geometry));
|
||||
if (search != x1c_areaListItems.end()) {
|
||||
x1c_areaListItems.erase(search);
|
||||
}
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetModelMatrix(const CTransform4f& xf) { CGraphics::SetModelMatrix(xf); }
|
||||
|
||||
// TODO non-matching
|
||||
void CCubeRenderer::SetWorldViewpoint(const CTransform4f& xf) {
|
||||
CGraphics::SetViewPointMatrix(xf);
|
||||
const CUnitVector3f forward(xf.GetColumn(kDY), CUnitVector3f::kN_No);
|
||||
xb0_viewPlane = CPlane(CVector3f::Dot(forward, xf.GetTranslation()), forward);
|
||||
}
|
||||
|
||||
void CCubeRenderer::BeginScene() {
|
||||
int width = CGraphics::GetViewport().mWidth;
|
||||
int height = CGraphics::GetViewport().mHeight;
|
||||
CGraphics::SetUseVideoFilter(true);
|
||||
CGraphics::SetViewport(0, 0, width, height);
|
||||
CGraphics::SetClearColor(CColor(static_cast< uchar >(0), static_cast< uchar >(0),
|
||||
static_cast< uchar >(0), static_cast< uchar >(0)));
|
||||
CGraphics::SetCullMode(kCM_Front);
|
||||
CGraphics::SetDepthWriteMode(true, kE_LEqual, true);
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_InvSrcAlpha, kLO_Clear);
|
||||
#if NONMATCHING
|
||||
float aspect = static_cast< float >(width) / static_cast< float >(height);
|
||||
#else
|
||||
float aspect = 1.3333334f;
|
||||
#endif
|
||||
CGraphics::SetPerspective(75.f, aspect, 1.f, 4096.f);
|
||||
CGraphics::SetModelMatrix(CTransform4f::Identity());
|
||||
CGraphics::TickRenderTimings();
|
||||
if (x310_phazonSuitMaskCountdown != 0) {
|
||||
--x310_phazonSuitMaskCountdown;
|
||||
if (x310_phazonSuitMaskCountdown == 0) {
|
||||
x314_phazonSuitMask->fn_8030E10C();
|
||||
x314_phazonSuitMask = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
x318_27_currentRGBA6 = x318_26_requestRGBA6;
|
||||
if (!x318_31_persistRGBA6) {
|
||||
x318_26_requestRGBA6 = false;
|
||||
}
|
||||
|
||||
GXSetPixelFmt(x318_27_currentRGBA6 ? GX_PF_RGBA6_Z24 : GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||
GXSetAlphaUpdate(GX_TRUE);
|
||||
GXSetDstAlpha(GX_TRUE, 0);
|
||||
CGraphics::BeginScene();
|
||||
}
|
||||
|
||||
void CCubeRenderer::EndScene() {
|
||||
x318_31_persistRGBA6 = !CGraphics::IsBeginSceneClearFb();
|
||||
CGraphics::EndScene();
|
||||
if (x2dc_reflectionAge >= 2) {
|
||||
x14c_reflectionTex = nullptr;
|
||||
} else {
|
||||
++x2dc_reflectionAge;
|
||||
}
|
||||
}
|
||||
|
||||
void CCubeRenderer::AddParticleGen(const CParticleGen& gen) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
namespace Renderer {
|
||||
IRenderer* AllocateRenderer(IObjectStore& objStore, COsContext& osContext, CMemorySys& memorySys,
|
||||
CResFactory& resFactory) {
|
||||
CCubeRenderer* renderer = rs_new CCubeRenderer(objStore, osContext, memorySys, resFactory);
|
||||
IWeaponRenderer::SetRenderer(renderer);
|
||||
return renderer;
|
||||
}
|
||||
} // namespace Renderer
|
||||
|
||||
void CCubeRenderer::PrimColor(float r, float g, float b, float a) {
|
||||
x2e0_primColor.Set(r, g, b, a);
|
||||
}
|
||||
|
||||
void CCubeRenderer::PrimColor(const CColor& color) { x2e0_primColor = color; }
|
||||
|
||||
void CCubeRenderer::BeginPrimitive(IRenderer::EPrimitiveType type, int nverts) {
|
||||
const GXVtxDescList vtxDescList[4] = {
|
||||
{GX_VA_POS, GX_DIRECT},
|
||||
{GX_VA_NRM, GX_DIRECT},
|
||||
{GX_VA_CLR0, GX_DIRECT},
|
||||
{GX_VA_NULL, GX_NONE},
|
||||
};
|
||||
CGX::SetChanCtrl(CGX::Channel0, false, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE,
|
||||
GX_AF_NONE);
|
||||
CGX::SetNumChans(1);
|
||||
CGX::SetNumTexGens(0);
|
||||
CGX::SetNumTevStages(1);
|
||||
CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
||||
CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
|
||||
CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA);
|
||||
CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0);
|
||||
x18_primVertCount = nverts;
|
||||
CGX::SetVtxDescv(vtxDescList);
|
||||
CGX::Begin(GXPrimitive(type), GX_VTXFMT0, nverts);
|
||||
}
|
||||
|
||||
void CCubeRenderer::BeginLines(int nverts) {
|
||||
CCubeRenderer::BeginPrimitive(IRenderer::kPT_Lines, nverts);
|
||||
}
|
||||
|
||||
void CCubeRenderer::BeginLineStrip(int nverts) {
|
||||
CCubeRenderer::BeginPrimitive(IRenderer::kPT_LineStrip, nverts);
|
||||
}
|
||||
|
||||
void CCubeRenderer::BeginTriangles(int nverts) {
|
||||
CCubeRenderer::BeginPrimitive(IRenderer::kPT_Triangles, nverts);
|
||||
}
|
||||
|
||||
void CCubeRenderer::BeginTriangleStrip(int nverts) {
|
||||
CCubeRenderer::BeginPrimitive(IRenderer::kPT_TriangleStrip, nverts);
|
||||
}
|
||||
|
||||
void CCubeRenderer::BeginTriangleFan(int nverts) {
|
||||
CCubeRenderer::BeginPrimitive(IRenderer::kPT_TriangleFan, nverts);
|
||||
}
|
||||
|
||||
void CCubeRenderer::PrimVertex(const CVector3f& vtx) {
|
||||
--x18_primVertCount;
|
||||
GXPosition3f32(vtx.GetX(), vtx.GetY(), vtx.GetZ());
|
||||
GXNormal3f32(x2e4_primNormal.GetX(), x2e4_primNormal.GetY(), x2e4_primNormal.GetZ());
|
||||
GXColor1u32(x2e0_primColor.GetColor_u32());
|
||||
}
|
||||
|
||||
void CCubeRenderer::PrimNormal(const CVector3f& nrm) { x2e4_primNormal = nrm; }
|
||||
|
||||
void CCubeRenderer::EndPrimitive() {
|
||||
while (x18_primVertCount != 0) {
|
||||
PrimVertex(CVector3f::Zero());
|
||||
}
|
||||
CGX::End();
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetAmbientColor(const CColor& color) { CGraphics::SetAmbientColor(color); }
|
||||
|
||||
void CCubeRenderer::SetPerspective(float fovy, float aspect, float znear, float zfar) {
|
||||
CGraphics::SetPerspective(fovy, aspect, znear, zfar);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetPerspective(float fovy, float width, float height, float znear, float zfar) {
|
||||
CGraphics::SetPerspective(fovy, width / height, znear, zfar);
|
||||
}
|
||||
|
||||
rstl::pair< CVector2f, CVector2f > CCubeRenderer::SetViewportOrtho(bool centered, float znear,
|
||||
float zfar) {
|
||||
const CViewport& vp = CGraphics::GetViewport();
|
||||
int vpLeft = vp.mLeft;
|
||||
int vpTop = vp.mTop;
|
||||
int vpWidth = vp.mWidth;
|
||||
int vpHeight = vp.mHeight;
|
||||
float left = static_cast< float >(centered ? vpLeft - vpWidth / 2 : vpLeft);
|
||||
float top = static_cast< float >(centered ? vpTop - vpHeight / 2 : vpTop);
|
||||
float right = static_cast< float >(centered ? vpLeft + vpWidth / 2 : vpLeft + vpWidth);
|
||||
float bottom = static_cast< float >(centered ? vpTop + vpHeight / 2 : vpTop + vpHeight);
|
||||
CGraphics::SetOrtho(left, right, bottom, top, znear, zfar);
|
||||
CGraphics::SetViewPointMatrix(CTransform4f::Identity());
|
||||
CGraphics::SetModelMatrix(CTransform4f::Identity());
|
||||
return rstl::pair< CVector2f, CVector2f >(CVector2f(left, top), CVector2f(right, bottom));
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetViewport(int left, int bottom, int width, int height) {
|
||||
CGraphics::SetViewport(left, bottom, width, height);
|
||||
CGraphics::SetScissor(left, bottom, width, height);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetDepthReadWrite(bool read, bool update) {
|
||||
CGraphics::SetDepthWriteMode(read, kE_LEqual, update);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_AdditiveAlpha() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_One, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_AlphaBlended() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_InvSrcAlpha, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_NoColorWrite() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_Zero, kBF_One, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_ColorMultiply() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_Zero, kBF_SrcColor, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_InvertDst() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_InvSrcColor, kBF_Zero, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_InvertSrc() {
|
||||
CGraphics::SetBlendMode(kBM_Logic, kBF_One, kBF_Zero, kLO_InvCopy);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_Replace() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_One, kBF_Zero, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetBlendMode_AdditiveDestColor() {
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcColor, kBF_One, kLO_Clear);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetClippingPlanes(const CFrustumPlanes& frustum) {
|
||||
x44_frustumPlanes = frustum;
|
||||
}
|
||||
|
||||
float CCubeRenderer::GetFPS() { return CGraphics::GetFPS(); }
|
||||
|
||||
void CCubeRenderer::SetDrawableCallback(IRenderer::TDrawableCallback cb, const void* ctx) {
|
||||
xa8_drawableCallback = cb;
|
||||
xac_drawableCallbackUserData = ctx;
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetDebugOption(IRenderer::EDebugOption option, int value) {
|
||||
switch (option) {
|
||||
case IRenderer::kDO_PVSMode:
|
||||
xc0_pvsMode = value != 0 ? 1 : 0;
|
||||
break;
|
||||
case IRenderer::kDO_PVSState:
|
||||
xc4_pvsState = value;
|
||||
break;
|
||||
case IRenderer::kDO_FogDisabled:
|
||||
x318_28_disableFog = value != 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CTexture* CCubeRenderer::GetRealReflection() {
|
||||
x2dc_reflectionAge = 0;
|
||||
if (!x14c_reflectionTex.null()) {
|
||||
return x14c_reflectionTex.get();
|
||||
}
|
||||
return &xe4_blackTex;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user