mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-14 15:26:10 +00:00
Implement CGX & migrate usages to CGX/GX
This commit is contained in:
@@ -4,10 +4,9 @@
|
||||
#include "Graphics/CCubeModel.hpp"
|
||||
#include "Graphics/CCubeRenderer.hpp"
|
||||
#include "Graphics/CCubeSurface.hpp"
|
||||
#include "Graphics/CGX.hpp"
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
#include <aurora/model.hpp>
|
||||
|
||||
namespace metaforce {
|
||||
static u32 sReflectionType = 0;
|
||||
static u32 sLastMaterialUnique = UINT32_MAX;
|
||||
@@ -68,7 +67,7 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
||||
sLastMaterialUnique = groupIdx;
|
||||
|
||||
u32 vatFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur));
|
||||
aurora::gfx::model::set_vtx_desc_compressed(vatFlags);
|
||||
CGX::SetVtxDescv_Compressed(vatFlags);
|
||||
materialDataCur += 8;
|
||||
|
||||
bool packedLightMaps = matFlags.IsSet(CCubeMaterialFlagBits::fLightmapUvArray);
|
||||
@@ -84,14 +83,14 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
||||
for (u32 i = 0; i < konstCount; ++i) {
|
||||
u32 kColor = SBig(*reinterpret_cast<const u32*>(materialDataCur));
|
||||
materialDataCur += 4;
|
||||
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(i), kColor);
|
||||
CGX::SetTevKColor(static_cast<GX::TevKColorID>(i), kColor);
|
||||
}
|
||||
}
|
||||
|
||||
u32 blendFactors = SBig(*reinterpret_cast<const u32*>(materialDataCur));
|
||||
materialDataCur += 4;
|
||||
if (g_Renderer->IsInAreaDraw()) {
|
||||
// TODO blackout fog, additive blend
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_ONE, GX::BL_ONE, GX::LO_CLEAR);
|
||||
} else {
|
||||
SetupBlendMode(blendFactors, flags, matFlags.IsSet(CCubeMaterialFlagBits::fAlphaTest));
|
||||
}
|
||||
@@ -135,7 +134,7 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
||||
materialDataCur += 20;
|
||||
texMapTexCoordFlags += 1;
|
||||
finalCCFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
||||
aurora::gfx::set_tev_reg_color(GX::TEVREG0, 0xc0c0c0c0);
|
||||
GXSetTevColor(GX::TEVREG0, 0xc0c0c0c0);
|
||||
}
|
||||
finalACFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 12));
|
||||
HandleTev(firstTev, reinterpret_cast<const u32*>(materialDataCur), texMapTexCoordFlags,
|
||||
@@ -219,10 +218,10 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
||||
tcgCount += 1;
|
||||
}
|
||||
|
||||
// SetNumIndStages(numIndStages);
|
||||
aurora::gfx::disable_tev_stage(static_cast<ERglTevStage>(finalTevCount));
|
||||
// SetNumTexGens(tcgCount);
|
||||
// SetNumColorChans(finalNumColorChans);
|
||||
CGX::SetNumIndStages(numIndStages);
|
||||
CGX::SetNumTevStages(finalTevCount);
|
||||
CGX::SetNumTexGens(tcgCount);
|
||||
CGX::SetNumChans(finalNumColorChans);
|
||||
}
|
||||
|
||||
void CCubeMaterial::SetCurrentBlack() {
|
||||
@@ -230,50 +229,47 @@ void CCubeMaterial::SetCurrentBlack() {
|
||||
auto vatFlags = GetVatFlags();
|
||||
|
||||
if (flags.IsSet(CCubeMaterialFlagBits::fDepthSorting) || flags.IsSet(CCubeMaterialFlagBits::fAlphaTest)) {
|
||||
// set fog mode 0x21
|
||||
aurora::gfx::set_blend_mode(ERglBlendMode::Blend, ERglBlendFactor::Zero, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_ZERO, GX::BL_ONE, GX::LO_CLEAR);
|
||||
} else {
|
||||
// set fog mode 5
|
||||
aurora::gfx::set_blend_mode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::Zero, ERglLogicOp::Clear);
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_ONE, GX::BL_ZERO, GX::LO_CLEAR);
|
||||
}
|
||||
// set vtx desc flags
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeMaterial::SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest) {
|
||||
auto newSrcFactor = static_cast<ERglBlendFactor>(blendFactors & 0xffff);
|
||||
auto newDstFactor = static_cast<ERglBlendFactor>(blendFactors >> 16 & 0xffff);
|
||||
auto newSrcFactor = static_cast<GX::BlendFactor>(blendFactors & 0xffff);
|
||||
auto newDstFactor = static_cast<GX::BlendFactor>(blendFactors >> 16 & 0xffff);
|
||||
if (alphaTest) {
|
||||
// discard fragments with alpha < 0.25
|
||||
aurora::gfx::set_alpha_discard(true);
|
||||
newSrcFactor = ERglBlendFactor::One;
|
||||
newDstFactor = ERglBlendFactor::Zero;
|
||||
CGX::SetAlphaCompare(GX::GEQUAL, 64, GX::AOP_OR, GX::NEVER, 0);
|
||||
newSrcFactor = GX::BL_ONE;
|
||||
newDstFactor = GX::BL_ZERO;
|
||||
} else {
|
||||
aurora::gfx::set_alpha_discard(false);
|
||||
CGX::SetAlphaCompare(GX::ALWAYS, 0, GX::AOP_OR, GX::ALWAYS, 0);
|
||||
}
|
||||
|
||||
if (flags.x0_blendMode > 4 && newSrcFactor == ERglBlendFactor::One) {
|
||||
newSrcFactor = ERglBlendFactor::SrcAlpha;
|
||||
if (newDstFactor == ERglBlendFactor::Zero) {
|
||||
newDstFactor = flags.x0_blendMode > 6 ? ERglBlendFactor::One : ERglBlendFactor::InvSrcAlpha;
|
||||
if (flags.x0_blendMode > 4 && newSrcFactor == GX::BL_ONE) {
|
||||
newSrcFactor = GX::BL_SRCALPHA;
|
||||
if (newDstFactor == GX::BL_ZERO) {
|
||||
newDstFactor = flags.x0_blendMode > 6 ? GX::BL_ONE : GX::BL_INVSRCALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO set fog color zero if dst blend zero
|
||||
aurora::gfx::set_blend_mode(ERglBlendMode::Blend, newSrcFactor, newDstFactor, ERglLogicOp::Clear);
|
||||
CGX::SetBlendMode(GX::BM_BLEND, newSrcFactor, newDstFactor, GX::LO_CLEAR);
|
||||
}
|
||||
|
||||
void CCubeMaterial::HandleDepth(CModelFlagsFlags modelFlags, CCubeMaterialFlags matFlags) {
|
||||
ERglEnum func = ERglEnum::Never;
|
||||
GX::Compare func = GX::NEVER;
|
||||
if (!(modelFlags & CModelFlagBits::DepthTest)) {
|
||||
func = ERglEnum::Always;
|
||||
func = GX::ALWAYS;
|
||||
} else if (modelFlags & CModelFlagBits::DepthGreater) {
|
||||
func = modelFlags & CModelFlagBits::DepthNonInclusive ? ERglEnum::Greater : ERglEnum::GEqual;
|
||||
func = modelFlags & CModelFlagBits::DepthNonInclusive ? GX::GREATER : GX::GEQUAL;
|
||||
} else {
|
||||
func = modelFlags & CModelFlagBits::DepthNonInclusive ? ERglEnum::Less : ERglEnum::LEqual;
|
||||
func = modelFlags & CModelFlagBits::DepthNonInclusive ? GX::LESS : GX::LEQUAL;
|
||||
}
|
||||
bool depthWrite = modelFlags & CModelFlagBits::DepthUpdate && matFlags & CCubeMaterialFlagBits::fDepthWrite;
|
||||
aurora::gfx::set_depth_mode(true, func, depthWrite);
|
||||
CGX::SetZMode(true, func, depthWrite);
|
||||
}
|
||||
|
||||
void CCubeMaterial::ResetCachedMaterials() {
|
||||
@@ -305,39 +301,40 @@ void CCubeMaterial::EnsureViewDepStateCached(const CCubeSurface* surface) {
|
||||
u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) {
|
||||
if (CCubeModel::sRenderModelShadow) {
|
||||
if (chanCount != 0) {
|
||||
aurora::gfx::set_chan_amb_color(GX::COLOR1A1, zeus::skBlack);
|
||||
aurora::gfx::set_chan_mat_color(GX::COLOR1A1, zeus::skWhite);
|
||||
CGX::SetChanAmbColor(CGX::EChannelId::Channel1, zeus::skBlack);
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel1, zeus::skWhite);
|
||||
|
||||
// TODO chan / lights
|
||||
|
||||
aurora::gfx::set_chan_mat_color(GX::COLOR0A0, zeus::skWhite);
|
||||
auto chan0Lights = CGraphics::g_LightActive & ~CCubeModel::sChannel0DisableLightMask;
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, chan0Lights); // TODO use firstChan flags
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel1, CCubeModel::sChannel1EnableLightMask);
|
||||
if (chan0Lights.any()) {
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel0, zeus::skWhite);
|
||||
} else {
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0));
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (chanCount == 2) {
|
||||
aurora::gfx::set_chan_amb_color(GX::COLOR1A1, zeus::skBlack);
|
||||
aurora::gfx::set_chan_mat_color(GX::COLOR1A1, zeus::skWhite);
|
||||
CGX::SetChanAmbColor(CGX::EChannelId::Channel1, zeus::skBlack);
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel1, zeus::skWhite);
|
||||
} else {
|
||||
// TODO chan ctrls
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel1, {});
|
||||
}
|
||||
|
||||
if (chanCount == 0) {
|
||||
// TODO more chan ctrls
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, {});
|
||||
} else {
|
||||
auto uVar3 = firstChan & 0xfffffffe;
|
||||
// TODO enabled lights
|
||||
// TODO chan ctrl
|
||||
// if (sEnabledLights == 0) {
|
||||
// aurora::gfx::set_chan_mat_color(GX::COLOR0A0, amb_clr);
|
||||
// } else {
|
||||
aurora::gfx::set_chan_mat_color(GX::COLOR0A0, zeus::skWhite);
|
||||
// }
|
||||
// TODO use firstChan flags
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, CGraphics::g_LightActive);
|
||||
if (CGraphics::g_LightActive.any()) {
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel0, zeus::skWhite);
|
||||
} else {
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
aurora::gfx::set_chan_mat_src(GX::COLOR0A0, GX::SRC_REG);
|
||||
aurora::gfx::set_chan_mat_src(GX::COLOR1A1, GX::SRC_REG);
|
||||
return chanCount;
|
||||
}
|
||||
|
||||
@@ -348,27 +345,15 @@ void CCubeMaterial::HandleTev(u32 tevCur, const u32* materialDataCur, const u32*
|
||||
const u32 colorOps = SBig(materialDataCur[2]);
|
||||
const u32 alphaOps = SBig(materialDataCur[3]);
|
||||
|
||||
// GXSetTevDirect(tevCur);
|
||||
const CTevCombiners::ColorPass colPass{colorArgs};
|
||||
const CTevCombiners::AlphaPass alphaPass{alphaArgs};
|
||||
const CTevCombiners::CTevOp colorOp{colorOps};
|
||||
const CTevCombiners::CTevOp alphaOp{alphaOps};
|
||||
// TODO does this actually change anything?
|
||||
// if (colorOps == alphaOps && ((colorOps & 0x1FF) == 0x100)) {
|
||||
// colorOp = {true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, colorOp.x10_regId};
|
||||
// alphaOp = {true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, colorOp.x10_regId};
|
||||
// }
|
||||
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(tevCur), colPass, alphaPass, colorOp, alphaOp);
|
||||
const auto stage = static_cast<GX::TevStageID>(tevCur);
|
||||
CGX::SetStandardDirectTev_Compressed(stage, colorArgs, alphaArgs, colorOps, alphaOps);
|
||||
|
||||
u32 tmtcFlags = SBig(*texMapTexCoordFlags);
|
||||
u32 matFlags = SBig(materialDataCur[4]);
|
||||
aurora::gfx::set_tev_order(static_cast<GX::TevStageID>(tevCur), static_cast<GX::TexCoordID>(tmtcFlags & 0xFF),
|
||||
static_cast<GX::TexMapID>(tmtcFlags >> 8 & 0xFF),
|
||||
static_cast<GX::ChannelID>(matFlags & 0xFF));
|
||||
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(tevCur),
|
||||
static_cast<GX::TevKColorSel>(matFlags >> 0x8 & 0xFF));
|
||||
aurora::gfx::set_tev_k_alpha_sel(static_cast<GX::TevStageID>(tevCur),
|
||||
static_cast<GX::TevKAlphaSel>(matFlags >> 0x10 & 0xFF));
|
||||
CGX::SetTevOrder(stage, static_cast<GX::TexCoordID>(tmtcFlags & 0xFF),
|
||||
static_cast<GX::TexMapID>(tmtcFlags >> 8 & 0xFF), static_cast<GX::ChannelID>(matFlags & 0xFF));
|
||||
CGX::SetTevKColorSel(stage, static_cast<GX::TevKColorSel>(matFlags >> 0x8 & 0xFF));
|
||||
CGX::SetTevKAlphaSel(stage, static_cast<GX::TevKAlphaSel>(matFlags >> 0x10 & 0xFF));
|
||||
}
|
||||
|
||||
u32 CCubeMaterial::HandleAnimatedUV(const u32* uvAnim, u32 texMtx, u32 pttTexMtx) {
|
||||
@@ -405,76 +390,56 @@ void CCubeMaterial::HandleTransparency(u32& finalTevCount, u32& finalKColorCount
|
||||
u32 blendFactors, u32& finalCCFlags, u32& finalACFlags) {
|
||||
if (modelFlags.x0_blendMode == 2) {
|
||||
u16 dstFactor = blendFactors >> 16 & 0xffff;
|
||||
if (dstFactor == 1)
|
||||
if (dstFactor == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (modelFlags.x0_blendMode == 3) {
|
||||
// Stage outputting splatted KAlpha as color to reg0
|
||||
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(finalTevCount),
|
||||
CTevCombiners::ColorPass{GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_KONST},
|
||||
CTevCombiners::AlphaPass{GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV},
|
||||
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVREG0},
|
||||
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVPREV});
|
||||
// GXSetTevColorIn(finalTevCount, TEVCOLORARG_ZERO, TEVCOLORARG_ZERO, TEVCOLORARG_ZERO, TEVCOLORARG_KONST);
|
||||
// GXSetTevAlphaIn(finalTevCount, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_APREV);
|
||||
// GXSetTevColorOp(finalTevCount, 0, 0, 0, 1, 1); // ColorReg0
|
||||
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalTevCount),
|
||||
static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0_A));
|
||||
// GXSetTevKColorSel(finalTevCount, finalKColorCount+28);
|
||||
// GXSetTevAlphaOp(finalTevCount, 0, 0, 0, 1, 0); // AlphaRegPrev
|
||||
// GXSetTevOrder(finalTevCount, 255, 255, 255);
|
||||
// GXSetTevDirect(finalTevCount);
|
||||
auto stage = static_cast<GX::TevStageID>(finalTevCount);
|
||||
CGX::SetTevColorIn(stage, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_KONST);
|
||||
CGX::SetTevAlphaIn(stage, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV);
|
||||
CGX::SetTevColorOp(stage, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVREG0);
|
||||
CGX::SetTevKColorSel(stage, static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0_A));
|
||||
CGX::SetTevAlphaOp(stage, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
CGX::SetTevOrder(stage, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetTevDirect(stage);
|
||||
|
||||
// Stage interpolating from splatted KAlpha using KColor
|
||||
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(finalTevCount + 1),
|
||||
CTevCombiners::ColorPass{GX::CC_CPREV, GX::CC_C0, GX::CC_KONST, GX::CC_ZERO},
|
||||
CTevCombiners::AlphaPass{GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV},
|
||||
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVPREV},
|
||||
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVPREV});
|
||||
// GXSetTevColorIn(finalTevCount + 1, TEVCOLORARG_CPREV, TEVCOLORARG_C0, TEVCOLORARG_KONST, TEVCOLORARG_ZERO);
|
||||
// GXSetTevAlphaIn(finalTevCount + 1, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_APREV);
|
||||
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalTevCount + 1),
|
||||
static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0));
|
||||
// GXSetTevKColorSel(finalTevCount, finalKColorCount+12);
|
||||
// SetStandardTevColorAlphaOp(finalTevCount + 1);
|
||||
// GXSetTevDirect(finalTevCount + 1);
|
||||
// GXSetTevOrder(finalTevCount + 1, 255, 255, 255);
|
||||
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(finalKColorCount), modelFlags.x4_color);
|
||||
// GXSetTevKColor(finalKColorCount, modelFlags.x4_color);
|
||||
stage = static_cast<GX::TevStageID>(stage + 1);
|
||||
CGX::SetTevColorIn(stage, GX::CC_CPREV, GX::CC_C0, GX::CC_KONST, GX::CC_ZERO);
|
||||
CGX::SetTevAlphaIn(stage, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV);
|
||||
CGX::SetTevKColorSel(stage, static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0));
|
||||
CGX::SetStandardTevColorAlphaOp(stage);
|
||||
CGX::SetTevDirect(stage);
|
||||
CGX::SetTevOrder(stage, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetTevKColor(static_cast<GX::TevKColorID>(finalKColorCount), modelFlags.x4_color);
|
||||
|
||||
finalKColorCount += 1;
|
||||
finalTevCount += 2;
|
||||
} else {
|
||||
// Mul KAlpha
|
||||
CTevCombiners::AlphaPass alphaPass{GX::CA_ZERO, GX::CA_KONST, GX::CA_APREV, GX::CA_ZERO};
|
||||
u32 tevAlpha = 0x000380C7; // TEVALPHAARG_ZERO, TEVALPHAARG_KONST, TEVALPHAARG_APREV, TEVALPHAARG_ZERO
|
||||
auto stage = static_cast<GX::TevStageID>(finalTevCount);
|
||||
if (modelFlags.x0_blendMode == 8) {
|
||||
// Set KAlpha
|
||||
alphaPass = {GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_KONST};
|
||||
tevAlpha = 0x00031CE7; // TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_KONST
|
||||
CGX::SetTevAlphaIn(stage, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_KONST); // Set KAlpha
|
||||
} else {
|
||||
CGX::SetTevAlphaIn(stage, GX::CA_ZERO, GX::CA_KONST, GX::CA_APREV, GX::CA_ZERO); // Mul KAlpha
|
||||
}
|
||||
// Mul KColor
|
||||
CTevCombiners::ColorPass colorPass{GX::CC_ZERO, GX::CC_KONST, GX::CC_CPREV, GX::CC_ZERO};
|
||||
u32 tevColor = 0x000781CF; // TEVCOLORARG_ZERO, TEVCOLORARG_KONST, TEVCOLORARG_CPREV, TEVCOLORARG_ZERO
|
||||
if (modelFlags.x0_blendMode == 2) {
|
||||
// Add KColor
|
||||
colorPass = {GX::CC_ZERO, GX::CC_ONE, GX::CC_CPREV, GX::CC_KONST};
|
||||
tevColor = 0x0007018F; // TEVCOLORARG_ZERO, TEVCOLORARG_ONE, TEVCOLORARG_CPREV, TEVCOLORARG_KONST
|
||||
CGX::SetTevColorIn(stage, GX::CC_ZERO, GX::CC_ONE, GX::CC_CPREV, GX::CC_KONST); // Add KColor
|
||||
} else {
|
||||
CGX::SetTevColorIn(stage, GX::CC_ZERO, GX::CC_KONST, GX::CC_CPREV, GX::CC_ZERO); // Mul KColor
|
||||
}
|
||||
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(finalTevCount), colorPass, alphaPass, {}, {});
|
||||
// GXSetTevColorIn(finalTevCount)
|
||||
// GXSetTevAlphaIn(finalTevCount)
|
||||
// SetStandardTevColorAlphaOp(finalTevCount);
|
||||
CGX::SetStandardTevColorAlphaOp(stage);
|
||||
|
||||
finalCCFlags = 0x100; // Just clamp, output prev reg
|
||||
finalACFlags = 0x100;
|
||||
// GXSetTevDirect(finalTevCount);
|
||||
// GXSetTevOrder(finalTevCount, 255, 255, 255);
|
||||
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(finalKColorCount), modelFlags.x4_color);
|
||||
// GXSetTevKColor(finalKColorCount, modelFlags.x4_color);
|
||||
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalTevCount),
|
||||
static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0));
|
||||
// GXSetTevKColorSel(finalTevCount, finalKColorCount+12);
|
||||
aurora::gfx::set_tev_k_alpha_sel(static_cast<GX::TevStageID>(finalTevCount),
|
||||
static_cast<GX::TevKAlphaSel>(finalKColorCount + GX::TEV_KASEL_K0_A));
|
||||
// GXSetTevKAlphaSel(finalTevCount, finalKColorCount+28);
|
||||
|
||||
CGX::SetTevDirect(stage);
|
||||
CGX::SetTevOrder(stage, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetTevKColor(static_cast<GX::TevKColorID>(finalKColorCount), modelFlags.x4_color);
|
||||
CGX::SetTevKColorSel(stage, static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0));
|
||||
CGX::SetTevKAlphaSel(stage, static_cast<GX::TevKAlphaSel>(finalKColorCount + GX::TEV_KASEL_K0_A));
|
||||
|
||||
finalTevCount += 1;
|
||||
finalKColorCount += 1;
|
||||
}
|
||||
@@ -483,16 +448,20 @@ void CCubeMaterial::HandleTransparency(u32& finalTevCount, u32& finalKColorCount
|
||||
u32 CCubeMaterial::HandleReflection(bool usesTevReg2, u32 indTexSlot, u32 r5, u32 finalTevCount, u32 texCount,
|
||||
u32 tcgCount, u32 finalKColorCount, u32& finalCCFlags, u32& finalACFlags) {
|
||||
u32 out = 0;
|
||||
GX::TevColorArg colorArg = GX::CC_KONST;
|
||||
if (usesTevReg2) {
|
||||
// GX_CC_C2
|
||||
colorArg = GX::CC_C2;
|
||||
const auto stage = static_cast<GX::TevStageID>(finalTevCount);
|
||||
CGX::SetTevColorIn(stage, GX::CC_ZERO, GX::CC_C2, GX::CC_KONST, GX::CC_ZERO);
|
||||
CGX::SetTevAlphaIn(stage, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_A2);
|
||||
CGX::SetTevColorOp(stage, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVREG2);
|
||||
CGX::SetTevAlphaOp(stage, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVREG2);
|
||||
CGX::SetTevOrder(stage, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_ZERO);
|
||||
out = 1;
|
||||
} else {
|
||||
// GX_CC_KONST
|
||||
}
|
||||
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(finalKColorCount),
|
||||
zeus::CColor{sReflectionAlpha, sReflectionAlpha});
|
||||
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalTevCount),
|
||||
static_cast<GX::TevKColorSel>(GX::TEV_KCSEL_K0 + finalKColorCount));
|
||||
CGX::SetTevKColor(static_cast<GX::TevKColorID>(finalKColorCount), zeus::CColor{sReflectionAlpha, sReflectionAlpha});
|
||||
CGX::SetTevKColorSel(static_cast<GX::TevStageID>(finalTevCount),
|
||||
static_cast<GX::TevKColorSel>(GX::TEV_KCSEL_K0 + finalKColorCount));
|
||||
|
||||
const auto stage = static_cast<GX::TevStageID>(finalTevCount + out);
|
||||
// tex = g_Renderer->GetRealReflection
|
||||
@@ -505,11 +474,16 @@ u32 CCubeMaterial::HandleReflection(bool usesTevReg2, u32 indTexSlot, u32 r5, u3
|
||||
|
||||
// aurora::gfx::set_tev_order(stage, ...)
|
||||
|
||||
return out + 1;
|
||||
return out; //+ 1;
|
||||
}
|
||||
|
||||
void CCubeMaterial::DoPassthru(u32 finalTevCount) {
|
||||
aurora::gfx::disable_tev_stage(static_cast<ERglTevStage>(finalTevCount));
|
||||
const auto stage = static_cast<GX::TevStageID>(finalTevCount);
|
||||
CGX::SetTevColorIn(stage, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_CPREV);
|
||||
CGX::SetTevAlphaIn(stage, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV);
|
||||
CGX::SetTevOrder(stage, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetTevDirect(stage);
|
||||
CGX::SetStandardTevColorAlphaOp(stage);
|
||||
}
|
||||
|
||||
void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) {
|
||||
@@ -523,8 +497,8 @@ void CCubeMaterial::EnsureTevsDirect() {
|
||||
return;
|
||||
}
|
||||
|
||||
// CGX::SetNumIndStages(0);
|
||||
// CGX::SetTevDirect(sCurrentTevStage);
|
||||
CGX::SetNumIndStages(0);
|
||||
CGX::SetTevDirect(sCurrentTevStage);
|
||||
sCurrentTevStage = GX::NULL_STAGE;
|
||||
}
|
||||
} // namespace metaforce
|
||||
|
||||
@@ -5,22 +5,20 @@
|
||||
#include "Graphics/CCubeSurface.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
#include <aurora/model.hpp>
|
||||
#include "Graphics/CGX.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
bool CCubeModel::sRenderModelBlack = false;
|
||||
bool CCubeModel::sRenderModelShadow = false;
|
||||
bool CCubeModel::sUsingPackedLightmaps = false;
|
||||
const CTexture* CCubeModel::sShadowTexture = nullptr;
|
||||
zeus::CTransform CCubeModel::sTextureProjectionTransform;
|
||||
GX::LightMask CCubeModel::sChannel0DisableLightMask;
|
||||
GX::LightMask CCubeModel::sChannel1EnableLightMask;
|
||||
|
||||
static bool sDrawingOccluders = false;
|
||||
static bool sDrawingWireframe = false;
|
||||
|
||||
static zeus::CTransform sTextureProjectionTransform;
|
||||
static u8 sChannel0DisableLightMask = 0;
|
||||
static u8 sChannel1EnableLightMask = 0;
|
||||
|
||||
static zeus::CVector3f sPlayerPosition;
|
||||
|
||||
CCubeModel::CCubeModel(std::vector<CCubeSurface>* surfaces, std::vector<TCachedToken<CTexture>>* textures,
|
||||
@@ -159,8 +157,8 @@ void CCubeModel::DrawFlat(TConstVectorRef positions, TConstVectorRef normals, ES
|
||||
const auto* surface = x38_firstUnsortedSurf;
|
||||
while (surface != nullptr) {
|
||||
const auto mat = GetMaterialByIndex(surface->GetMaterialIndex());
|
||||
aurora::gfx::model::set_vtx_desc_compressed(mat.GetVertexDesc());
|
||||
aurora::gfx::model::queue_surface(surface->GetDisplayList(), surface->GetDisplayListSize());
|
||||
CGX::SetVtxDescv_Compressed(mat.GetVertexDesc());
|
||||
CGX::CallDisplayList(surface->GetDisplayList(), surface->GetDisplayListSize());
|
||||
surface = surface->GetNextSurface();
|
||||
}
|
||||
}
|
||||
@@ -168,19 +166,23 @@ void CCubeModel::DrawFlat(TConstVectorRef positions, TConstVectorRef normals, ES
|
||||
const auto* surface = x3c_firstSortedSurf;
|
||||
while (surface != nullptr) {
|
||||
const auto mat = GetMaterialByIndex(surface->GetMaterialIndex());
|
||||
aurora::gfx::model::set_vtx_desc_compressed(mat.GetVertexDesc());
|
||||
aurora::gfx::model::queue_surface(surface->GetDisplayList(), surface->GetDisplayListSize());
|
||||
CGX::SetVtxDescv_Compressed(mat.GetVertexDesc());
|
||||
CGX::CallDisplayList(surface->GetDisplayList(), surface->GetDisplayListSize());
|
||||
surface = surface->GetNextSurface();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCubeModel::DrawNormal(TConstVectorRef positions, TConstVectorRef normals, ESurfaceSelection surfaces) {
|
||||
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::skPassZero);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru);
|
||||
// TODO update fog
|
||||
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::Zero, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||
CGX::SetNumIndStages(0);
|
||||
CGX::SetNumTevStages(1);
|
||||
CGX::SetNumTexGens(1);
|
||||
CGX::SetZMode(true, GX::LEQUAL, true);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO);
|
||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE0);
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_ZERO, GX::BL_ONE, GX::LO_CLEAR);
|
||||
DrawFlat(positions, normals, surfaces);
|
||||
}
|
||||
|
||||
@@ -210,7 +212,7 @@ void CCubeModel::DrawSurface(const CCubeSurface& surface, const CModelFlags& fla
|
||||
auto mat = GetMaterialByIndex(surface.GetMaterialIndex());
|
||||
if (!mat.GetFlags().IsSet(CCubeMaterialFlagBits::fShadowOccluderMesh) || sDrawingOccluders) {
|
||||
mat.SetCurrent(flags, surface, *this);
|
||||
aurora::gfx::model::queue_surface(surface.GetDisplayList(), surface.GetDisplayListSize());
|
||||
CGX::CallDisplayList(surface.GetDisplayList(), surface.GetDisplayListSize());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,8 +247,8 @@ void CCubeModel::DrawSurfaceWireframe(const CCubeSurface& surface) {
|
||||
// TODO convert vertices to line strips and draw
|
||||
}
|
||||
|
||||
void CCubeModel::EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf, u8 chan0DisableMask,
|
||||
u8 chan1EnableLightMask) {
|
||||
void CCubeModel::EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf,
|
||||
GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask) {
|
||||
sRenderModelShadow = true;
|
||||
sShadowTexture = &shadowTex;
|
||||
sTextureProjectionTransform = textureProjXf;
|
||||
@@ -257,8 +259,8 @@ void CCubeModel::EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransf
|
||||
void CCubeModel::DisableShadowMaps() { sRenderModelShadow = false; }
|
||||
|
||||
void CCubeModel::SetArraysCurrent() {
|
||||
aurora::gfx::model::set_vertex_buffer(x0_modelInstance.GetVertexPointer());
|
||||
aurora::gfx::model::set_normal_buffer(x0_modelInstance.GetNormalPointer());
|
||||
CGX::SetArray(GX::VA_POS, x0_modelInstance.GetVertexPointer());
|
||||
CGX::SetArray(GX::VA_NRM, x0_modelInstance.GetNormalPointer());
|
||||
SetStaticArraysCurrent();
|
||||
}
|
||||
|
||||
@@ -278,8 +280,8 @@ void CCubeModel::SetRenderModelBlack(bool v) {
|
||||
}
|
||||
|
||||
void CCubeModel::SetSkinningArraysCurrent(TConstVectorRef positions, TConstVectorRef normals) {
|
||||
aurora::gfx::model::set_vertex_buffer(positions);
|
||||
aurora::gfx::model::set_normal_buffer(normals);
|
||||
CGX::SetArray(GX::VA_POS, positions);
|
||||
CGX::SetArray(GX::VA_NRM, normals);
|
||||
// colors unused
|
||||
SetStaticArraysCurrent();
|
||||
}
|
||||
@@ -292,20 +294,21 @@ void CCubeModel::SetStaticArraysCurrent() {
|
||||
sUsingPackedLightmaps = false;
|
||||
}
|
||||
if (sUsingPackedLightmaps) {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(packedTexCoords);
|
||||
CGX::SetArray(GX::VA_TEX0, packedTexCoords);
|
||||
} else {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(texCoords);
|
||||
CGX::SetArray(GX::VA_TEX0, texCoords);
|
||||
}
|
||||
aurora::gfx::model::set_tc_buffer(texCoords);
|
||||
// TexCoord1 is currently used for all remaining
|
||||
CGX::SetArray(GX::VA_TEX1, texCoords);
|
||||
CCubeMaterial::KillCachedViewDepState();
|
||||
}
|
||||
|
||||
void CCubeModel::SetUsingPackedLightmaps(bool v) {
|
||||
sUsingPackedLightmaps = v;
|
||||
if (v) {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(x0_modelInstance.GetPackedTCPointer());
|
||||
CGX::SetArray(GX::VA_TEX0, x0_modelInstance.GetPackedTCPointer());
|
||||
} else {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(x0_modelInstance.GetTCPointer());
|
||||
CGX::SetArray(GX::VA_TEX0, x0_modelInstance.GetTCPointer());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ using TConstVectorRef = const std::vector<zeus::CVector3f>*;
|
||||
|
||||
class CCubeModel {
|
||||
friend class CModel;
|
||||
friend class CCubeMaterial;
|
||||
|
||||
private:
|
||||
class ModelInstance {
|
||||
@@ -110,8 +111,8 @@ public:
|
||||
[[nodiscard]] TConstVectorRef GetNormals() const { return x0_modelInstance.GetNormalPointer(); }
|
||||
[[nodiscard]] TCachedToken<CTexture>& GetTexture(u32 idx) const { return x1c_textures->at(idx); }
|
||||
|
||||
static void EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf, u8 chan0DisableMask,
|
||||
u8 chan1EnableLightMask);
|
||||
static void EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf,
|
||||
GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask);
|
||||
static void DisableShadowMaps();
|
||||
static void MakeTexturesFromMats(const u8* ptr, std::vector<TCachedToken<CTexture>>& texture, IObjectStore* store,
|
||||
bool b1);
|
||||
@@ -120,11 +121,6 @@ public:
|
||||
static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos, const CStopwatch& time);
|
||||
static void SetRenderModelBlack(bool v);
|
||||
|
||||
static bool sRenderModelBlack;
|
||||
static bool sUsingPackedLightmaps;
|
||||
static bool sRenderModelShadow;
|
||||
static const CTexture* sShadowTexture;
|
||||
|
||||
private:
|
||||
void Draw(TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags);
|
||||
void DrawAlphaSurfaces(const CModelFlags& flags);
|
||||
@@ -132,5 +128,13 @@ private:
|
||||
void DrawSurfaces(const CModelFlags& flags);
|
||||
void SetSkinningArraysCurrent(TConstVectorRef positions, TConstVectorRef normals);
|
||||
void SetStaticArraysCurrent();
|
||||
|
||||
static bool sRenderModelBlack;
|
||||
static bool sUsingPackedLightmaps;
|
||||
static bool sRenderModelShadow;
|
||||
static const CTexture* sShadowTexture;
|
||||
static zeus::CTransform sTextureProjectionTransform;
|
||||
static GX::LightMask sChannel0DisableLightMask;
|
||||
static GX::LightMask sChannel1EnableLightMask;
|
||||
};
|
||||
} // namespace metaforce
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#include "Runtime/Graphics/CCubeRenderer.hpp"
|
||||
|
||||
#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/CCubeMaterial.hpp"
|
||||
#include "Runtime/Graphics/CCubeModel.hpp"
|
||||
#include "Runtime/Graphics/CCubeSurface.hpp"
|
||||
#include "Runtime/Graphics/CCubeMaterial.hpp"
|
||||
#include "Runtime/Graphics/CDrawable.hpp"
|
||||
#include "Runtime/Graphics/CDrawablePlaneObject.hpp"
|
||||
#include "Runtime/Graphics/CGX.hpp"
|
||||
#include "Runtime/Graphics/CLight.hpp"
|
||||
#include "Runtime/Graphics/CMetroidModelInstance.hpp"
|
||||
#include "Runtime/Graphics/CModel.hpp"
|
||||
#include "Runtime/Particle/CParticleGen.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
static logvisor::Module Log("CCubeRenderer");
|
||||
@@ -197,15 +198,35 @@ CCubeRenderer::CCubeRenderer(IObjectStore& store, IFactory& resFac) : x8_factory
|
||||
|
||||
CCubeRenderer::~CCubeRenderer() { g_Renderer = nullptr; }
|
||||
|
||||
void CCubeRenderer::GenerateReflectionTex() {}
|
||||
void CCubeRenderer::GenerateFogVolumeRampTex() {}
|
||||
void CCubeRenderer::GenerateSphereRampTex() {}
|
||||
void CCubeRenderer::LoadThermoPalette() {}
|
||||
void CCubeRenderer::ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, const CTexture& maskTex,
|
||||
const CTexture& indTex, const zeus::CColor& modColor,
|
||||
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::GenerateReflectionTex() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::GenerateFogVolumeRampTex() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::GenerateSphereRampTex() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::LoadThermoPalette() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, CTexture& maskTex,
|
||||
CTexture& indTex, const zeus::CColor& modColor, float scale,
|
||||
float offX, float offY) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, CTexture& maskTex) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DoPhazonSuitIndirectAlphaBlur(float blurRadius, float f2, const TLockedToken<CTexture>& indTex) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::AddWorldSurfaces(CCubeModel& model) {
|
||||
for (auto* it = model.GetFirstSortedSurface(); it != nullptr; it = it->GetNextSurface()) {
|
||||
@@ -216,6 +237,7 @@ void CCubeRenderer::AddWorldSurfaces(CCubeModel& model) {
|
||||
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, s32 areaIdx) {
|
||||
auto search = FindStaticGeometry(geometry);
|
||||
@@ -448,7 +470,11 @@ void CCubeRenderer::RenderBucketItems(const CAreaListItem* item) {
|
||||
}
|
||||
}
|
||||
}
|
||||
void CCubeRenderer::PostRenderFogs() {}
|
||||
|
||||
void CCubeRenderer::PostRenderFogs() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetModelMatrix(const zeus::CTransform& xf) { CGraphics::SetModelMatrix(xf); }
|
||||
|
||||
void CCubeRenderer::HandleUnsortedModel(CAreaListItem* areaItem, CCubeModel& model, const CModelFlags& flags) {
|
||||
@@ -473,7 +499,10 @@ void CCubeRenderer::HandleUnsortedModelWireframe(CAreaListItem* areaItem, CCubeM
|
||||
}
|
||||
}
|
||||
|
||||
void CCubeRenderer::ActivateLightsForModel(const CAreaListItem* areaItem, CCubeModel& model) {}
|
||||
void CCubeRenderer::ActivateLightsForModel(const CAreaListItem* areaItem, CCubeModel& model) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::AddParticleGen(CParticleGen& gen) {
|
||||
auto bounds = gen.GetBounds();
|
||||
|
||||
@@ -575,8 +604,8 @@ void CCubeRenderer::BeginScene() {
|
||||
}
|
||||
|
||||
// GXSetPixelFmt(x318_26_requestRGBA6, GX_ZC_LINEAR);
|
||||
aurora::gfx::set_alpha_update(true);
|
||||
aurora::gfx::set_dst_alpha(true, 0.f);
|
||||
GXSetAlphaUpdate(true);
|
||||
GXSetDstAlpha(true, 0.f);
|
||||
CGraphics::BeginScene();
|
||||
}
|
||||
|
||||
@@ -607,64 +636,164 @@ 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, s32 x, s32 y) { x10_font.DrawString(string, x, y, zeus::skWhite); }
|
||||
|
||||
u32 CCubeRenderer::GetFPS() { return CGraphics::GetFPS(); }
|
||||
void CCubeRenderer::CacheReflection(IRenderer::TReflectionCallback cb, void* ctx, bool clearAfter) {}
|
||||
void CCubeRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) {}
|
||||
void CCubeRenderer::DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) {}
|
||||
void CCubeRenderer::DrawModelDisintegrate(const CModel& model, const CTexture& tex, const zeus::CColor& color,
|
||||
TConstVectorRef positions, TConstVectorRef normals) {}
|
||||
void CCubeRenderer::DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) {}
|
||||
void CCubeRenderer::SetWireframeFlags(s32 flags) {}
|
||||
void CCubeRenderer::SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) {}
|
||||
void CCubeRenderer::RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb,
|
||||
const TLockedToken<CModel>* model, const CSkinnedModel* sModel) {}
|
||||
void CCubeRenderer::SetThermal(bool thermal, float level, const zeus::CColor& color) {}
|
||||
void CCubeRenderer::SetThermalColdScale(float scale) {}
|
||||
void CCubeRenderer::DoThermalBlendCold() {}
|
||||
void CCubeRenderer::DoThermalBlendHot() {}
|
||||
u32 CCubeRenderer::GetStaticWorldDataSize() { return 0; }
|
||||
|
||||
void CCubeRenderer::SetGXRegister1Color(const zeus::CColor& color) {
|
||||
aurora::gfx::set_tev_reg_color(GX::TevRegID::TEVREG1, color);
|
||||
void CCubeRenderer::CacheReflection(IRenderer::TReflectionCallback cb, void* ctx, bool clearAfter) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DrawThermalModel(CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) {
|
||||
model.UpdateLastFrame();
|
||||
// TODO
|
||||
// DoThermalModelDraw(model.GetInstance(), multCol, addCol, positions, normals, flags);
|
||||
}
|
||||
|
||||
void CCubeRenderer::DrawModelDisintegrate(CModel& model, CTexture& tex, const zeus::CColor& color,
|
||||
TConstVectorRef positions, TConstVectorRef normals, float t) {
|
||||
tex.Load(GX::TEXMAP0, EClampMode::Clamp);
|
||||
CGX::SetNumIndStages(0);
|
||||
CGX::SetNumTevStages(2);
|
||||
CGX::SetNumTexGens(2);
|
||||
CGX::SetNumChans(0);
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_SRCALPHA, GX::BL_INVSRCALPHA, GX::LO_CLEAR);
|
||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE0);
|
||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE1);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_TEXC);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_TEXA);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE1, GX::CC_ZERO, GX::CC_TEXC, GX::CC_CPREV, GX::CC_KONST);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE1, GX::CA_ZERO, GX::CA_TEXA, GX::CA_APREV, GX::CA_ZERO);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD0, GX::TEXMAP0, GX::COLOR_NULL);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE1, GX::TEXCOORD1, GX::TEXMAP0, GX::COLOR_NULL);
|
||||
CGX::SetTevKColorSel(GX::TEVSTAGE1, GX::TEV_KCSEL_K0);
|
||||
CGX::SetTevKColor(GX::KCOLOR0, color);
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DrawModelFlat(CModel& model, const CModelFlags& flags, bool unsortedOnly, TConstVectorRef positions,
|
||||
TConstVectorRef normals) {
|
||||
if (flags.x0_blendMode >= 7) {
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_SRCALPHA, GX::BL_ONE, GX::LO_CLEAR);
|
||||
} else if (flags.x0_blendMode >= 5) {
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_SRCALPHA, GX::BL_INVSRCALPHA, GX::LO_CLEAR);
|
||||
} else {
|
||||
CGX::SetBlendMode(GX::BM_BLEND, GX::BL_ONE, GX::BL_ZERO, GX::LO_CLEAR);
|
||||
}
|
||||
CGX::SetZMode(true, flags.x2_flags & CModelFlagBits::DepthTest ? GX::LEQUAL : GX::ALWAYS,
|
||||
flags.x2_flags.IsSet(CModelFlagBits::DepthUpdate));
|
||||
CGX::SetNumTevStages(1);
|
||||
CGX::SetNumTexGens(1);
|
||||
CGX::SetNumChans(0);
|
||||
CGX::SetNumIndStages(0);
|
||||
CGX::SetAlphaCompare(GX::ALWAYS, 0, GX::AOP_AND, GX::ALWAYS, 0);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_KONST);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_KONST);
|
||||
CGX::SetTevKColor(GX::KCOLOR0, flags.x4_color);
|
||||
CGX::SetTevKColorSel(GX::TEVSTAGE0, GX::TEV_KCSEL_K0);
|
||||
CGX::SetTevKAlphaSel(GX::TEVSTAGE0, GX::TEV_KASEL_K0_A);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE0);
|
||||
CGX::SetTevDirect(GX::TEVSTAGE0);
|
||||
CGX::SetTexCoordGen(GX::TEXCOORD0, GX::TG_MTX2x4, GX::TG_POS, GX::IDENTITY, false, GX::PTIDENTITY);
|
||||
model.UpdateLastFrame();
|
||||
model.GetInstance().DrawFlat(positions, normals, unsortedOnly ? ESurfaceSelection::Unsorted : ESurfaceSelection::All);
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetWireframeFlags(s32 flags) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb,
|
||||
const TLockedToken<CModel>* model, const CSkinnedModel* sModel) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetThermal(bool thermal, float level, const zeus::CColor& color) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetThermalColdScale(float scale) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DoThermalBlendCold() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DoThermalBlendHot() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
u32 CCubeRenderer::GetStaticWorldDataSize() {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetGXRegister1Color(const zeus::CColor& color) { GXSetTevColor(GX::TevRegID::TEVREG1, color); }
|
||||
|
||||
void CCubeRenderer::SetWorldLightFadeLevel(float level) { x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f); }
|
||||
|
||||
void CCubeRenderer::PrepareDynamicLights(const std::vector<CLight>& lights) {}
|
||||
void CCubeRenderer::AllocatePhazonSuitMaskTexture() {}
|
||||
void CCubeRenderer::PrepareDynamicLights(const std::vector<CLight>& lights) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::AllocatePhazonSuitMaskTexture() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCubeRenderer::DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod,
|
||||
const TLockedToken<CTexture>& indTex, const zeus::CColor& indirectMod,
|
||||
float blurRadius, float scale, float offX, float offY) {
|
||||
// TODO
|
||||
aurora::gfx::set_dst_alpha(false, 0.f);
|
||||
GXSetDstAlpha(false, 0.f);
|
||||
}
|
||||
|
||||
void CCubeRenderer::DrawXRayOutline(const zeus::CAABox& aabb) {}
|
||||
void CCubeRenderer::DrawXRayOutline(const zeus::CAABox& aabb) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
std::list<CCubeRenderer::CAreaListItem>::iterator
|
||||
CCubeRenderer::FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) {
|
||||
@@ -687,9 +816,10 @@ void CCubeRenderer::SetupCGraphicsState() {
|
||||
CGraphics::SetModelMatrix({});
|
||||
CTevCombiners::ResetStates();
|
||||
CGraphics::SetAmbientColor({0.4f});
|
||||
// CGX::SetChanMatColor(EChannelId::Channel0, GX::Color{0xFFFFFFFF});
|
||||
CGX::SetChanMatColor(CGX::EChannelId::Channel0, zeus::skWhite);
|
||||
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true);
|
||||
// CGX::SetChanCtrl(EChannelId::Channel1, false, GX::SRC_REG, GX::LIGHT_NULL, GX::DF_NONE, GX::AF_NONE);
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel1, false, GX::SRC_REG, GX::SRC_REG, GX::LIGHT_NULL, GX::DF_NONE,
|
||||
GX::AF_NONE);
|
||||
CCubeMaterial::EnsureTevsDirect();
|
||||
}
|
||||
|
||||
@@ -699,6 +829,6 @@ void CCubeRenderer::SetupRendererStates(bool depthWrite) {
|
||||
CGraphics::SetAmbientColor(zeus::skBlack);
|
||||
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, depthWrite);
|
||||
CCubeMaterial::ResetCachedMaterials();
|
||||
aurora::gfx::set_tev_reg_color(GX::TEVREG1, x2fc_tevReg1Color);
|
||||
GXSetTevColor(GX::TEVREG1, x2fc_tevReg1Color);
|
||||
}
|
||||
} // namespace metaforce
|
||||
|
||||
@@ -97,10 +97,9 @@ private:
|
||||
void GenerateSphereRampTex();
|
||||
void LoadThermoPalette();
|
||||
|
||||
void ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, const CTexture& maskTex,
|
||||
const CTexture& indTex, const zeus::CColor& modColor, float scale, float offX,
|
||||
float offY);
|
||||
void ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, const CTexture& maskTex);
|
||||
void ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, CTexture& maskTex, CTexture& indTex,
|
||||
const zeus::CColor& modColor, float scale, float offX, float offY);
|
||||
void ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, CTexture& maskTex);
|
||||
void DoPhazonSuitIndirectAlphaBlur(float blurRadius, float f2, const TLockedToken<CTexture>& indTex);
|
||||
|
||||
public:
|
||||
@@ -179,11 +178,12 @@ public:
|
||||
u32 GetFPS() override;
|
||||
void CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) override;
|
||||
void DrawSpaceWarp(const zeus::CVector3f& pt, float strength) override;
|
||||
void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
void DrawThermalModel(CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) override;
|
||||
void DrawModelDisintegrate(const CModel& model, const CTexture& tex, const zeus::CColor& color,
|
||||
TConstVectorRef positions, TConstVectorRef normals) override;
|
||||
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) override;
|
||||
void DrawModelDisintegrate(CModel& model, CTexture& tex, const zeus::CColor& color, TConstVectorRef positions,
|
||||
TConstVectorRef normals, float t) override;
|
||||
void DrawModelFlat(CModel& model, const CModelFlags& flags, bool unsortedOnly, TConstVectorRef positions,
|
||||
TConstVectorRef normals) override;
|
||||
void SetWireframeFlags(s32 flags) override;
|
||||
void SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) override;
|
||||
void RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const TLockedToken<CModel>* model,
|
||||
@@ -217,6 +217,9 @@ public:
|
||||
|
||||
void ActivateLightsForModel(const CAreaListItem* areaItem, CCubeModel& model);
|
||||
|
||||
void DoThermalModelDraw(CCubeModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags);
|
||||
|
||||
// Getters
|
||||
[[nodiscard]] bool IsInAreaDraw() const { return x318_30_inAreaDraw; }
|
||||
[[nodiscard]] bool IsReflectionDirty() const { return x318_24_refectionDirty; }
|
||||
|
||||
30
Runtime/Graphics/CGX.cpp
Normal file
30
Runtime/Graphics/CGX.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "CGX.hpp"
|
||||
|
||||
#include "Graphics/CTexture.hpp"
|
||||
|
||||
namespace metaforce::CGX {
|
||||
SGXState sGXState;
|
||||
|
||||
void ResetGXStates() noexcept {
|
||||
sGXState.x48_descList = nullptr;
|
||||
// GXClearVtxDesc();
|
||||
sGXState.x0_arrayPtrs.fill(nullptr);
|
||||
for (GX::TexMapID id = GX::TEXMAP0; id < GX::MAX_TEXMAP; id = static_cast<GX::TexMapID>(id + 1)) {
|
||||
CTexture::InvalidateTexMap(id);
|
||||
}
|
||||
for (GX::TevKColorID id = GX::KCOLOR0; const auto& item : sGXState.x58_kColors) {
|
||||
GXSetTevKColor(id, item);
|
||||
id = static_cast<GX::TevKColorID>(id + 1);
|
||||
}
|
||||
// GXSetTevSwapModeTable
|
||||
SetAlphaCompare(GX::ALWAYS, 0, GX::AOP_AND, GX::ALWAYS, 0);
|
||||
// GXSetCurrentMtx(0);
|
||||
SetNumIndStages(0);
|
||||
// TODO GXSetIndTexCoordScale
|
||||
for (GX::TevStageID id = GX::TEVSTAGE0; id < GX::MAX_TEVSTAGE; id = static_cast<GX::TevStageID>(id + 1)) {
|
||||
SetTevDirect(id);
|
||||
}
|
||||
// GXSetTexCoordCylWrap
|
||||
// GXSetZTexture
|
||||
}
|
||||
} // namespace metaforce::CGX
|
||||
387
Runtime/Graphics/CGX.hpp
Normal file
387
Runtime/Graphics/CGX.hpp
Normal file
@@ -0,0 +1,387 @@
|
||||
#pragma once
|
||||
|
||||
#include "Graphics/GX.hpp"
|
||||
#include "RetroTypes.hpp"
|
||||
|
||||
#include <aurora/model.hpp>
|
||||
#include <zeus/CColor.hpp>
|
||||
|
||||
namespace metaforce::CGX {
|
||||
enum class EChannelId {
|
||||
Channel0, // GX::COLOR0
|
||||
Channel1, // GX::COLOR1
|
||||
};
|
||||
|
||||
struct STevState {
|
||||
u32 x0_colorInArgs = 0;
|
||||
u32 x4_alphaInArgs = 0;
|
||||
u32 x8_colorOps = 0;
|
||||
u32 xc_alphaOps = 0;
|
||||
u32 x10_indFlags = 0;
|
||||
u32 x14_tevOrderFlags = 0;
|
||||
GX::TevKColorSel x18_kColorSel = GX::TEV_KCSEL_1;
|
||||
GX::TevKAlphaSel x19_kAlphaSel = GX::TEV_KASEL_1;
|
||||
};
|
||||
struct STexState {
|
||||
u32 x0_coordGen = 0;
|
||||
};
|
||||
struct SGXState {
|
||||
std::array<void*, 12> x0_arrayPtrs{};
|
||||
std::array<u16, 2> x30_prevChanCtrls{};
|
||||
std::array<u16, 2> x34_chanCtrls{};
|
||||
std::array<GXColor, 2> x38_chanAmbColors;
|
||||
std::array<GXColor, 2> x40_chanMatColors;
|
||||
GX::VtxDescList* x48_descList = nullptr;
|
||||
u8 x4c_dirtyChans = 0;
|
||||
u8 x4d_prevNumChans = 0;
|
||||
u8 x4e_numChans = 0;
|
||||
u8 x4f_numTexGens = 0;
|
||||
u8 x50_numTevStages = 0;
|
||||
u8 x51_numIndStages = 0;
|
||||
u8 x52_zmode = 0;
|
||||
GX::FogType x53_fogType = GX::FOG_NONE;
|
||||
u16 x54_lineWidthAndOffset = 0;
|
||||
u16 x56_blendMode = 0;
|
||||
std::array<GXColor, GX::MAX_KCOLOR> x58_kColors;
|
||||
std::array<STevState, GX::MAX_TEVSTAGE> x68_tevStates;
|
||||
std::array<STexState, GX::MAX_TEXMAP> x228_texStates;
|
||||
u32 x248_alphaCompare = 0;
|
||||
float x24c_fogStartZ = 0.f;
|
||||
float x250_fogEndZ = 0.f;
|
||||
float x254_fogNearZ = 0.f;
|
||||
float x258_fogFarZ = 0.f;
|
||||
GXColor x25c_fogColor;
|
||||
};
|
||||
extern SGXState sGXState;
|
||||
|
||||
static inline void update_fog(u32 value) noexcept {
|
||||
if (sGXState.x53_fogType == GX::FOG_NONE || (sGXState.x56_blendMode & 0xE0) == (value & 0xE0)) {
|
||||
return;
|
||||
}
|
||||
if ((value & 0xE0) == 0x20) {
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
static inline void FlushState() noexcept {
|
||||
if ((sGXState.x4c_dirtyChans & 1) != 0) {
|
||||
u8 numChans = sGXState.x4e_numChans;
|
||||
GXSetNumChans(numChans);
|
||||
sGXState.x4d_prevNumChans = numChans;
|
||||
}
|
||||
if ((sGXState.x4c_dirtyChans & 2) != 0) {
|
||||
// TODO actually COLOR0
|
||||
auto flags = sGXState.x34_chanCtrls[0];
|
||||
GXSetChanCtrl(GX::COLOR0A0, GXBool(flags & 1), GX::ColorSrc(flags >> 1 & 1), GX::ColorSrc(flags >> 2 & 1),
|
||||
flags >> 3 & 0xFF, GX::DiffuseFn(flags >> 11 & 3), GX::AttnFn(flags >> 13 & 3));
|
||||
sGXState.x30_prevChanCtrls[0] = flags;
|
||||
}
|
||||
if ((sGXState.x4c_dirtyChans & 4) != 0) {
|
||||
// TODO actually COLOR1
|
||||
auto flags = sGXState.x34_chanCtrls[1];
|
||||
GXSetChanCtrl(GX::COLOR1A1, GXBool(flags & 1), GX::ColorSrc(flags >> 1 & 1), GX::ColorSrc(flags >> 2 & 1),
|
||||
flags >> 3 & 0xFF, GX::DiffuseFn(flags >> 11 & 3), GX::AttnFn(flags >> 13 & 3));
|
||||
sGXState.x30_prevChanCtrls[1] = flags;
|
||||
}
|
||||
sGXState.x4c_dirtyChans = 0;
|
||||
}
|
||||
|
||||
static inline void Begin(GX::Primitive primitive, GX::VtxFmt fmt, u16 nverts) noexcept {
|
||||
if (sGXState.x4c_dirtyChans != 0) {
|
||||
FlushState();
|
||||
}
|
||||
// TODO GXBegin(type, fmt, nverts);
|
||||
}
|
||||
|
||||
static inline void CallDisplayList(const void* data, u32 nbytes) noexcept {
|
||||
if (sGXState.x4c_dirtyChans != 0) {
|
||||
FlushState();
|
||||
}
|
||||
GXCallDisplayList(data, nbytes);
|
||||
}
|
||||
|
||||
static inline void End() noexcept {
|
||||
// no-op
|
||||
}
|
||||
|
||||
static inline const GXColor& GetChanAmbColor(EChannelId id) noexcept {
|
||||
const auto idx = std::underlying_type_t<EChannelId>(id);
|
||||
return sGXState.x38_chanAmbColors[idx];
|
||||
}
|
||||
|
||||
void ResetGXStates() noexcept;
|
||||
|
||||
static inline void SetAlphaCompare(GX::Compare comp0, u8 ref0, GX::AlphaOp op, GX::Compare comp1, u8 ref1) noexcept {
|
||||
u32 flags = ref1 << 17 | (comp1 & 7) << 14 | (op & 7) << 11 | ref0 << 3 | (comp0 & 7);
|
||||
if (flags != sGXState.x248_alphaCompare) {
|
||||
sGXState.x248_alphaCompare = flags;
|
||||
GXSetAlphaCompare(comp0, ref0 / 255.f, op, comp1, ref1 / 255.f);
|
||||
// GXSetZCompLoc(comp0 == GX::ALWAYS);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void SetArray(GX::Attr attr, const std::vector<T>* data) noexcept {
|
||||
if (data != nullptr && sGXState.x0_arrayPtrs[attr - GX::VA_POS] != data) {
|
||||
GXSetArray(attr, data, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetBlendMode(GX::BlendMode mode, GX::BlendFactor srcFac, GX::BlendFactor dstFac,
|
||||
GX::LogicOp op) noexcept {
|
||||
const u16 flags = (op & 0xF) << 8 | (dstFac & 7) << 5 | (srcFac & 7) << 2 | (mode & 3);
|
||||
if (flags != sGXState.x56_blendMode) {
|
||||
update_fog(flags);
|
||||
sGXState.x56_blendMode = flags;
|
||||
GXSetBlendMode(mode, srcFac, dstFac, op);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetChanAmbColor(EChannelId id, const GXColor& color) noexcept {
|
||||
const auto idx = std::underlying_type_t<EChannelId>(id);
|
||||
if (color != sGXState.x38_chanAmbColors[idx]) {
|
||||
sGXState.x38_chanAmbColors[idx] = color;
|
||||
GXSetChanAmbColor(GX::ChannelID(idx + GX::COLOR0A0), color);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetChanCtrl(EChannelId id, GXBool enable, GX::ColorSrc ambSrc, GX::ColorSrc matSrc,
|
||||
GX::LightMask lights, GX::DiffuseFn diffFn, GX::AttnFn attnFn) noexcept {
|
||||
const auto idx = std::underlying_type_t<EChannelId>(id);
|
||||
const u32 flags = (attnFn & 3) << 13 | (diffFn & 3) << 11 | (lights.to_ulong() & 0xFF) << 3 | (matSrc & 1) << 2 |
|
||||
(ambSrc & 1) << 1 | (u8(enable) & 1);
|
||||
sGXState.x34_chanCtrls[idx] = flags;
|
||||
sGXState.x4c_dirtyChans = 7; // TODO
|
||||
}
|
||||
|
||||
// Helper function for common logic
|
||||
static inline void SetChanCtrl(EChannelId id, GX::LightMask lights) noexcept {
|
||||
const bool hasLights = lights.any();
|
||||
SetChanCtrl(id, hasLights, GX::SRC_REG, GX::SRC_REG, lights, hasLights ? GX::DF_CLAMP : GX::DF_NONE,
|
||||
hasLights ? GX::AF_SPOT : GX::AF_NONE);
|
||||
}
|
||||
|
||||
static inline void SetChanMatColor(EChannelId id, const GXColor& color) noexcept {
|
||||
const auto idx = std::underlying_type_t<EChannelId>(id);
|
||||
if (color != sGXState.x40_chanMatColors[idx]) {
|
||||
sGXState.x40_chanMatColors[idx] = color;
|
||||
GXSetChanMatColor(GX::ChannelID(idx + GX::COLOR0A0), color);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetFog(GX::FogType type, float startZ, float endZ, float nearZ, float farZ,
|
||||
const GXColor& color) noexcept {
|
||||
sGXState.x25c_fogColor = color;
|
||||
sGXState.x53_fogType = type;
|
||||
sGXState.x24c_fogStartZ = startZ;
|
||||
sGXState.x250_fogEndZ = endZ;
|
||||
sGXState.x254_fogNearZ = nearZ;
|
||||
sGXState.x258_fogFarZ = farZ;
|
||||
auto fogColor = color;
|
||||
if ((sGXState.x56_blendMode & 0xE0) == 0x20) {
|
||||
fogColor = zeus::skClear;
|
||||
}
|
||||
// TODO
|
||||
// GXSetFog(type, startZ, endZ, nearZ, farZ, fogColor);
|
||||
}
|
||||
|
||||
void SetIndTexMtxSTPointFive(GX::IndTexMtxID id, s8 scaleExp) noexcept;
|
||||
|
||||
void SetLineWidth(u8 width, GX::TexOffset offset) noexcept;
|
||||
|
||||
static inline void SetNumChans(u8 num) noexcept {
|
||||
sGXState.x4c_dirtyChans = 7; // TODO
|
||||
sGXState.x4e_numChans = num;
|
||||
}
|
||||
|
||||
static inline void SetNumIndStages(u8 num) noexcept {
|
||||
auto& state = sGXState.x51_numIndStages;
|
||||
if (num != state) {
|
||||
state = num;
|
||||
GXSetNumIndStages(num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetNumTevStages(u8 num) noexcept {
|
||||
auto& state = sGXState.x50_numTevStages;
|
||||
if (num != state) {
|
||||
state = num;
|
||||
GXSetNumTevStages(num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetNumTexGens(u8 num) noexcept {
|
||||
auto& state = sGXState.x4f_numTexGens;
|
||||
if (num != state) {
|
||||
state = num;
|
||||
GXSetNumTexGens(num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetStandardTevColorAlphaOp(GX::TevStageID stageId) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId];
|
||||
if (state.x8_colorOps != 0x100 || state.xc_alphaOps != 0x100) {
|
||||
state.x8_colorOps = 0x100;
|
||||
state.xc_alphaOps = 0x100;
|
||||
GXSetTevColorOp(stageId, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
GXSetTevAlphaOp(stageId, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevAlphaIn(GX::TevStageID stageId, GX::TevAlphaArg a, GX::TevAlphaArg b, GX::TevAlphaArg c,
|
||||
GX::TevAlphaArg d) noexcept {
|
||||
u32 flags = (d & 31) << 15 | (c & 31) << 10 | (b & 31) << 5 | (a & 31);
|
||||
auto& state = sGXState.x68_tevStates[stageId].x4_alphaInArgs;
|
||||
if (flags != state) {
|
||||
state = flags;
|
||||
GXSetTevAlphaIn(stageId, a, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevAlphaOp(GX::TevStageID stageId, GX::TevOp op, GX::TevBias bias, GX::TevScale scale,
|
||||
GXBool clamp, GX::TevRegID outReg) noexcept {
|
||||
u32 flags = (outReg & 3) << 9 | (u8(clamp) & 1) << 8 | (scale & 3) << 6 | (bias & 3) << 4 | (op & 15);
|
||||
auto& state = sGXState.x68_tevStates[stageId].xc_alphaOps;
|
||||
if (flags != state) {
|
||||
state = flags;
|
||||
GXSetTevAlphaOp(stageId, op, bias, scale, clamp, outReg);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevAlphaOp_Compressed(GX::TevStageID stageId, u32 ops) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId].xc_alphaOps;
|
||||
if (ops != state) {
|
||||
state = ops;
|
||||
GXSetTevAlphaOp(stageId, GX::TevOp(ops & 31), GX::TevBias(ops >> 4 & 3), GX::TevScale(ops >> 6 & 3),
|
||||
GXBool(ops >> 8 & 1), GX::TevRegID(ops >> 9 & 3));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevColorIn(GX::TevStageID stageId, GX::TevColorArg a, GX::TevColorArg b, GX::TevColorArg c,
|
||||
GX::TevColorArg d) noexcept {
|
||||
u32 flags = (d & 31) << 15 | (c & 31) << 10 | (b & 31) << 5 | (a & 31);
|
||||
auto& state = sGXState.x68_tevStates[stageId].x0_colorInArgs;
|
||||
if (flags != state) {
|
||||
state = flags;
|
||||
GXSetTevColorIn(stageId, a, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevColorOp(GX::TevStageID stageId, GX::TevOp op, GX::TevBias bias, GX::TevScale scale,
|
||||
GXBool clamp, GX::TevRegID outReg) noexcept {
|
||||
u32 flags = (outReg & 3) << 9 | (u8(clamp) & 1) << 8 | (scale & 3) << 6 | (bias & 3) << 4 | (op & 15);
|
||||
auto& state = sGXState.x68_tevStates[stageId].x8_colorOps;
|
||||
if (flags != state) {
|
||||
state = flags;
|
||||
GXSetTevColorOp(stageId, op, bias, scale, clamp, outReg);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevColorOp_Compressed(GX::TevStageID stageId, u32 ops) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId].x8_colorOps;
|
||||
if (ops != state) {
|
||||
state = ops;
|
||||
GXSetTevColorOp(stageId, GX::TevOp(ops & 31), GX::TevBias(ops >> 4 & 3), GX::TevScale(ops >> 6 & 3),
|
||||
GXBool(ops >> 8 & 1), GX::TevRegID(ops >> 9 & 3));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevDirect(GX::TevStageID stageId) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId].x10_indFlags;
|
||||
if (state != 0) {
|
||||
state = 0;
|
||||
// TODO
|
||||
// GXSetTevDirect(stageId);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetStandardDirectTev_Compressed(GX::TevStageID stageId, u32 colorArgs, u32 alphaArgs, u32 colorOps,
|
||||
u32 alphaOps) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId];
|
||||
SetTevDirect(stageId);
|
||||
if (state.x0_colorInArgs != colorArgs) {
|
||||
state.x0_colorInArgs = colorArgs;
|
||||
GXSetTevColorIn(stageId, GX::TevColorArg(colorArgs & 31), GX::TevColorArg(colorArgs >> 5 & 31),
|
||||
GX::TevColorArg(colorArgs >> 10 & 31), GX::TevColorArg(colorArgs >> 15 & 31));
|
||||
}
|
||||
if (state.x4_alphaInArgs != alphaArgs) {
|
||||
state.x4_alphaInArgs = alphaArgs;
|
||||
GXSetTevAlphaIn(stageId, GX::TevAlphaArg(alphaArgs & 31), GX::TevAlphaArg(alphaArgs >> 5 & 31),
|
||||
GX::TevAlphaArg(alphaArgs >> 10 & 31), GX::TevAlphaArg(alphaArgs >> 15 & 31));
|
||||
}
|
||||
if (colorOps != alphaOps || (colorOps & 0x1FF) != 0x100) {
|
||||
SetTevColorOp_Compressed(stageId, colorOps);
|
||||
SetTevAlphaOp_Compressed(stageId, alphaOps);
|
||||
} else if (colorOps != state.x8_colorOps || colorOps != state.xc_alphaOps) {
|
||||
state.x8_colorOps = colorOps;
|
||||
state.xc_alphaOps = colorOps;
|
||||
const auto outReg = GX::TevRegID(colorOps >> 9 & 3);
|
||||
GXSetTevColorOp(stageId, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, outReg);
|
||||
GXSetTevAlphaOp(stageId, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, outReg);
|
||||
}
|
||||
}
|
||||
|
||||
void SetTevIndirect(GX::TevStageID stageId, GX::IndTexStageID indStage, GX::IndTexFormat fmt, GX::IndTexBiasSel biasSel,
|
||||
GX::IndTexMtxID mtxSel, GX::IndTexWrap wrapS, GX::IndTexWrap wrapT, GXBool addPrev, GXBool indLod,
|
||||
GX::IndTexAlphaSel alphaSel) noexcept;
|
||||
|
||||
void SetTevIndWarp(GX::TevStageID stageId, GX::IndTexStageID indStage, GXBool signedOffset, GXBool replaceMode,
|
||||
GX::IndTexMtxID mtxSel) noexcept;
|
||||
|
||||
static inline void SetTevKAlphaSel(GX::TevStageID stageId, GX::TevKAlphaSel sel) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId].x19_kAlphaSel;
|
||||
if (sel != state) {
|
||||
state = sel;
|
||||
GXSetTevKAlphaSel(stageId, sel);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevKColor(GX::TevKColorID id, const GXColor& color) noexcept {
|
||||
auto& state = sGXState.x58_kColors[id];
|
||||
if (color != state) {
|
||||
state = color;
|
||||
GXSetTevKColor(id, color);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevKColorSel(GX::TevStageID stageId, GX::TevKColorSel sel) noexcept {
|
||||
auto& state = sGXState.x68_tevStates[stageId].x18_kColorSel;
|
||||
if (sel != state) {
|
||||
state = sel;
|
||||
GXSetTevKColorSel(stageId, sel);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTevOrder(GX::TevStageID stageId, GX::TexCoordID texCoord, GX::TexMapID texMap,
|
||||
GX::ChannelID color) noexcept {
|
||||
u32 flags = (color & 0xFF) << 16 | (texMap & 0xFF) << 8 | (texCoord & 0xFF);
|
||||
auto& state = sGXState.x68_tevStates[stageId].x14_tevOrderFlags;
|
||||
if (flags != state) {
|
||||
state = flags;
|
||||
GXSetTevOrder(stageId, texCoord, texMap, color);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetTexCoordGen(GX::TexCoordID dstCoord, GX::TexGenType fn, GX::TexGenSrc src, u32 mtx,
|
||||
GXBool normalize, u32 postMtx) noexcept {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SetVtxDescv(GX::VtxDescList* descList) noexcept;
|
||||
|
||||
static inline void SetVtxDescv_Compressed(u32 descList) noexcept {
|
||||
// TODO convert to GX::VtxDescList
|
||||
aurora::gfx::model::set_vtx_desc_compressed(descList);
|
||||
}
|
||||
|
||||
static inline void SetZMode(GXBool compareEnable, GX::Compare func, GXBool updateEnable) noexcept {
|
||||
u32 flags = (func & 0xFF) << 2 | (u8(updateEnable) << 1) | (u8(compareEnable) & 1);
|
||||
auto& state = sGXState.x52_zmode;
|
||||
if (flags != state) {
|
||||
state = flags;
|
||||
GXSetZMode(compareEnable, func, updateEnable);
|
||||
}
|
||||
}
|
||||
} // namespace metaforce::CGX
|
||||
@@ -6,18 +6,19 @@
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTextSupportShader.hpp"
|
||||
#include "Runtime/GuiSys/CGuiSys.hpp"
|
||||
#include "Runtime/Graphics/CGX.hpp"
|
||||
|
||||
#include <zeus/Math.hpp>
|
||||
|
||||
namespace metaforce {
|
||||
CGraphics::CProjectionState CGraphics::g_Proj;
|
||||
CFogState CGraphics::g_Fog;
|
||||
// CFogState CGraphics::g_Fog;
|
||||
float CGraphics::g_ProjAspect = 1.f;
|
||||
u32 CGraphics::g_NumBreakpointsWaiting = 0;
|
||||
u32 CGraphics::g_FlippingState;
|
||||
bool CGraphics::g_LastFrameUsedAbove = false;
|
||||
bool CGraphics::g_InterruptLastFrameUsedAbove = false;
|
||||
std::bitset<aurora::gfx::MaxLights> CGraphics::g_LightActive{};
|
||||
GX::LightMask CGraphics::g_LightActive{};
|
||||
zeus::CTransform CGraphics::g_GXModelView;
|
||||
zeus::CTransform CGraphics::g_GXModelViewInvXpose;
|
||||
zeus::CTransform CGraphics::g_GXModelMatrix = zeus::CTransform();
|
||||
@@ -56,9 +57,15 @@ const std::array<zeus::CMatrix3f, 6> CGraphics::skCubeBasisMats{{
|
||||
{-1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, -1.f},
|
||||
}};
|
||||
|
||||
// Stream API
|
||||
static EStreamFlags sStreamFlags;
|
||||
static zeus::CColor sQueuedColor;
|
||||
static zeus::CVector2f sQueuedTexCoord;
|
||||
static zeus::CVector3f sQueuedNormal;
|
||||
|
||||
void CGraphics::DisableAllLights() {
|
||||
g_LightActive.reset();
|
||||
aurora::gfx::set_light_state(g_LightActive);
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, {});
|
||||
}
|
||||
|
||||
void CGraphics::LoadLight(ERglLight light, const CLight& info) {
|
||||
@@ -89,50 +96,55 @@ void CGraphics::LoadLight(ERglLight light, const CLight& info) {
|
||||
}
|
||||
|
||||
void CGraphics::EnableLight(ERglLight light) {
|
||||
CGX::SetNumChans(1);
|
||||
if (!g_LightActive.test(light)) {
|
||||
g_LightActive.set(light);
|
||||
aurora::gfx::set_light_state(g_LightActive);
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, g_LightActive);
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics::SetLightState(std::bitset<aurora::gfx::MaxLights> lightState) {
|
||||
void CGraphics::SetLightState(GX::LightMask lightState) {
|
||||
g_LightActive = lightState;
|
||||
aurora::gfx::set_light_state(g_LightActive);
|
||||
const bool hasLights = lightState.any();
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, hasLights, GX::SRC_REG,
|
||||
sStreamFlags & EStreamFlagBits::fHasColor ? GX::SRC_VTX : GX::SRC_REG, lightState,
|
||||
hasLights ? GX::DF_CLAMP : GX::DF_NONE, hasLights ? GX::AF_SPOT : GX::AF_NONE);
|
||||
}
|
||||
|
||||
void CGraphics::SetAmbientColor(const zeus::CColor& col) {
|
||||
aurora::gfx::set_chan_amb_color(GX::COLOR0A0, col);
|
||||
aurora::gfx::set_chan_amb_color(GX::COLOR1A1, col);
|
||||
CGX::SetChanAmbColor(CGX::EChannelId::Channel0, col);
|
||||
CGX::SetChanAmbColor(CGX::EChannelId::Channel1, col);
|
||||
}
|
||||
|
||||
void CGraphics::SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) {
|
||||
g_Fog.m_mode = mode > ERglFogMode::PerspRevExp2 ? ERglFogMode(int(mode) - 8) : mode;
|
||||
g_Fog.m_color = color;
|
||||
if (CGraphics::g_Proj.x18_far == CGraphics::g_Proj.x14_near || endz == startz) {
|
||||
g_Fog.m_A = 0.f;
|
||||
g_Fog.m_B = 0.5f;
|
||||
g_Fog.m_C = 0.f;
|
||||
} else {
|
||||
float depthrange = CGraphics::g_Proj.x18_far - CGraphics::g_Proj.x14_near;
|
||||
float fogrange = endz - startz;
|
||||
g_Fog.m_A = (CGraphics::g_Proj.x18_far * CGraphics::g_Proj.x14_near) / (depthrange * fogrange);
|
||||
g_Fog.m_B = CGraphics::g_Proj.x18_far / depthrange;
|
||||
g_Fog.m_C = startz / fogrange;
|
||||
}
|
||||
// g_Fog.m_mode = mode > ERglFogMode::PerspRevExp2 ? ERglFogMode(int(mode) - 8) : mode;
|
||||
// g_Fog.m_color = color;
|
||||
// if (CGraphics::g_Proj.x18_far == CGraphics::g_Proj.x14_near || endz == startz) {
|
||||
// g_Fog.m_A = 0.f;
|
||||
// g_Fog.m_B = 0.5f;
|
||||
// g_Fog.m_C = 0.f;
|
||||
// } else {
|
||||
// float depthrange = CGraphics::g_Proj.x18_far - CGraphics::g_Proj.x14_near;
|
||||
// float fogrange = endz - startz;
|
||||
// g_Fog.m_A = (CGraphics::g_Proj.x18_far * CGraphics::g_Proj.x14_near) / (depthrange * fogrange);
|
||||
// g_Fog.m_B = CGraphics::g_Proj.x18_far / depthrange;
|
||||
// g_Fog.m_C = startz / fogrange;
|
||||
// }
|
||||
CGX::SetFog(GX::FogType(mode), startz, endz, g_Proj.x14_near, g_Proj.x18_far, color);
|
||||
}
|
||||
|
||||
void CGraphics::SetDepthWriteMode(bool compare_enable, ERglEnum comp, bool update_enable) {
|
||||
g_depthFunc = comp;
|
||||
aurora::gfx::set_depth_mode(compare_enable, comp, update_enable);
|
||||
CGX::SetZMode(compare_enable, GX::Compare(comp), update_enable);
|
||||
}
|
||||
|
||||
void CGraphics::SetBlendMode(ERglBlendMode mode, ERglBlendFactor src, ERglBlendFactor dst, ERglLogicOp op) {
|
||||
aurora::gfx::set_blend_mode(mode, src, dst, op);
|
||||
CGX::SetBlendMode(GX::BlendMode(mode), GX::BlendFactor(src), GX::BlendFactor(dst), GX::LogicOp(op));
|
||||
}
|
||||
|
||||
void CGraphics::SetCullMode(ERglCullMode mode) {
|
||||
g_cullMode = mode;
|
||||
aurora::gfx::set_cull_mode(mode);
|
||||
GXSetCullMode(GX::CullMode(mode));
|
||||
}
|
||||
|
||||
void CGraphics::BeginScene() {
|
||||
@@ -140,7 +152,8 @@ void CGraphics::BeginScene() {
|
||||
}
|
||||
|
||||
void CGraphics::EndScene() {
|
||||
aurora::gfx::set_depth_mode(true, ERglEnum::LEqual, true);
|
||||
CGX::SetZMode(true, GX::LEQUAL, true);
|
||||
|
||||
/* Spinwait until g_NumBreakpointsWaiting is 0 */
|
||||
/* ++g_NumBreakpointsWaiting; */
|
||||
/* GXCopyDisp to g_CurrenFrameBuf with clear enabled */
|
||||
@@ -497,26 +510,18 @@ void CGraphics::SetUseVideoFilter(bool filter) {
|
||||
|
||||
void CGraphics::SetClearColor(const zeus::CColor& color) {
|
||||
g_ClearColor = color;
|
||||
aurora::gfx::set_clear_color(color);
|
||||
GXSetCopyClear(color, g_ClearDepthValue);
|
||||
}
|
||||
|
||||
void CGraphics::SetCopyClear(const zeus::CColor& color, float depth) {
|
||||
g_ClearColor = color;
|
||||
g_ClearDepthValue = depth; // 1.6777215E7 * depth; Metroid Prime needed this to convert float [0,1] depth into 24 bit
|
||||
// range, we no longer have this requirement
|
||||
aurora::gfx::set_clear_color(color);
|
||||
// TODO do we care about depth value?
|
||||
// GXSetCopyClear(g_ClearColor, g_ClearDepthValue);
|
||||
GXSetCopyClear(g_ClearColor, g_ClearDepthValue);
|
||||
}
|
||||
|
||||
void CGraphics::SetIsBeginSceneClearFb(bool clear) { g_IsBeginSceneClearFb = clear; }
|
||||
|
||||
// Stream API
|
||||
static EStreamFlags sStreamFlags;
|
||||
static zeus::CColor sQueuedColor;
|
||||
static zeus::CVector2f sQueuedTexCoord;
|
||||
static zeus::CVector3f sQueuedNormal;
|
||||
|
||||
void CGraphics::SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass) {
|
||||
CTevCombiners::SetupPass(stage, pass);
|
||||
}
|
||||
@@ -583,13 +588,22 @@ void CGraphics::DrawPrimitive(GX::Primitive primitive, const zeus::CVector3f* po
|
||||
|
||||
void CGraphics::SetTevStates(EStreamFlags flags) noexcept {
|
||||
if (flags & EStreamFlagBits::fHasTexture) {
|
||||
aurora::gfx::set_tev_order(GX::TEVSTAGE0, GX::TEXCOORD0, GX::TEXMAP0, GX::COLOR0A0);
|
||||
aurora::gfx::set_tev_order(GX::TEVSTAGE1, GX::TEXCOORD1, GX::TEXMAP1, GX::COLOR0A0);
|
||||
} else {
|
||||
aurora::gfx::set_tev_order(GX::TEVSTAGE0, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR0A0);
|
||||
aurora::gfx::set_tev_order(GX::TEVSTAGE1, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR0A0);
|
||||
CGX::SetNumChans(1);
|
||||
CGX::SetNumTexGens(0);
|
||||
CGX::SetNumTevStages(1);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD0, GX::TEXMAP0, GX::COLOR0A0);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE1, GX::TEXCOORD1, GX::TEXMAP1, GX::COLOR0A0);
|
||||
} else /* if (flags < 8) ? */ {
|
||||
CGX::SetNumChans(1);
|
||||
CGX::SetNumTexGens(2); // sTextureUsed & 3?
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR0A0);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE1, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR0A0);
|
||||
}
|
||||
CGX::SetNumIndStages(0);
|
||||
// TODO load TCGs
|
||||
aurora::gfx::set_chan_mat_src(GX::COLOR0A0, flags & EStreamFlagBits::fHasColor ? GX::SRC_VTX : GX::SRC_REG);
|
||||
const bool hasLights = g_LightActive.any();
|
||||
CGX::SetChanCtrl(CGX::EChannelId::Channel0, hasLights, GX::SRC_REG,
|
||||
flags & EStreamFlagBits::fHasColor ? GX::SRC_VTX : GX::SRC_REG, g_LightActive,
|
||||
hasLights ? GX::DF_CLAMP : GX::DF_NONE, hasLights ? GX::AF_SPOT : GX::AF_NONE);
|
||||
}
|
||||
} // namespace metaforce
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
#include "Runtime/Graphics/GX.hpp"
|
||||
#include "Runtime/Graphics/CTevCombiners.hpp"
|
||||
#include "Runtime/ConsoleVariables/CVar.hpp"
|
||||
#include "Runtime/Graphics/CTevCombiners.hpp"
|
||||
#include "Runtime/Graphics/GX.hpp"
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
@@ -25,6 +25,83 @@ extern CVar* g_disableLighting;
|
||||
class CLight;
|
||||
class CTimeProvider;
|
||||
|
||||
enum class ERglCullMode : std::underlying_type_t<GX::CullMode> {
|
||||
None = GX::CULL_NONE,
|
||||
Front = GX::CULL_FRONT,
|
||||
Back = GX::CULL_BACK,
|
||||
All = GX::CULL_ALL,
|
||||
};
|
||||
|
||||
enum class ERglBlendMode : std::underlying_type_t<GX::BlendMode> {
|
||||
None = GX::BM_NONE,
|
||||
Blend = GX::BM_BLEND,
|
||||
Logic = GX::BM_LOGIC,
|
||||
Subtract = GX::BM_SUBTRACT,
|
||||
Max = GX::MAX_BLENDMODE,
|
||||
};
|
||||
|
||||
enum class ERglBlendFactor : std::underlying_type_t<GX::BlendFactor> {
|
||||
Zero = GX::BL_ZERO,
|
||||
One = GX::BL_ONE,
|
||||
SrcColor = GX::BL_SRCCLR,
|
||||
InvSrcColor = GX::BL_INVSRCCLR,
|
||||
SrcAlpha = GX::BL_SRCALPHA,
|
||||
InvSrcAlpha = GX::BL_INVSRCALPHA,
|
||||
DstAlpha = GX::BL_DSTALPHA,
|
||||
InvDstAlpha = GX::BL_INVDSTALPHA,
|
||||
DstColor = GX::BL_DSTCLR,
|
||||
InvDstColor = GX::BL_INVDSTCLR,
|
||||
};
|
||||
|
||||
enum class ERglLogicOp : std::underlying_type_t<GX::LogicOp> {
|
||||
Clear = GX::LO_CLEAR,
|
||||
And = GX::LO_AND,
|
||||
RevAnd = GX::LO_REVAND,
|
||||
Copy = GX::LO_COPY,
|
||||
InvAnd = GX::LO_INVAND,
|
||||
NoOp = GX::LO_NOOP,
|
||||
Xor = GX::LO_XOR,
|
||||
Or = GX::LO_OR,
|
||||
Nor = GX::LO_NOR,
|
||||
Equiv = GX::LO_EQUIV,
|
||||
Inv = GX::LO_INV,
|
||||
RevOr = GX::LO_REVOR,
|
||||
InvCopy = GX::LO_INVCOPY,
|
||||
InvOr = GX::LO_INVOR,
|
||||
NAnd = GX::LO_NAND,
|
||||
Set = GX::LO_SET,
|
||||
};
|
||||
|
||||
enum class ERglAlphaFunc : std::underlying_type_t<GX::Compare> {
|
||||
Never = GX::NEVER,
|
||||
Less = GX::LESS,
|
||||
Equal = GX::EQUAL,
|
||||
LEqual = GX::LEQUAL,
|
||||
Greater = GX::GREATER,
|
||||
NEqual = GX::NEQUAL,
|
||||
GEqual = GX::GEQUAL,
|
||||
Always = GX::ALWAYS,
|
||||
};
|
||||
|
||||
enum class ERglAlphaOp : std::underlying_type_t<GX::AlphaOp> {
|
||||
And = GX::AOP_AND,
|
||||
Or = GX::AOP_OR,
|
||||
Xor = GX::AOP_XOR,
|
||||
XNor = GX::AOP_XNOR,
|
||||
Max = GX::MAX_ALPHAOP,
|
||||
};
|
||||
|
||||
enum class ERglEnum : std::underlying_type_t<GX::Compare> {
|
||||
Never = GX::NEVER,
|
||||
Less = GX::LESS,
|
||||
Equal = GX::EQUAL,
|
||||
LEqual = GX::LEQUAL,
|
||||
Greater = GX::GREATER,
|
||||
NEqual = GX::NEQUAL,
|
||||
GEqual = GX::GEQUAL,
|
||||
Always = GX::ALWAYS,
|
||||
};
|
||||
|
||||
using ERglLight = u8;
|
||||
|
||||
struct SViewport {
|
||||
@@ -104,14 +181,14 @@ public:
|
||||
|
||||
static CProjectionState g_Proj;
|
||||
static zeus::CVector2f g_CachedDepthRange;
|
||||
static CFogState g_Fog;
|
||||
// static CFogState g_Fog;
|
||||
static SViewport g_Viewport;
|
||||
static float g_ProjAspect;
|
||||
static u32 g_NumBreakpointsWaiting;
|
||||
static u32 g_FlippingState;
|
||||
static bool g_LastFrameUsedAbove;
|
||||
static bool g_InterruptLastFrameUsedAbove;
|
||||
static std::bitset<aurora::gfx::MaxLights> g_LightActive;
|
||||
static GX::LightMask g_LightActive;
|
||||
static zeus::CTransform g_GXModelView;
|
||||
static zeus::CTransform g_GXModelViewInvXpose;
|
||||
static zeus::CTransform g_GXModelMatrix;
|
||||
@@ -131,7 +208,7 @@ public:
|
||||
static void DisableAllLights();
|
||||
static void LoadLight(ERglLight light, const CLight& info);
|
||||
static void EnableLight(ERglLight light);
|
||||
static void SetLightState(std::bitset<aurora::gfx::MaxLights> lightState);
|
||||
static void SetLightState(GX::LightMask lightState);
|
||||
static void SetAmbientColor(const zeus::CColor& col);
|
||||
static void SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color);
|
||||
static void SetDepthWriteMode(bool test, ERglEnum comp, bool write);
|
||||
|
||||
@@ -17,6 +17,7 @@ set(GRAPHICS_SOURCES
|
||||
CVertexMorphEffect.hpp CVertexMorphEffect.cpp
|
||||
CMoviePlayer.hpp CMoviePlayer.cpp
|
||||
CGraphicsPalette.hpp CGraphicsPalette.cpp
|
||||
CGX.hpp CGX.cpp
|
||||
CPVSVisSet.hpp CPVSVisSet.cpp
|
||||
CPVSVisOctree.hpp CPVSVisOctree.cpp
|
||||
CPVSAreaSet.hpp CPVSAreaSet.cpp
|
||||
|
||||
@@ -105,13 +105,15 @@ public:
|
||||
void DrawUnsortedParts(CModelFlags flags);
|
||||
bool IsLoaded(u32 matIdx);
|
||||
|
||||
TVectorRef GetPositions();
|
||||
TConstVectorRef GetPositions() const;
|
||||
TVectorRef GetNormals();
|
||||
TConstVectorRef GetNormals() const;
|
||||
u32 GetNumMaterialSets() const { return x18_matSets.size(); }
|
||||
bool IsOpaque() const { return x28_modelInst->x3c_firstSortedSurf == nullptr; }
|
||||
const zeus::CAABox& GetAABB() const { return x28_modelInst->x20_worldAABB; }
|
||||
[[nodiscard]] TVectorRef GetPositions();
|
||||
[[nodiscard]] TConstVectorRef GetPositions() const;
|
||||
[[nodiscard]] TVectorRef GetNormals();
|
||||
[[nodiscard]] TConstVectorRef GetNormals() const;
|
||||
[[nodiscard]] u32 GetNumMaterialSets() const { return x18_matSets.size(); }
|
||||
[[nodiscard]] bool IsOpaque() const { return x28_modelInst->x3c_firstSortedSurf == nullptr; }
|
||||
[[nodiscard]] const zeus::CAABox& GetAABB() const { return x28_modelInst->x20_worldAABB; }
|
||||
[[nodiscard]] auto& GetInstance() { return *x28_modelInst; }
|
||||
[[nodiscard]] const auto& GetInstance() const { return *x28_modelInst; }
|
||||
|
||||
static void FrameDone();
|
||||
static void EnableTextureTimeout();
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
#include "Graphics/CTevCombiners.hpp"
|
||||
|
||||
#include "Graphics/CGX.hpp"
|
||||
|
||||
namespace metaforce::CTevCombiners {
|
||||
u32 CTevPass::sNextUniquePass = 0;
|
||||
|
||||
void CTevPass::Execute(ERglTevStage stage) const {
|
||||
aurora::gfx::update_tev_stage(stage, x4_colorPass, x14_alphaPass, x24_colorOp, x38_alphaOp);
|
||||
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(stage), GX::TevKColorSel::TEV_KCSEL_8_8);
|
||||
aurora::gfx::set_tev_k_alpha_sel(static_cast<GX::TevStageID>(stage), GX::TevKAlphaSel::TEV_KASEL_8_8);
|
||||
const auto stageId = GX::TevStageID(stage);
|
||||
CGX::SetTevColorIn(stageId, x4_colorPass.x0_a, x4_colorPass.x4_b, x4_colorPass.x8_c, x4_colorPass.xc_d);
|
||||
CGX::SetTevAlphaIn(stageId, x14_alphaPass.x0_a, x14_alphaPass.x4_b, x14_alphaPass.x8_c, x14_alphaPass.xc_d);
|
||||
CGX::SetTevColorOp(stageId, x24_colorOp.x4_op, x24_colorOp.x8_bias, x24_colorOp.xc_scale, x24_colorOp.x0_clamp,
|
||||
x24_colorOp.x10_regId);
|
||||
CGX::SetTevAlphaOp(stageId, x38_alphaOp.x4_op, x38_alphaOp.x8_bias, x38_alphaOp.xc_scale, x38_alphaOp.x0_clamp,
|
||||
x38_alphaOp.x10_regId);
|
||||
CGX::SetTevKColorSel(stageId, GX::TevKColorSel::TEV_KCSEL_8_8);
|
||||
CGX::SetTevKAlphaSel(stageId, GX::TevKAlphaSel::TEV_KASEL_8_8);
|
||||
}
|
||||
|
||||
constexpr u32 maxTevPasses = 2;
|
||||
@@ -17,10 +25,6 @@ const CTevPass skPassThru{
|
||||
{GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC},
|
||||
{GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA},
|
||||
};
|
||||
const CTevPass skPassZero{
|
||||
{GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO},
|
||||
{GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO},
|
||||
};
|
||||
const CTevPass sTevPass805a5698{
|
||||
{GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_C0, GX::TevColorArg::CC_ZERO},
|
||||
{GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_A0, GX::TevAlphaArg::CA_ZERO},
|
||||
@@ -96,16 +100,13 @@ bool SetPassCombiners(ERglTevStage stage, const CTevPass& pass) {
|
||||
|
||||
void RecomputePasses() {
|
||||
sNumEnabledPasses = 1 - static_cast<int>(sValidPasses[maxTevPasses - 1]);
|
||||
for (u32 i = sNumEnabledPasses; i < maxTevPasses; ++i) {
|
||||
aurora::gfx::disable_tev_stage(ERglTevStage(i));
|
||||
}
|
||||
// CGX::SetNumTevStages(sNumEnabledPasses);
|
||||
CGX::SetNumTevStages(sNumEnabledPasses);
|
||||
}
|
||||
|
||||
void ResetStates() {
|
||||
sValidPasses.fill(false);
|
||||
skPassThru.Execute(ERglTevStage::Stage0);
|
||||
sNumEnabledPasses = 1;
|
||||
// CGX::SetNumTevStages(1);
|
||||
CGX::SetNumTevStages(1);
|
||||
}
|
||||
} // namespace metaforce::CTevCombiners
|
||||
|
||||
@@ -3,9 +3,80 @@
|
||||
#include "Graphics/GX.hpp"
|
||||
#include "RetroTypes.hpp"
|
||||
|
||||
#include <aurora/gfx.hpp>
|
||||
namespace metaforce {
|
||||
enum class ERglTevStage : std::underlying_type_t<GX::TevStageID> {
|
||||
Stage0 = GX::TEVSTAGE0,
|
||||
Stage1 = GX::TEVSTAGE1,
|
||||
Stage2 = GX::TEVSTAGE2,
|
||||
Stage3 = GX::TEVSTAGE3,
|
||||
Stage4 = GX::TEVSTAGE4,
|
||||
Stage5 = GX::TEVSTAGE5,
|
||||
Stage6 = GX::TEVSTAGE6,
|
||||
Stage7 = GX::TEVSTAGE7,
|
||||
Stage8 = GX::TEVSTAGE8,
|
||||
Stage9 = GX::TEVSTAGE9,
|
||||
Stage10 = GX::TEVSTAGE10,
|
||||
Stage11 = GX::TEVSTAGE11,
|
||||
Stage12 = GX::TEVSTAGE12,
|
||||
Stage13 = GX::TEVSTAGE13,
|
||||
Stage14 = GX::TEVSTAGE14,
|
||||
Stage15 = GX::TEVSTAGE15,
|
||||
Max = GX::MAX_TEVSTAGE,
|
||||
None = GX::NULL_STAGE,
|
||||
};
|
||||
|
||||
namespace metaforce::CTevCombiners {
|
||||
namespace CTevCombiners {
|
||||
struct CTevOp {
|
||||
bool x0_clamp = true;
|
||||
GX::TevOp x4_op = GX::TevOp::TEV_ADD;
|
||||
GX::TevBias x8_bias = GX::TevBias::TB_ZERO;
|
||||
GX::TevScale xc_scale = GX::TevScale::CS_SCALE_1;
|
||||
GX::TevRegID x10_regId = GX::TevRegID::TEVPREV;
|
||||
|
||||
constexpr CTevOp() = default;
|
||||
constexpr CTevOp(bool clamp, GX::TevOp op, GX::TevBias bias, GX::TevScale scale, GX::TevRegID regId)
|
||||
: x0_clamp(clamp), x4_op(op), x8_bias(bias), xc_scale(scale), x10_regId(regId) {}
|
||||
constexpr CTevOp(u32 compressedDesc)
|
||||
: x0_clamp((compressedDesc >> 8 & 1) != 0)
|
||||
, x4_op(static_cast<GX::TevOp>(compressedDesc & 0xF))
|
||||
, x8_bias(static_cast<GX::TevBias>(compressedDesc >> 4 & 3))
|
||||
, xc_scale(static_cast<GX::TevScale>(compressedDesc >> 6 & 3))
|
||||
, x10_regId(static_cast<GX::TevRegID>(compressedDesc >> 9 & 3)) {}
|
||||
|
||||
auto operator<=>(const CTevOp&) const = default;
|
||||
};
|
||||
struct ColorPass {
|
||||
GX::TevColorArg x0_a;
|
||||
GX::TevColorArg x4_b;
|
||||
GX::TevColorArg x8_c;
|
||||
GX::TevColorArg xc_d;
|
||||
|
||||
constexpr ColorPass(GX::TevColorArg a, GX::TevColorArg b, GX::TevColorArg c, GX::TevColorArg d)
|
||||
: x0_a(a), x4_b(b), x8_c(c), xc_d(d) {}
|
||||
constexpr ColorPass(u32 compressedDesc)
|
||||
: x0_a(static_cast<GX::TevColorArg>(compressedDesc & 0x1F))
|
||||
, x4_b(static_cast<GX::TevColorArg>(compressedDesc >> 5 & 0x1F))
|
||||
, x8_c(static_cast<GX::TevColorArg>(compressedDesc >> 10 & 0x1F))
|
||||
, xc_d(static_cast<GX::TevColorArg>(compressedDesc >> 15 & 0x1F)) {}
|
||||
|
||||
auto operator<=>(const ColorPass&) const = default;
|
||||
};
|
||||
struct AlphaPass {
|
||||
GX::TevAlphaArg x0_a;
|
||||
GX::TevAlphaArg x4_b;
|
||||
GX::TevAlphaArg x8_c;
|
||||
GX::TevAlphaArg xc_d;
|
||||
|
||||
constexpr AlphaPass(GX::TevAlphaArg a, GX::TevAlphaArg b, GX::TevAlphaArg c, GX::TevAlphaArg d)
|
||||
: x0_a(a), x4_b(b), x8_c(c), xc_d(d) {}
|
||||
constexpr AlphaPass(u32 compressedDesc)
|
||||
: x0_a(static_cast<GX::TevAlphaArg>(compressedDesc & 0x1F))
|
||||
, x4_b(static_cast<GX::TevAlphaArg>(compressedDesc >> 5 & 0x1F))
|
||||
, x8_c(static_cast<GX::TevAlphaArg>(compressedDesc >> 10 & 0x1F))
|
||||
, xc_d(static_cast<GX::TevAlphaArg>(compressedDesc >> 15 & 0x1F)) {}
|
||||
|
||||
auto operator<=>(const AlphaPass&) const = default;
|
||||
};
|
||||
class CTevPass {
|
||||
u32 x0_id;
|
||||
ColorPass x4_colorPass;
|
||||
@@ -29,7 +100,6 @@ public:
|
||||
};
|
||||
|
||||
extern const CTevPass skPassThru;
|
||||
extern const CTevPass skPassZero;
|
||||
extern const CTevPass sTevPass805a5698;
|
||||
extern const CTevPass sTevPass805a5e70;
|
||||
extern const CTevPass sTevPass805a5ebc;
|
||||
@@ -47,4 +117,5 @@ void DeletePass(ERglTevStage stage);
|
||||
bool SetPassCombiners(ERglTevStage stage, const CTevPass& pass);
|
||||
void RecomputePasses();
|
||||
void ResetStates();
|
||||
} // namespace metaforce::CTevCombiners
|
||||
} // namespace CTevCombiners
|
||||
} // namespace metaforce
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include "../GCNTypes.hpp"
|
||||
|
||||
#include <bit>
|
||||
#include <bitset>
|
||||
|
||||
#include <zeus/CColor.hpp>
|
||||
|
||||
namespace GX {
|
||||
enum Attr {
|
||||
@@ -303,12 +307,14 @@ enum TevSwapSel {
|
||||
TEV_SWAP3 = 0x3,
|
||||
MAX_TEVSWAP = 0x4,
|
||||
};
|
||||
|
||||
enum TevColorChan {
|
||||
CH_RED = 0x0,
|
||||
CH_GREEN = 0x1,
|
||||
CH_BLUE = 0x2,
|
||||
CH_ALPHA = 0x3,
|
||||
};
|
||||
|
||||
enum TevRegID {
|
||||
TEVPREV = 0,
|
||||
TEVREG0 = 1,
|
||||
@@ -319,14 +325,14 @@ enum TevRegID {
|
||||
|
||||
enum DiffuseFn {
|
||||
DF_NONE = 0,
|
||||
DF_SIGN,
|
||||
DF_CLAMP,
|
||||
DF_SIGN = 1,
|
||||
DF_CLAMP = 2,
|
||||
};
|
||||
|
||||
enum AttnFn {
|
||||
AF_SPEC = 0,
|
||||
AF_SPOT = 1,
|
||||
AF_NONE,
|
||||
AF_NONE = 2,
|
||||
};
|
||||
|
||||
enum Primitive {
|
||||
@@ -405,7 +411,7 @@ enum Compare {
|
||||
ALWAYS,
|
||||
};
|
||||
|
||||
enum BlendFactor : uint16_t {
|
||||
enum BlendFactor {
|
||||
BL_ZERO,
|
||||
BL_ONE,
|
||||
BL_SRCCLR,
|
||||
@@ -413,10 +419,19 @@ enum BlendFactor : uint16_t {
|
||||
BL_SRCALPHA,
|
||||
BL_INVSRCALPHA,
|
||||
BL_DSTALPHA,
|
||||
BL_INVDSTALPHA
|
||||
BL_INVDSTALPHA,
|
||||
BL_DSTCLR,
|
||||
BL_INVDSTCLR,
|
||||
};
|
||||
|
||||
enum TextureFormat : uint32_t {
|
||||
enum CullMode {
|
||||
CULL_NONE,
|
||||
CULL_FRONT,
|
||||
CULL_BACK,
|
||||
CULL_ALL,
|
||||
};
|
||||
|
||||
enum TextureFormat {
|
||||
TF_I4 = 0x0,
|
||||
TF_I8 = 0x1,
|
||||
TF_IA4 = 0x2,
|
||||
@@ -520,6 +535,7 @@ enum IndTexAlphaSel {
|
||||
ITBA_U,
|
||||
MAX_ITBALPHA,
|
||||
};
|
||||
|
||||
enum IndTexStageID {
|
||||
INDTEXSTAGE0,
|
||||
INDTEXSTAGE1,
|
||||
@@ -611,6 +627,8 @@ enum LightID {
|
||||
MAX_LIGHT = 0x100,
|
||||
LIGHT_NULL = 0x000,
|
||||
};
|
||||
constexpr u8 MaxLights = std::bit_width<std::underlying_type_t<LightID>>(MAX_LIGHT) - 1;
|
||||
using LightMask = std::bitset<MaxLights>;
|
||||
|
||||
enum FogType {
|
||||
FOG_NONE = 0x00,
|
||||
@@ -627,3 +645,43 @@ enum FogType {
|
||||
};
|
||||
|
||||
} // namespace GX
|
||||
|
||||
using GXColor = zeus::CColor;
|
||||
using GXBool = bool;
|
||||
|
||||
void GXSetNumChans(u8 num) noexcept;
|
||||
void GXSetNumIndStages(u8 num) noexcept;
|
||||
void GXSetNumTevStages(u8 num) noexcept;
|
||||
void GXSetNumTexGens(u8 num) noexcept;
|
||||
void GXSetTevAlphaIn(GX::TevStageID stageId, GX::TevAlphaArg a, GX::TevAlphaArg b, GX::TevAlphaArg c,
|
||||
GX::TevAlphaArg d) noexcept;
|
||||
void GXSetTevAlphaOp(GX::TevStageID stageId, GX::TevOp op, GX::TevBias bias, GX::TevScale scale, GXBool clamp,
|
||||
GX::TevRegID outReg) noexcept;
|
||||
void GXSetTevColorIn(GX::TevStageID stageId, GX::TevColorArg a, GX::TevColorArg b, GX::TevColorArg c,
|
||||
GX::TevColorArg d) noexcept;
|
||||
void GXSetTevColorOp(GX::TevStageID stageId, GX::TevOp op, GX::TevBias bias, GX::TevScale scale, GXBool clamp,
|
||||
GX::TevRegID outReg) noexcept;
|
||||
void GXSetCullMode(GX::CullMode mode) noexcept;
|
||||
void GXSetBlendMode(GX::BlendMode mode, GX::BlendFactor src, GX::BlendFactor dst, GX::LogicOp op) noexcept;
|
||||
void GXSetZMode(GXBool compare_enable, GX::Compare func, GXBool update_enable) noexcept;
|
||||
void GXSetTevColor(GX::TevRegID id, const GXColor& color) noexcept;
|
||||
void GXSetTevKColor(GX::TevKColorID id, const GXColor& color) noexcept;
|
||||
void GXSetAlphaUpdate(GXBool enabled) noexcept;
|
||||
// Originally u8 instead of float
|
||||
void GXSetDstAlpha(GXBool enabled, float value) noexcept;
|
||||
void GXSetCopyClear(const GXColor& color, float depth) noexcept;
|
||||
void GXSetTevOrder(GX::TevStageID id, GX::TexCoordID tcid, GX::TexMapID tmid, GX::ChannelID cid) noexcept;
|
||||
void GXSetTevKColorSel(GX::TevStageID id, GX::TevKColorSel sel) noexcept;
|
||||
void GXSetTevKAlphaSel(GX::TevStageID id, GX::TevKAlphaSel sel) noexcept;
|
||||
void GXSetChanAmbColor(GX::ChannelID id, const GXColor& color) noexcept;
|
||||
void GXSetChanMatColor(GX::ChannelID id, const GXColor& color) noexcept;
|
||||
void GXSetChanCtrl(GX::ChannelID id, GXBool lightingEnabled, GX::ColorSrc ambSrc, GX::ColorSrc matSrc,
|
||||
GX::LightMask lightState, GX::DiffuseFn diffFn, GX::AttnFn attnFn) noexcept;
|
||||
// Originally u8 instead of floats
|
||||
void GXSetAlphaCompare(GX::Compare comp0, float ref0, GX::AlphaOp op, GX::Compare comp1, float ref1) noexcept;
|
||||
void GXSetVtxDescv(GX::VtxDescList* list) noexcept;
|
||||
void GXClearVtxDesc() noexcept;
|
||||
void GXSetArray(GX::Attr attr, const void* data, u8 stride) noexcept;
|
||||
void GXSetTevDirect(GX::TevStageID stageId) noexcept;
|
||||
void GXSetFog(GX::FogType type, float startZ, float endZ, float nearZ, float farZ, const GXColor& color) noexcept;
|
||||
void GXCallDisplayList(const void* data, u32 nbytes) noexcept;
|
||||
|
||||
@@ -92,11 +92,12 @@ public:
|
||||
virtual u32 GetFPS() = 0;
|
||||
virtual void CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) = 0;
|
||||
virtual void DrawSpaceWarp(const zeus::CVector3f& pt, float strength) = 0;
|
||||
virtual void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
virtual void DrawThermalModel(CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,
|
||||
TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) = 0;
|
||||
virtual void DrawModelDisintegrate(const CModel& model, const CTexture& tex, const zeus::CColor& color,
|
||||
TConstVectorRef positions, TConstVectorRef normals) = 0;
|
||||
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) = 0;
|
||||
virtual void DrawModelDisintegrate(CModel& model, CTexture& tex, const zeus::CColor& color, TConstVectorRef positions,
|
||||
TConstVectorRef normals, float t) = 0;
|
||||
virtual void DrawModelFlat(CModel& model, const CModelFlags& flags, bool unsortedOnly, TConstVectorRef positions,
|
||||
TConstVectorRef normals) = 0;
|
||||
virtual void SetWireframeFlags(s32 flags) = 0;
|
||||
virtual void SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) = 0;
|
||||
virtual void RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const TLockedToken<CModel>* model,
|
||||
|
||||
Reference in New Issue
Block a user