mirror of https://github.com/AxioDL/metaforce.git
More CCubeMaterial, more CGraphics, more aurora::gx
This commit is contained in:
parent
7a61b6cf30
commit
cd86dbd6ee
|
@ -472,13 +472,12 @@ void CActorLights::ActivateLights() const {
|
||||||
if (lights.empty()) {
|
if (lights.empty()) {
|
||||||
CGraphics::DisableAllLights();
|
CGraphics::DisableAllLights();
|
||||||
} else {
|
} else {
|
||||||
for (int idx = 0; const auto& item : lights) {
|
for (ERglLight idx = 0; const auto& item : lights) {
|
||||||
CGraphics::LoadLight(static_cast<ERglLight>(idx), item);
|
CGraphics::LoadLight(idx, item);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
// Sets n LSB to 1
|
// Sets n LSB to 1
|
||||||
auto bits = static_cast<u8>((1 << lights.size()) + 255);
|
CGraphics::SetLightState(static_cast<ERglLight>((1 << lights.size()) + 255));
|
||||||
CGraphics::SetLightState(static_cast<ERglLightBits>(bits));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x298_31_disableWorldLights) {
|
if (x298_31_disableWorldLights) {
|
||||||
|
|
|
@ -76,17 +76,17 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
||||||
|
|
||||||
u32 finalKColorCount = 0;
|
u32 finalKColorCount = 0;
|
||||||
if (matFlags & CCubeMaterialFlagBits::fKonstValues) {
|
if (matFlags & CCubeMaterialFlagBits::fKonstValues) {
|
||||||
u32 konstCount = *reinterpret_cast<const u32*>(materialDataCur);
|
u32 konstCount = SBig(*reinterpret_cast<const u32*>(materialDataCur));
|
||||||
finalKColorCount = konstCount;
|
finalKColorCount = konstCount;
|
||||||
materialDataCur += 4;
|
materialDataCur += 4;
|
||||||
for (u32 i = 0; i < konstCount; ++i) {
|
for (u32 i = 0; i < konstCount; ++i) {
|
||||||
u32 kColor = *reinterpret_cast<const u32*>(materialDataCur);
|
u32 kColor = SBig(*reinterpret_cast<const u32*>(materialDataCur));
|
||||||
materialDataCur += 4;
|
materialDataCur += 4;
|
||||||
// TODO set KColor
|
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(i), kColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 blendFactors = *reinterpret_cast<const u32*>(materialDataCur);
|
u32 blendFactors = SBig(*reinterpret_cast<const u32*>(materialDataCur));
|
||||||
materialDataCur += 4;
|
materialDataCur += 4;
|
||||||
if (g_Renderer->IsInAreaDraw()) {
|
if (g_Renderer->IsInAreaDraw()) {
|
||||||
// TODO blackout fog, additive blend
|
// TODO blackout fog, additive blend
|
||||||
|
@ -128,25 +128,27 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
||||||
finalTevCount = firstTev + 1;
|
finalTevCount = firstTev + 1;
|
||||||
u32 ccFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
u32 ccFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
||||||
finalCCFlags = ccFlags;
|
finalCCFlags = ccFlags;
|
||||||
u32 outputReg = ccFlags >> 9 & 0x3;
|
auto outputReg = static_cast<GX::TevRegID>(ccFlags >> 9 & 0x3);
|
||||||
if (outputReg == 1) { // TevReg0
|
if (outputReg == GX::TEVREG0) {
|
||||||
materialDataCur += 20;
|
materialDataCur += 20;
|
||||||
texMapTexCoordFlags += 1;
|
texMapTexCoordFlags += 1;
|
||||||
finalCCFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
finalCCFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
||||||
// Set TevReg0 = 0xc0c0c0c0
|
aurora::gfx::set_tev_reg_color(GX::TEVREG0, 0xc0c0c0c0);
|
||||||
}
|
}
|
||||||
finalACFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 12));
|
finalACFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 12));
|
||||||
HandleTev(firstTev, materialDataCur, texMapTexCoordFlags, CCubeModel::sRenderModelShadow);
|
HandleTev(firstTev, reinterpret_cast<const u32*>(materialDataCur), texMapTexCoordFlags,
|
||||||
|
CCubeModel::sRenderModelShadow);
|
||||||
usesTevReg2 = false;
|
usesTevReg2 = false;
|
||||||
} else {
|
} else {
|
||||||
finalTevCount = firstTev + matTevCount;
|
finalTevCount = firstTev + matTevCount;
|
||||||
for (u32 i = firstTev; i < finalTevCount; ++i) {
|
for (u32 i = firstTev; i < finalTevCount; ++i) {
|
||||||
HandleTev(i, materialDataCur, texMapTexCoordFlags, CCubeModel::sRenderModelShadow && i == firstTev);
|
HandleTev(i, reinterpret_cast<const u32*>(materialDataCur), texMapTexCoordFlags,
|
||||||
|
CCubeModel::sRenderModelShadow && i == firstTev);
|
||||||
u32 ccFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
u32 ccFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 8));
|
||||||
finalCCFlags = ccFlags;
|
finalCCFlags = ccFlags;
|
||||||
finalACFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 12));
|
finalACFlags = SBig(*reinterpret_cast<const u32*>(materialDataCur + 12));
|
||||||
u32 outputReg = ccFlags >> 9 & 0x3;
|
auto outputReg = static_cast<GX::TevRegID>(ccFlags >> 9 & 0x3);
|
||||||
if (outputReg == 3) { // TevReg2
|
if (outputReg == GX::TEVREG2) {
|
||||||
usesTevReg2 = true;
|
usesTevReg2 = true;
|
||||||
}
|
}
|
||||||
materialDataCur += 20;
|
materialDataCur += 20;
|
||||||
|
@ -310,10 +312,34 @@ u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) {
|
||||||
return chanCount;
|
return chanCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCubeMaterial::HandleTev(u32 tevCur, const u8* materialDataCur, const u32* texMapTexCoordFlags,
|
void CCubeMaterial::HandleTev(u32 tevCur, const u32* materialDataCur, const u32* texMapTexCoordFlags,
|
||||||
bool shadowMapsEnabled) {
|
bool shadowMapsEnabled) {
|
||||||
u32 colorArgs = shadowMapsEnabled ? 0x7a04f : SBig(*materialDataCur);
|
const u32 colorArgs = shadowMapsEnabled ? 0x7a04f : SBig(materialDataCur[0]);
|
||||||
// CGX::SetStandardDirectTev_Compressed
|
const u32 alphaArgs = SBig(materialDataCur[1]);
|
||||||
|
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);
|
||||||
|
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CCubeMaterial::HandleAnimatedUV(const u32* uvAnim, u32 texMtx, u32 pttTexMtx) {
|
u32 CCubeMaterial::HandleAnimatedUV(const u32* uvAnim, u32 texMtx, u32 pttTexMtx) {
|
||||||
|
@ -409,17 +435,27 @@ u32 CCubeMaterial::HandleReflection(bool usesTevReg2, u32 indTexSlot, u32 r5, u3
|
||||||
} else {
|
} else {
|
||||||
// GX_CC_KONST
|
// GX_CC_KONST
|
||||||
}
|
}
|
||||||
// set reflection kcolor
|
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));
|
||||||
|
|
||||||
|
const auto stage = static_cast<GX::TevStageID>(finalTevCount + out);
|
||||||
// tex = g_Renderer->GetRealReflection
|
// tex = g_Renderer->GetRealReflection
|
||||||
// tex.Load(texCount, 0)
|
// tex.Load(texCount, 0)
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
finalACFlags = 0;
|
finalACFlags = 0;
|
||||||
finalCCFlags = 0;
|
finalCCFlags = 0;
|
||||||
|
|
||||||
|
// aurora::gfx::set_tev_order(stage, ...)
|
||||||
|
|
||||||
return out + 1;
|
return out + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCubeMaterial::DoPassthru(u32 finalTevCount) {
|
void CCubeMaterial::DoPassthru(u32 finalTevCount) {
|
||||||
// TODO
|
aurora::gfx::disable_tev_stage(static_cast<ERglTevStage>(finalTevCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) {
|
void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) {
|
||||||
|
|
|
@ -96,7 +96,7 @@ private:
|
||||||
static void SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest);
|
static void SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest);
|
||||||
static void HandleDepth(CModelFlagsFlags modelFlags, CCubeMaterialFlags matFlags);
|
static void HandleDepth(CModelFlagsFlags modelFlags, CCubeMaterialFlags matFlags);
|
||||||
static u32 HandleColorChannels(u32 chanCount, u32 firstChan);
|
static u32 HandleColorChannels(u32 chanCount, u32 firstChan);
|
||||||
static void HandleTev(u32 tevCur, const u8* materialDataCur, const u32* texMapTexCoordFlags, bool shadowMapsEnabled);
|
static void HandleTev(u32 tevCur, const u32* materialDataCur, const u32* texMapTexCoordFlags, bool shadowMapsEnabled);
|
||||||
static u32 HandleAnimatedUV(const u32* uvAnim, u32 texMtx, u32 pttTexMtx);
|
static u32 HandleAnimatedUV(const u32* uvAnim, u32 texMtx, u32 pttTexMtx);
|
||||||
static void HandleTransparency(u32& finalTevCount, u32& finalKColorCount, const CModelFlags& modelFlags,
|
static void HandleTransparency(u32& finalTevCount, u32& finalKColorCount, const CModelFlags& modelFlags,
|
||||||
u32 blendFactors, u32& finalCCFlags, u32& finalACFlags);
|
u32 blendFactors, u32& finalCCFlags, u32& finalACFlags);
|
||||||
|
|
|
@ -472,14 +472,11 @@ void CCubeRenderer::DoThermalBlendHot() {}
|
||||||
u32 CCubeRenderer::GetStaticWorldDataSize() { return 0; }
|
u32 CCubeRenderer::GetStaticWorldDataSize() { return 0; }
|
||||||
|
|
||||||
void CCubeRenderer::SetGXRegister1Color(const zeus::CColor& color) {
|
void CCubeRenderer::SetGXRegister1Color(const zeus::CColor& color) {
|
||||||
CGraphics::g_ColorRegs[1] = color;
|
aurora::gfx::set_tev_reg_color(GX::TevRegID::TEVREG1, color);
|
||||||
aurora::gfx::set_gx_reg1_color(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCubeRenderer::SetWorldLightFadeLevel(float level) { x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f); }
|
void CCubeRenderer::SetWorldLightFadeLevel(float level) { x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f); }
|
||||||
|
|
||||||
void CCubeRenderer::SetWorldLightMultiplyColor(const zeus::CColor& color) { CGraphics::g_ColorRegs[2] = color; }
|
|
||||||
|
|
||||||
void CCubeRenderer::PrepareDynamicLights(const std::vector<CLight>& lights) {}
|
void CCubeRenderer::PrepareDynamicLights(const std::vector<CLight>& lights) {}
|
||||||
void CCubeRenderer::AllocatePhazonSuitMaskTexture() {}
|
void CCubeRenderer::AllocatePhazonSuitMaskTexture() {}
|
||||||
void CCubeRenderer::DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod,
|
void CCubeRenderer::DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod,
|
||||||
|
@ -511,4 +508,13 @@ void CCubeRenderer::SetupCGraphicsState() {
|
||||||
// CGX::SetChanCtrl(EChannelId::Channel1, false, GX::SRC_REG, GX::LIGHT_NULL, GX::DF_NONE, GX::AF_NONE);
|
// CGX::SetChanCtrl(EChannelId::Channel1, false, GX::SRC_REG, GX::LIGHT_NULL, GX::DF_NONE, GX::AF_NONE);
|
||||||
CCubeMaterial::EnsureTevsDirect();
|
CCubeMaterial::EnsureTevsDirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCubeRenderer::SetupRendererStates(bool depthWrite) {
|
||||||
|
CGraphics::DisableAllLights();
|
||||||
|
CGraphics::SetModelMatrix({});
|
||||||
|
CGraphics::SetAmbientColor(zeus::skBlack);
|
||||||
|
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, depthWrite);
|
||||||
|
CCubeMaterial::ResetCachedMaterials();
|
||||||
|
aurora::gfx::set_tev_reg_color(GX::TEVREG1, x2fc_tevReg1Color);
|
||||||
|
}
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -195,10 +195,10 @@ public:
|
||||||
u32 GetStaticWorldDataSize() override;
|
u32 GetStaticWorldDataSize() override;
|
||||||
void SetGXRegister1Color(const zeus::CColor& color) override;
|
void SetGXRegister1Color(const zeus::CColor& color) override;
|
||||||
void SetWorldLightFadeLevel(float level) override;
|
void SetWorldLightFadeLevel(float level) override;
|
||||||
void SetWorldLightMultiplyColor(const zeus::CColor& color) override;
|
|
||||||
void PrepareDynamicLights(const std::vector<CLight>& lights) override;
|
void PrepareDynamicLights(const std::vector<CLight>& lights) override;
|
||||||
|
|
||||||
// Non-virtual functions
|
// Non-virtual functions
|
||||||
|
void SetupRendererStates(bool depthWrite);
|
||||||
void AllocatePhazonSuitMaskTexture();
|
void AllocatePhazonSuitMaskTexture();
|
||||||
void DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod, const TLockedToken<CTexture>& indTex,
|
void DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod, const TLockedToken<CTexture>& indTex,
|
||||||
const zeus::CColor& indirectMod, float blurRadius, float scale, float offX,
|
const zeus::CColor& indirectMod, float blurRadius, float scale, float offX,
|
||||||
|
@ -212,7 +212,6 @@ public:
|
||||||
void RenderBucketItems(const CAreaListItem* lights);
|
void RenderBucketItems(const CAreaListItem* lights);
|
||||||
void DrawRenderBucketsDebug() {}
|
void DrawRenderBucketsDebug() {}
|
||||||
|
|
||||||
void SetupRendererStates(bool b) {}
|
|
||||||
// Getters
|
// Getters
|
||||||
[[nodiscard]] bool IsInAreaDraw() const { return x318_30_inAreaDraw; }
|
[[nodiscard]] bool IsInAreaDraw() const { return x318_30_inAreaDraw; }
|
||||||
[[nodiscard]] bool IsReflectionDirty() const { return x318_24_refectionDirty; }
|
[[nodiscard]] bool IsReflectionDirty() const { return x318_24_refectionDirty; }
|
||||||
|
|
|
@ -12,15 +12,12 @@
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
CGraphics::CProjectionState CGraphics::g_Proj;
|
CGraphics::CProjectionState CGraphics::g_Proj;
|
||||||
CFogState CGraphics::g_Fog;
|
CFogState CGraphics::g_Fog;
|
||||||
std::array<zeus::CColor, 3> CGraphics::g_ColorRegs{};
|
|
||||||
float CGraphics::g_ProjAspect = 1.f;
|
float CGraphics::g_ProjAspect = 1.f;
|
||||||
u32 CGraphics::g_NumLightsActive = 0;
|
|
||||||
u32 CGraphics::g_NumBreakpointsWaiting = 0;
|
u32 CGraphics::g_NumBreakpointsWaiting = 0;
|
||||||
u32 CGraphics::g_FlippingState;
|
u32 CGraphics::g_FlippingState;
|
||||||
bool CGraphics::g_LastFrameUsedAbove = false;
|
bool CGraphics::g_LastFrameUsedAbove = false;
|
||||||
bool CGraphics::g_InterruptLastFrameUsedAbove = false;
|
bool CGraphics::g_InterruptLastFrameUsedAbove = false;
|
||||||
ERglLightBits CGraphics::g_LightActive = ERglLightBits::None;
|
std::bitset<aurora::gfx::MaxLights> CGraphics::g_LightActive{};
|
||||||
ERglLightBits CGraphics::g_LightsWereOn = ERglLightBits::None;
|
|
||||||
zeus::CTransform CGraphics::g_GXModelView;
|
zeus::CTransform CGraphics::g_GXModelView;
|
||||||
zeus::CTransform CGraphics::g_GXModelViewInvXpose;
|
zeus::CTransform CGraphics::g_GXModelViewInvXpose;
|
||||||
zeus::CTransform CGraphics::g_GXModelMatrix = zeus::CTransform();
|
zeus::CTransform CGraphics::g_GXModelMatrix = zeus::CTransform();
|
||||||
|
@ -60,33 +57,52 @@ const std::array<zeus::CMatrix3f, 6> CGraphics::skCubeBasisMats{{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
void CGraphics::DisableAllLights() {
|
void CGraphics::DisableAllLights() {
|
||||||
g_NumLightsActive = 0;
|
g_LightActive.reset();
|
||||||
g_LightActive = ERglLightBits::None;
|
aurora::gfx::set_light_state(g_LightActive);
|
||||||
// TODO: turn lights off for real
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::LoadLight(ERglLight light, const CLight& info) {
|
void CGraphics::LoadLight(ERglLight light, const CLight& info) {
|
||||||
// TODO: load light for real
|
const auto lightId = static_cast<GX::LightID>(1 << light);
|
||||||
|
switch (info.GetType()) {
|
||||||
|
case ELightType::LocalAmbient:
|
||||||
|
aurora::gfx::load_light_ambient(lightId, info.GetColor());
|
||||||
|
break;
|
||||||
|
case ELightType::Point:
|
||||||
|
case ELightType::Spot:
|
||||||
|
case ELightType::Custom:
|
||||||
|
case ELightType::Directional: {
|
||||||
|
aurora::gfx::Light lightOut{
|
||||||
|
.pos = CGraphics::g_CameraMatrix * info.GetPosition(),
|
||||||
|
.dir = (CGraphics::g_CameraMatrix.basis * info.GetDirection()).normalized(),
|
||||||
|
.color = info.GetColor(),
|
||||||
|
.linAtt = {info.GetAttenuationConstant(), info.GetAttenuationLinear(), info.GetAttenuationQuadratic()},
|
||||||
|
.angAtt = {info.GetAngleAttenuationConstant(), info.GetAngleAttenuationLinear(),
|
||||||
|
info.GetAngleAttenuationQuadratic()},
|
||||||
|
};
|
||||||
|
if (info.GetType() == ELightType::Directional) {
|
||||||
|
lightOut.pos = (-lightOut.dir) * 1048576.f;
|
||||||
|
}
|
||||||
|
aurora::gfx::load_light(lightId, lightOut);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::EnableLight(ERglLight light) {
|
void CGraphics::EnableLight(ERglLight light) {
|
||||||
ERglLightBits lightBit = ERglLightBits(1 << int(light));
|
if (!g_LightActive.test(light)) {
|
||||||
if ((lightBit & g_LightActive) == ERglLightBits::None) {
|
g_LightActive.set(light);
|
||||||
g_LightActive |= lightBit;
|
aurora::gfx::set_light_state(g_LightActive);
|
||||||
++g_NumLightsActive;
|
|
||||||
// TODO: turn light on for real
|
|
||||||
}
|
}
|
||||||
g_LightsWereOn = g_LightActive;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::SetLightState(ERglLightBits lightState) {
|
void CGraphics::SetLightState(std::bitset<aurora::gfx::MaxLights> lightState) {
|
||||||
// TODO: set state for real
|
|
||||||
g_LightActive = lightState;
|
g_LightActive = lightState;
|
||||||
g_NumLightsActive = zeus::PopCount(lightState);
|
aurora::gfx::set_light_state(g_LightActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::SetAmbientColor(const zeus::CColor& col) {
|
void CGraphics::SetAmbientColor(const zeus::CColor& col) {
|
||||||
// TODO: set for real
|
aurora::gfx::set_chan_amb_color(GX::COLOR0A0, col);
|
||||||
|
aurora::gfx::set_chan_amb_color(GX::COLOR1A1, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) {
|
void CGraphics::SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) {
|
||||||
|
@ -150,13 +166,53 @@ void CGraphics::EndScene() {
|
||||||
UpdateFPSCounter();
|
UpdateFPSCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::Render2D(const CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col) {
|
void CGraphics::Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col) {
|
||||||
const auto oldProj = g_Proj;
|
const auto oldProj = g_Proj;
|
||||||
CGraphics::SetOrtho(-g_Viewport.x8_width / 2, g_Viewport.x8_width / 2, g_Viewport.xc_height / 2,
|
const auto oldCull = g_cullMode;
|
||||||
-g_Viewport.xc_height / 2, -1.f, -10.f);
|
const auto oldLights = g_LightActive;
|
||||||
// TODO
|
SetOrtho(-g_Viewport.x10_halfWidth, g_Viewport.x10_halfWidth, g_Viewport.x14_halfHeight, -g_Viewport.x14_halfHeight,
|
||||||
|
-1.f, -10.f);
|
||||||
|
// disable Y/Z swap TODO do we need to do this elsewhere?
|
||||||
|
aurora::gfx::update_model_view(zeus::CMatrix4f{}, zeus::CMatrix4f{});
|
||||||
|
DisableAllLights();
|
||||||
|
SetCullMode(ERglCullMode::None);
|
||||||
|
tex.Load(GX::TEXMAP0, EClampMode::Repeat);
|
||||||
|
|
||||||
|
// float hPad, vPad;
|
||||||
|
// if (CGraphics::GetViewportAspect() >= 1.78f) {
|
||||||
|
// hPad = 1.78f / CGraphics::GetViewportAspect();
|
||||||
|
// vPad = 1.78f / 1.33f;
|
||||||
|
// } else {
|
||||||
|
// hPad = 1.f;
|
||||||
|
// vPad = CGraphics::GetViewportAspect() / 1.33f;
|
||||||
|
// }
|
||||||
|
// TODO make this right
|
||||||
|
float scaledX = static_cast<float>(x) / 640.f * static_cast<float>(g_Viewport.x8_width);
|
||||||
|
float scaledY = static_cast<float>(y) / 448.f * static_cast<float>(g_Viewport.xc_height);
|
||||||
|
float scaledW = static_cast<float>(w) / 640.f * static_cast<float>(g_Viewport.x8_width);
|
||||||
|
float scaledH = static_cast<float>(h) / 448.f * static_cast<float>(g_Viewport.xc_height);
|
||||||
|
|
||||||
|
float x1 = scaledX - g_Viewport.x10_halfWidth;
|
||||||
|
float y1 = scaledY - g_Viewport.x14_halfHeight;
|
||||||
|
float x2 = x1 + scaledW;
|
||||||
|
float y2 = y1 + scaledH;
|
||||||
|
StreamBegin(GX::TRIANGLESTRIP);
|
||||||
|
StreamColor(col);
|
||||||
|
StreamTexcoord(0.f, 0.f);
|
||||||
|
StreamVertex(x1, y1, 1.f);
|
||||||
|
StreamTexcoord(1.f, 0.f);
|
||||||
|
StreamVertex(x2, y1, 1.f);
|
||||||
|
StreamTexcoord(0.f, 1.f);
|
||||||
|
StreamVertex(x1, y2, 1.f);
|
||||||
|
StreamTexcoord(1.f, 1.f);
|
||||||
|
StreamVertex(x2, y2, 1.f);
|
||||||
|
StreamEnd();
|
||||||
|
|
||||||
|
SetLightState(g_LightActive);
|
||||||
g_Proj = oldProj;
|
g_Proj = oldProj;
|
||||||
FlushProjection();
|
FlushProjection();
|
||||||
|
SetModelMatrix({});
|
||||||
|
SetCullMode(oldCull);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGraphics::BeginRender2D(const CTexture& tex) { return false; }
|
bool CGraphics::BeginRender2D(const CTexture& tex) { return false; }
|
||||||
|
@ -249,13 +305,12 @@ zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix() {
|
||||||
float rpl = g_Proj.x8_right + g_Proj.x4_left;
|
float rpl = g_Proj.x8_right + g_Proj.x4_left;
|
||||||
float tmb = g_Proj.xc_top - g_Proj.x10_bottom;
|
float tmb = g_Proj.xc_top - g_Proj.x10_bottom;
|
||||||
float tpb = g_Proj.xc_top + g_Proj.x10_bottom;
|
float tpb = g_Proj.xc_top + g_Proj.x10_bottom;
|
||||||
float fpn = g_Proj.x18_far + g_Proj.x14_near;
|
|
||||||
float fmn = g_Proj.x18_far - g_Proj.x14_near;
|
float fmn = g_Proj.x18_far - g_Proj.x14_near;
|
||||||
// clang-format off
|
// clang-format off
|
||||||
return {
|
return {
|
||||||
2.f / rml, 0.f, 0.f, -rpl / rml,
|
2.f / rml, 0.f, 0.f, -rpl / rml,
|
||||||
0.f, 2.f / tmb, 0.f, -tpb / tmb,
|
0.f, 2.f / tmb, 0.f, -tpb / tmb,
|
||||||
0.f, 0.f, -2.f / fmn, -fpn / fmn,
|
0.f, 0.f, -1.f / fmn, -g_Proj.x14_near / fmn,
|
||||||
0.f, 0.f, 0.f, 1.f
|
0.f, 0.f, 0.f, 1.f
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
@ -25,20 +25,7 @@ extern CVar* g_disableLighting;
|
||||||
class CLight;
|
class CLight;
|
||||||
class CTimeProvider;
|
class CTimeProvider;
|
||||||
|
|
||||||
enum class ERglLight : u8 { Zero = 0, One, Two, Three, Four, Five, Six, Seven };
|
using ERglLight = u8;
|
||||||
|
|
||||||
enum class ERglLightBits : u8 {
|
|
||||||
None = 0,
|
|
||||||
Zero = 1,
|
|
||||||
One = 1 << 1,
|
|
||||||
Two = 1 << 2,
|
|
||||||
Three = 1 << 3,
|
|
||||||
Four = 1 << 4,
|
|
||||||
Five = 1 << 5,
|
|
||||||
Six = 1 << 6,
|
|
||||||
Seven = 1 << 7
|
|
||||||
};
|
|
||||||
ENABLE_BITWISE_ENUM(ERglLightBits)
|
|
||||||
|
|
||||||
struct SViewport {
|
struct SViewport {
|
||||||
u32 x0_left;
|
u32 x0_left;
|
||||||
|
@ -119,15 +106,12 @@ public:
|
||||||
static zeus::CVector2f g_CachedDepthRange;
|
static zeus::CVector2f g_CachedDepthRange;
|
||||||
static CFogState g_Fog;
|
static CFogState g_Fog;
|
||||||
static SViewport g_Viewport;
|
static SViewport g_Viewport;
|
||||||
static std::array<zeus::CColor, 3> g_ColorRegs;
|
|
||||||
static float g_ProjAspect;
|
static float g_ProjAspect;
|
||||||
static u32 g_NumLightsActive;
|
|
||||||
static u32 g_NumBreakpointsWaiting;
|
static u32 g_NumBreakpointsWaiting;
|
||||||
static u32 g_FlippingState;
|
static u32 g_FlippingState;
|
||||||
static bool g_LastFrameUsedAbove;
|
static bool g_LastFrameUsedAbove;
|
||||||
static bool g_InterruptLastFrameUsedAbove;
|
static bool g_InterruptLastFrameUsedAbove;
|
||||||
static ERglLightBits g_LightActive;
|
static std::bitset<aurora::gfx::MaxLights> g_LightActive;
|
||||||
static ERglLightBits g_LightsWereOn;
|
|
||||||
static zeus::CTransform g_GXModelView;
|
static zeus::CTransform g_GXModelView;
|
||||||
static zeus::CTransform g_GXModelViewInvXpose;
|
static zeus::CTransform g_GXModelViewInvXpose;
|
||||||
static zeus::CTransform g_GXModelMatrix;
|
static zeus::CTransform g_GXModelMatrix;
|
||||||
|
@ -147,7 +131,7 @@ public:
|
||||||
static void DisableAllLights();
|
static void DisableAllLights();
|
||||||
static void LoadLight(ERglLight light, const CLight& info);
|
static void LoadLight(ERglLight light, const CLight& info);
|
||||||
static void EnableLight(ERglLight light);
|
static void EnableLight(ERglLight light);
|
||||||
static void SetLightState(ERglLightBits lightState);
|
static void SetLightState(std::bitset<aurora::gfx::MaxLights> lightState);
|
||||||
static void SetAmbientColor(const zeus::CColor& col);
|
static void SetAmbientColor(const zeus::CColor& col);
|
||||||
static void SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color);
|
static void SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color);
|
||||||
static void SetDepthWriteMode(bool test, ERglEnum comp, bool write);
|
static void SetDepthWriteMode(bool test, ERglEnum comp, bool write);
|
||||||
|
@ -155,7 +139,7 @@ public:
|
||||||
static void SetCullMode(ERglCullMode);
|
static void SetCullMode(ERglCullMode);
|
||||||
static void BeginScene();
|
static void BeginScene();
|
||||||
static void EndScene();
|
static void EndScene();
|
||||||
static void Render2D(const CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col);
|
static void Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col);
|
||||||
static bool BeginRender2D(const CTexture& tex);
|
static bool BeginRender2D(const CTexture& tex);
|
||||||
static void DoRender2D(const CTexture& tex, s32 x, s32 y, s32 w1, s32 w2, s32 w3, s32 w4, s32 w5,
|
static void DoRender2D(const CTexture& tex, s32 x, s32 y, s32 w1, s32 w2, s32 w3, s32 w4, s32 w5,
|
||||||
const zeus::CColor& col);
|
const zeus::CColor& col);
|
||||||
|
|
|
@ -227,7 +227,7 @@ bool CModel::IsLoaded(u32 matIdx) {
|
||||||
VerifyCurrentShader(matIdx);
|
VerifyCurrentShader(matIdx);
|
||||||
const auto& textures = *x28_modelInst->x1c_textures;
|
const auto& textures = *x28_modelInst->x1c_textures;
|
||||||
if (textures.empty()) {
|
if (textures.empty()) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
for (const auto& token : textures) {
|
for (const auto& token : textures) {
|
||||||
if (token.IsNull() && !token.IsLoaded()) {
|
if (token.IsNull() && !token.IsLoaded()) {
|
||||||
|
|
|
@ -366,36 +366,24 @@ void CMoviePlayer::Rewind() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMoviePlayer::Draw() {
|
void CMoviePlayer::Draw() {
|
||||||
if (GetIsFullyCached()) {
|
if (xd0_drawTexSlot == UINT32_MAX || !GetIsFullyCached()) {
|
||||||
g_Renderer->SetDepthReadWrite(false, false);
|
|
||||||
g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f);
|
|
||||||
const auto vpHeight = CGraphics::GetViewportHeight();
|
|
||||||
const auto vpWidth = CGraphics::GetViewportWidth();
|
|
||||||
const auto vpTop = CGraphics::GetViewportTop();
|
|
||||||
const auto vpLeft = CGraphics::GetViewportLeft();
|
|
||||||
const auto [width, height] = GetVideoDimensions();
|
|
||||||
const auto centerX = (width - vpWidth) / 2;
|
|
||||||
const auto centerY = (height - vpHeight) / 2;
|
|
||||||
DrawFrame(vpLeft - centerX, vpLeft + vpWidth + centerX, vpTop - centerY, vpTop + vpHeight + centerY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMoviePlayer::DrawFrame(u32 left, u32 right, u32 top, u32 bottom) {
|
|
||||||
DrawFrame({static_cast<float>(left), 0.f, static_cast<float>(bottom)},
|
|
||||||
{static_cast<float>(right), 0.f, static_cast<float>(bottom)},
|
|
||||||
{static_cast<float>(left), 0.f, static_cast<float>(top)},
|
|
||||||
{static_cast<float>(right), 0.f, static_cast<float>(top)});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMoviePlayer::DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
|
||||||
const zeus::CVector3f& v4) {
|
|
||||||
if (xd0_drawTexSlot == UINT32_MAX)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
SCOPED_GRAPHICS_DEBUG_GROUP("CMoviePlayer::DrawFrame", zeus::skYellow);
|
SCOPED_GRAPHICS_DEBUG_GROUP("CMoviePlayer::DrawFrame", zeus::skYellow);
|
||||||
|
|
||||||
|
/* Correct movie aspect ratio */
|
||||||
|
float hPad, vPad;
|
||||||
|
if (CGraphics::GetViewportAspect() >= 1.78f) {
|
||||||
|
hPad = 1.78f / CGraphics::GetViewportAspect();
|
||||||
|
vPad = 1.78f / 1.33f;
|
||||||
|
} else {
|
||||||
|
hPad = 1.f;
|
||||||
|
vPad = CGraphics::GetViewportAspect() / 1.33f;
|
||||||
|
}
|
||||||
|
|
||||||
/* draw appropriate field */
|
/* draw appropriate field */
|
||||||
CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot];
|
CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot];
|
||||||
aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, v1, v2, v3, v4);
|
aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, hPad, vPad);
|
||||||
|
|
||||||
/* ensure second field is being displayed by VI to signal advance
|
/* ensure second field is being displayed by VI to signal advance
|
||||||
* (faked in metaforce with continuous xor) */
|
* (faked in metaforce with continuous xor) */
|
||||||
|
|
|
@ -110,9 +110,6 @@ private:
|
||||||
float m_vpad;
|
float m_vpad;
|
||||||
|
|
||||||
void DecodeFromRead(const void* data);
|
void DecodeFromRead(const void* data);
|
||||||
void DrawFrame(u32 left, u32 right, u32 top, u32 bottom);
|
|
||||||
void DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
|
||||||
const zeus::CVector3f& v4);
|
|
||||||
void PostDVDReadRequestIfNeeded();
|
void PostDVDReadRequestIfNeeded();
|
||||||
void ReadCompleted();
|
void ReadCompleted();
|
||||||
|
|
||||||
|
|
|
@ -457,6 +457,8 @@ enum TexMapID {
|
||||||
TEXMAP6,
|
TEXMAP6,
|
||||||
TEXMAP7,
|
TEXMAP7,
|
||||||
MAX_TEXMAP,
|
MAX_TEXMAP,
|
||||||
|
TEXMAP_NULL = 0xFF,
|
||||||
|
TEX_DISABLE = 0x100,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TevStageID {
|
enum TevStageID {
|
||||||
|
|
|
@ -108,7 +108,7 @@ public:
|
||||||
virtual u32 GetStaticWorldDataSize() = 0;
|
virtual u32 GetStaticWorldDataSize() = 0;
|
||||||
virtual void SetGXRegister1Color(const zeus::CColor& color) = 0;
|
virtual void SetGXRegister1Color(const zeus::CColor& color) = 0;
|
||||||
virtual void SetWorldLightFadeLevel(float level) = 0;
|
virtual void SetWorldLightFadeLevel(float level) = 0;
|
||||||
virtual void SetWorldLightMultiplyColor(const zeus::CColor& color) = 0;
|
// Something
|
||||||
virtual void PrepareDynamicLights(const std::vector<CLight>& lights) = 0;
|
virtual void PrepareDynamicLights(const std::vector<CLight>& lights) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,21 +44,19 @@ void CGuiFrame::SortDrawOrder() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGuiFrame::EnableLights(u32 lights) const {
|
void CGuiFrame::EnableLights(ERglLight lights) const {
|
||||||
CGraphics::DisableAllLights();
|
CGraphics::DisableAllLights();
|
||||||
|
|
||||||
zeus::CColor ambColor(zeus::skBlack);
|
zeus::CColor ambColor(zeus::skBlack);
|
||||||
ERglLight lightId = ERglLight::Zero;
|
ERglLight lightId = 0;
|
||||||
int idx = 0;
|
|
||||||
int enabledLights = 0;
|
int enabledLights = 0;
|
||||||
for (CGuiLight* light : m_indexedLights) {
|
for (CGuiLight* light : m_indexedLights) {
|
||||||
if (light == nullptr || !light->GetIsVisible()) {
|
if (light == nullptr || !light->GetIsVisible()) {
|
||||||
++reinterpret_cast<std::underlying_type_t<ERglLight>&>(lightId);
|
++lightId;
|
||||||
++idx;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((lights & (1 << idx)) != 0) {
|
if ((lights & (1 << lightId)) != 0) {
|
||||||
const zeus::CColor& geomCol = light->GetGeometryColor();
|
const auto& geomCol = light->GetGeometryColor();
|
||||||
if (geomCol.r() != 0.f || geomCol.g() != 0.f || geomCol.b() != 0.f) {
|
if (geomCol.r() != 0.f || geomCol.g() != 0.f || geomCol.b() != 0.f) {
|
||||||
CGraphics::LoadLight(lightId, light->BuildLight());
|
CGraphics::LoadLight(lightId, light->BuildLight());
|
||||||
CGraphics::EnableLight(lightId);
|
CGraphics::EnableLight(lightId);
|
||||||
|
@ -67,8 +65,7 @@ void CGuiFrame::EnableLights(u32 lights) const {
|
||||||
ambColor += light->GetAmbientLightColor();
|
ambColor += light->GetAmbientLightColor();
|
||||||
++enabledLights;
|
++enabledLights;
|
||||||
}
|
}
|
||||||
++reinterpret_cast<std::underlying_type_t<ERglLight>&>(lightId);
|
++lightId;
|
||||||
++idx;
|
|
||||||
}
|
}
|
||||||
if (enabledLights == 0) {
|
if (enabledLights == 0) {
|
||||||
CGraphics::SetAmbientColor(zeus::skWhite);
|
CGraphics::SetAmbientColor(zeus::skWhite);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Runtime/GuiSys/CGuiHeadWidget.hpp"
|
#include "Runtime/GuiSys/CGuiHeadWidget.hpp"
|
||||||
#include "Runtime/GuiSys/CGuiWidgetIdDB.hpp"
|
#include "Runtime/GuiSys/CGuiWidgetIdDB.hpp"
|
||||||
#include "Runtime/GuiSys/CGuiWidget.hpp"
|
#include "Runtime/GuiSys/CGuiWidget.hpp"
|
||||||
|
#include "Runtime/Graphics/CGraphics.hpp"
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
class CGuiCamera;
|
class CGuiCamera;
|
||||||
|
@ -69,7 +70,7 @@ public:
|
||||||
void SetHeadWidget(std::shared_ptr<CGuiHeadWidget>&& hwig) { xc_headWidget = std::move(hwig); }
|
void SetHeadWidget(std::shared_ptr<CGuiHeadWidget>&& hwig) { xc_headWidget = std::move(hwig); }
|
||||||
CGuiHeadWidget* GetHeadWidget() const { return xc_headWidget.get(); }
|
CGuiHeadWidget* GetHeadWidget() const { return xc_headWidget.get(); }
|
||||||
void SortDrawOrder();
|
void SortDrawOrder();
|
||||||
void EnableLights(u32 lights) const;
|
void EnableLights(ERglLight lights) const;
|
||||||
void DisableLights() const;
|
void DisableLights() const;
|
||||||
void RemoveLight(CGuiLight* light);
|
void RemoveLight(CGuiLight* light);
|
||||||
void AddLight(CGuiLight* light);
|
void AddLight(CGuiLight* light);
|
||||||
|
|
|
@ -113,8 +113,7 @@ void CFrontEndUI::PlayAdvanceSfx() {
|
||||||
CSfxManager::SfxStart(SFXfnt_advance_R, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
CSfxManager::SfxStart(SFXfnt_advance_R, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFrontEndUI::SNewFileSelectFrame::SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd)
|
CFrontEndUI::SNewFileSelectFrame::SNewFileSelectFrame(CSaveGameScreen* sui, u32 rnd) : x0_rnd(rnd), x4_saveUI(sui) {
|
||||||
: x0_rnd(rnd), x4_saveUI(sui) {
|
|
||||||
x10_frme = g_SimplePool->GetObj("FRME_NewFileSelect");
|
x10_frme = g_SimplePool->GetObj("FRME_NewFileSelect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,8 +217,7 @@ void CFrontEndUI::SNewFileSelectFrame::Update(float dt) {
|
||||||
x1c_loadedFrame->Update(dt);
|
x1c_loadedFrame->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFrontEndUI::SNewFileSelectFrame::EAction
|
CFrontEndUI::SNewFileSelectFrame::EAction CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input) {
|
||||||
CFrontEndUI::SNewFileSelectFrame::ProcessUserInput(const CFinalInput& input) {
|
|
||||||
xc_action = EAction::None;
|
xc_action = EAction::None;
|
||||||
|
|
||||||
if (x8_subMenu != ESubMenu::EraseGamePopup)
|
if (x8_subMenu != ESubMenu::EraseGamePopup)
|
||||||
|
@ -962,8 +960,8 @@ void CFrontEndUI::SFusionBonusFrame::Update(float dt, CSaveGameScreen* saveUI) {
|
||||||
x30_textpane_instructions.SetPairText(instructionStr);
|
x30_textpane_instructions.SetPairText(instructionStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFrontEndUI::SFusionBonusFrame::EAction
|
CFrontEndUI::SFusionBonusFrame::EAction CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input,
|
||||||
CFrontEndUI::SFusionBonusFrame::ProcessUserInput(const CFinalInput& input, CSaveGameScreen* sui) {
|
CSaveGameScreen* sui) {
|
||||||
x8_action = EAction::None;
|
x8_action = EAction::None;
|
||||||
|
|
||||||
if (sui)
|
if (sui)
|
||||||
|
@ -1149,8 +1147,7 @@ void CFrontEndUI::SFrontEndFrame::Update(float dt) {
|
||||||
x14_loadedFrme->Update(dt);
|
x14_loadedFrme->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFrontEndUI::SFrontEndFrame::EAction
|
CFrontEndUI::SFrontEndFrame::EAction CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input) {
|
||||||
CFrontEndUI::SFrontEndFrame::ProcessUserInput(const CFinalInput& input) {
|
|
||||||
x4_action = EAction::None;
|
x4_action = EAction::None;
|
||||||
x14_loadedFrme->ProcessUserInput(input);
|
x14_loadedFrme->ProcessUserInput(input);
|
||||||
return x4_action;
|
return x4_action;
|
||||||
|
@ -1193,8 +1190,7 @@ void CFrontEndUI::SFrontEndFrame::DoAdvance(CGuiTableGroup* caller) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd)
|
CFrontEndUI::SFrontEndFrame::SFrontEndFrame(u32 rnd) : x0_rnd(rnd) {
|
||||||
: x0_rnd(rnd) {
|
|
||||||
x8_frme = g_SimplePool->GetObj("FRME_FrontEndPL");
|
x8_frme = g_SimplePool->GetObj("FRME_FrontEndPL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1827,15 +1823,14 @@ void CFrontEndUI::Draw() {
|
||||||
|
|
||||||
if (x64_pressStartAlpha > 0.f && x38_pressStart.IsLoaded()) {
|
if (x64_pressStartAlpha > 0.f && x38_pressStart.IsLoaded()) {
|
||||||
/* Render "Press Start" */
|
/* Render "Press Start" */
|
||||||
// TODO fixme
|
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc);
|
||||||
// const zeus::CRectangle rect(0.5f - x38_pressStart->GetWidth() / 2.f / 640.f * hPad,
|
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru);
|
||||||
// 0.5f + (x38_pressStart->GetHeight() / 2.f - 240.f + 72.f) / 480.f * vPad,
|
g_Renderer->SetBlendMode_AdditiveAlpha();
|
||||||
// x38_pressStart->GetWidth() / 640.f * hPad,
|
g_Renderer->SetDepthReadWrite(false, false);
|
||||||
// x38_pressStart->GetHeight() / 480.f * vPad);
|
const auto width = x38_pressStart->GetWidth();
|
||||||
// zeus::CColor color = zeus::skWhite;
|
const auto height = x38_pressStart->GetHeight();
|
||||||
// color.a() = x64_pressStartAlpha;
|
CGraphics::Render2D(*x38_pressStart, 320 - width / 2, 72 - height / 2, width, height,
|
||||||
// aurora::gfx::queue_textured_quad(aurora::gfx::CameraFilterType::Add, x38_pressStart->GetTexture(),
|
zeus::CColor{1.f, x64_pressStartAlpha});
|
||||||
// aurora::gfx::ZComp::Always, false, color, 1.f, rect, 0.f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xc0_attractCount > 0) {
|
if (xc0_attractCount > 0) {
|
||||||
|
|
|
@ -100,7 +100,7 @@ private:
|
||||||
bool x26d_27_enableOPTS : 1;
|
bool x26d_27_enableOPTS : 1;
|
||||||
bool x26d_28_enableADV : 1 = false;
|
bool x26d_28_enableADV : 1 = false;
|
||||||
int x270_MBSP = 0;
|
int x270_MBSP = 0;
|
||||||
ERglLightBits x274_backupLightActive = ERglLightBits::None;
|
std::bitset<aurora::gfx::MaxLights> x274_backupLightActive{};
|
||||||
std::array<bool, 4> x278_hasVMD{};
|
std::array<bool, 4> x278_hasVMD{};
|
||||||
CRandom16 x27c_randState;
|
CRandom16 x27c_randState;
|
||||||
std::array<CModVectorElement*, 4> x280_VELSources{};
|
std::array<CModVectorElement*, 4> x280_VELSources{};
|
||||||
|
|
|
@ -25,6 +25,7 @@ add_library(aurora STATIC
|
||||||
lib/gfx/common.cpp
|
lib/gfx/common.cpp
|
||||||
lib/gfx/texture.cpp
|
lib/gfx/texture.cpp
|
||||||
lib/gfx/stream.cpp
|
lib/gfx/stream.cpp
|
||||||
|
lib/gfx/gx.cpp
|
||||||
lib/gfx/texture_convert.cpp
|
lib/gfx/texture_convert.cpp
|
||||||
lib/gfx/movie_player/shader.cpp
|
lib/gfx/movie_player/shader.cpp
|
||||||
lib/gfx/textured_quad/shader.cpp
|
lib/gfx/textured_quad/shader.cpp
|
||||||
|
|
|
@ -151,6 +151,16 @@ struct CTevOp {
|
||||||
GX::TevScale xc_scale = GX::TevScale::CS_SCALE_1;
|
GX::TevScale xc_scale = GX::TevScale::CS_SCALE_1;
|
||||||
GX::TevRegID x10_regId = GX::TevRegID::TEVPREV;
|
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)) {}
|
||||||
|
|
||||||
bool operator<=>(const CTevOp&) const = default;
|
bool operator<=>(const CTevOp&) const = default;
|
||||||
};
|
};
|
||||||
struct ColorPass {
|
struct ColorPass {
|
||||||
|
@ -159,6 +169,14 @@ struct ColorPass {
|
||||||
GX::TevColorArg x8_c;
|
GX::TevColorArg x8_c;
|
||||||
GX::TevColorArg xc_d;
|
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)) {}
|
||||||
|
|
||||||
bool operator<=>(const ColorPass&) const = default;
|
bool operator<=>(const ColorPass&) const = default;
|
||||||
};
|
};
|
||||||
struct AlphaPass {
|
struct AlphaPass {
|
||||||
|
@ -167,6 +185,14 @@ struct AlphaPass {
|
||||||
GX::TevAlphaArg x8_c;
|
GX::TevAlphaArg x8_c;
|
||||||
GX::TevAlphaArg xc_d;
|
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)) {}
|
||||||
|
|
||||||
bool operator<=>(const AlphaPass&) const = default;
|
bool operator<=>(const AlphaPass&) const = default;
|
||||||
};
|
};
|
||||||
} // namespace CTevCombiners
|
} // namespace CTevCombiners
|
||||||
|
@ -220,8 +246,23 @@ enum class ZComp : uint8_t {
|
||||||
Always,
|
Always,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr u32 MaxLights = 8;
|
||||||
|
struct Light {
|
||||||
|
zeus::CVector3f pos;
|
||||||
|
zeus::CVector3f dir;
|
||||||
|
zeus::CColor color;
|
||||||
|
zeus::CVector3f linAtt{1.f, 0.f, 0.f};
|
||||||
|
zeus::CVector3f angAtt{1.f, 0.f, 0.f};
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] bool get_dxt_compression_supported() noexcept;
|
[[nodiscard]] bool get_dxt_compression_supported() noexcept;
|
||||||
|
|
||||||
|
void stream_begin(GX::Primitive primitive) noexcept;
|
||||||
|
void stream_vertex(metaforce::EStreamFlags flags, const zeus::CVector3f& pos, const zeus::CVector3f& nrm,
|
||||||
|
const zeus::CColor& color, const zeus::CVector2f& uv) noexcept;
|
||||||
|
void stream_end() noexcept;
|
||||||
|
|
||||||
|
// GX state
|
||||||
void bind_texture(GX::TexMapID id, metaforce::EClampMode clamp, const TextureHandle& tex, float lod) noexcept;
|
void bind_texture(GX::TexMapID id, metaforce::EClampMode clamp, const TextureHandle& tex, float lod) noexcept;
|
||||||
void unbind_texture(GX::TexMapID id) noexcept;
|
void unbind_texture(GX::TexMapID id) noexcept;
|
||||||
void disable_tev_stage(metaforce::ERglTevStage stage) noexcept;
|
void disable_tev_stage(metaforce::ERglTevStage stage) noexcept;
|
||||||
|
@ -229,20 +270,20 @@ void update_tev_stage(metaforce::ERglTevStage stage, const metaforce::CTevCombin
|
||||||
const metaforce::CTevCombiners::AlphaPass& alphaPass,
|
const metaforce::CTevCombiners::AlphaPass& alphaPass,
|
||||||
const metaforce::CTevCombiners::CTevOp& colorOp,
|
const metaforce::CTevCombiners::CTevOp& colorOp,
|
||||||
const metaforce::CTevCombiners::CTevOp& alphaOp) noexcept;
|
const metaforce::CTevCombiners::CTevOp& alphaOp) noexcept;
|
||||||
void stream_begin(GX::Primitive primitive) noexcept;
|
|
||||||
void stream_vertex(metaforce::EStreamFlags flags, const zeus::CVector3f& pos, const zeus::CVector3f& nrm,
|
|
||||||
const zeus::CColor& color, const zeus::CVector2f& uv) noexcept;
|
|
||||||
void stream_end() noexcept;
|
|
||||||
|
|
||||||
// GX state
|
|
||||||
void set_cull_mode(metaforce::ERglCullMode mode) noexcept;
|
void set_cull_mode(metaforce::ERglCullMode mode) noexcept;
|
||||||
void set_blend_mode(metaforce::ERglBlendMode mode, metaforce::ERglBlendFactor src, metaforce::ERglBlendFactor dst,
|
void set_blend_mode(metaforce::ERglBlendMode mode, metaforce::ERglBlendFactor src, metaforce::ERglBlendFactor dst,
|
||||||
metaforce::ERglLogicOp op) noexcept;
|
metaforce::ERglLogicOp op) noexcept;
|
||||||
void set_depth_mode(bool compare_enable, metaforce::ERglEnum func, bool update_enable) noexcept;
|
void set_depth_mode(bool compare_enable, metaforce::ERglEnum func, bool update_enable) noexcept;
|
||||||
void set_gx_reg1_color(const zeus::CColor& color) noexcept;
|
void set_tev_reg_color(GX::TevRegID id, const zeus::CColor& color) noexcept;
|
||||||
|
void set_tev_k_color(GX::TevKColorID id, const zeus::CColor& color) noexcept;
|
||||||
void set_alpha_update(bool enabled) noexcept;
|
void set_alpha_update(bool enabled) noexcept;
|
||||||
void set_dst_alpha(bool enabled, float value) noexcept;
|
void set_dst_alpha(bool enabled, float value) noexcept;
|
||||||
void set_clear_color(const zeus::CColor& color) noexcept;
|
void set_clear_color(const zeus::CColor& color) noexcept;
|
||||||
|
void set_tev_order(GX::TevStageID id, GX::TexCoordID tcid, GX::TexMapID tmid, GX::ChannelID cid) noexcept;
|
||||||
|
void set_tev_k_color_sel(GX::TevStageID id, GX::TevKColorSel sel) noexcept;
|
||||||
|
void set_tev_k_alpha_sel(GX::TevStageID id, GX::TevKAlphaSel sel) noexcept;
|
||||||
|
void set_chan_amb_color(GX::ChannelID id, const zeus::CColor& color) noexcept;
|
||||||
|
void set_chan_mat_color(GX::ChannelID id, const zeus::CColor& color) noexcept;
|
||||||
|
|
||||||
// Model state
|
// Model state
|
||||||
void set_alpha_discard(bool v);
|
void set_alpha_discard(bool v);
|
||||||
|
@ -250,6 +291,9 @@ void set_alpha_discard(bool v);
|
||||||
void update_model_view(const zeus::CMatrix4f& mv, const zeus::CMatrix4f& mv_inv) noexcept;
|
void update_model_view(const zeus::CMatrix4f& mv, const zeus::CMatrix4f& mv_inv) noexcept;
|
||||||
void update_projection(const zeus::CMatrix4f& proj) noexcept;
|
void update_projection(const zeus::CMatrix4f& proj) noexcept;
|
||||||
void update_fog_state(const metaforce::CFogState& state) noexcept;
|
void update_fog_state(const metaforce::CFogState& state) noexcept;
|
||||||
|
void load_light(GX::LightID id, const Light& light) noexcept;
|
||||||
|
void load_light_ambient(GX::LightID id, const zeus::CColor& ambient) noexcept;
|
||||||
|
void set_light_state(std::bitset<MaxLights> bits) noexcept;
|
||||||
void set_viewport(const zeus::CRectangle& rect, float znear, float zfar) noexcept;
|
void set_viewport(const zeus::CRectangle& rect, float znear, float zfar) noexcept;
|
||||||
void set_scissor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) noexcept;
|
void set_scissor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) noexcept;
|
||||||
|
|
||||||
|
@ -272,9 +316,8 @@ void queue_colored_quad_verts(CameraFilterType filter_type, ZComp z_comparison,
|
||||||
const ArrayRef<zeus::CVector3f>& pos) noexcept;
|
const ArrayRef<zeus::CVector3f>& pos) noexcept;
|
||||||
void queue_colored_quad(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color,
|
void queue_colored_quad(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color,
|
||||||
const zeus::CRectangle& rect, float z) noexcept;
|
const zeus::CRectangle& rect, float z) noexcept;
|
||||||
void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v,
|
void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, float h_pad,
|
||||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
float v_pad) noexcept;
|
||||||
const zeus::CVector3f& v4) noexcept;
|
|
||||||
|
|
||||||
TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mips, metaforce::ETexelFormat format,
|
TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mips, metaforce::ETexelFormat format,
|
||||||
ArrayRef<uint8_t> data, zstring_view label) noexcept;
|
ArrayRef<uint8_t> data, zstring_view label) noexcept;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace aurora::gfx::model {
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#include <aurora/aurora.hpp>
|
#include <aurora/aurora.hpp>
|
||||||
#include "gfx/common.hpp"
|
#include "gfx/common.hpp"
|
||||||
|
#include "gfx/gx.hpp"
|
||||||
#include "gpu.hpp"
|
#include "gpu.hpp"
|
||||||
#include "input.hpp"
|
#include "input.hpp"
|
||||||
#include "imgui.hpp"
|
#include "imgui.hpp"
|
||||||
|
@ -298,7 +299,13 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv)
|
||||||
// .resolveTarget = g_frameBufferResolved.view,
|
// .resolveTarget = g_frameBufferResolved.view,
|
||||||
.loadOp = wgpu::LoadOp::Clear,
|
.loadOp = wgpu::LoadOp::Clear,
|
||||||
.storeOp = wgpu::StoreOp::Store,
|
.storeOp = wgpu::StoreOp::Store,
|
||||||
.clearColor = {0.f, 0.f, 0.f, 0.f},
|
.clearColor =
|
||||||
|
{
|
||||||
|
.r = gfx::g_clearColor.r(),
|
||||||
|
.g = gfx::g_clearColor.g(),
|
||||||
|
.b = gfx::g_clearColor.b(),
|
||||||
|
.a = gfx::g_clearColor.a(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const auto depthStencilAttachment = wgpu::RenderPassDepthStencilAttachment{
|
const auto depthStencilAttachment = wgpu::RenderPassDepthStencilAttachment{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "shader.hpp"
|
#include "shader.hpp"
|
||||||
|
|
||||||
#include "../../gpu.hpp"
|
#include "../../gpu.hpp"
|
||||||
|
#include "../gx.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <logvisor/logvisor.hpp>
|
||||||
#include <magic_enum.hpp>
|
#include <magic_enum.hpp>
|
||||||
|
|
|
@ -65,24 +65,6 @@ struct Command {
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
zeus::CMatrix4f g_mv;
|
|
||||||
zeus::CMatrix4f g_mvInv;
|
|
||||||
zeus::CMatrix4f g_proj;
|
|
||||||
metaforce::CFogState g_fogState;
|
|
||||||
// GX state
|
|
||||||
metaforce::ERglCullMode g_cullMode;
|
|
||||||
metaforce::ERglBlendMode g_blendMode;
|
|
||||||
metaforce::ERglBlendFactor g_blendFacSrc;
|
|
||||||
metaforce::ERglBlendFactor g_blendFacDst;
|
|
||||||
metaforce::ERglLogicOp g_blendOp;
|
|
||||||
bool g_depthCompare;
|
|
||||||
bool g_depthUpdate;
|
|
||||||
metaforce::ERglEnum g_depthFunc;
|
|
||||||
std::array<zeus::CColor, 4> g_colorRegs;
|
|
||||||
bool g_alphaUpdate;
|
|
||||||
std::optional<float> g_dstAlpha;
|
|
||||||
zeus::CColor g_clearColor;
|
|
||||||
|
|
||||||
using NewPipelineCallback = std::function<wgpu::RenderPipeline()>;
|
using NewPipelineCallback = std::function<wgpu::RenderPipeline()>;
|
||||||
static std::mutex g_pipelineMutex;
|
static std::mutex g_pipelineMutex;
|
||||||
static std::thread g_pipelineThread;
|
static std::thread g_pipelineThread;
|
||||||
|
@ -135,48 +117,6 @@ static void push_draw_command(ShaderDrawCommand data) { g_commands.push_back({Co
|
||||||
|
|
||||||
bool get_dxt_compression_supported() noexcept { return g_device.HasFeature(wgpu::FeatureName::TextureCompressionBC); }
|
bool get_dxt_compression_supported() noexcept { return g_device.HasFeature(wgpu::FeatureName::TextureCompressionBC); }
|
||||||
|
|
||||||
// GX state
|
|
||||||
void set_cull_mode(metaforce::ERglCullMode mode) noexcept { g_cullMode = mode; }
|
|
||||||
void set_blend_mode(metaforce::ERglBlendMode mode, metaforce::ERglBlendFactor src, metaforce::ERglBlendFactor dst,
|
|
||||||
metaforce::ERglLogicOp op) noexcept {
|
|
||||||
g_blendMode = mode;
|
|
||||||
g_blendFacSrc = src;
|
|
||||||
g_blendFacDst = dst;
|
|
||||||
g_blendOp = op;
|
|
||||||
}
|
|
||||||
void set_depth_mode(bool compare_enable, metaforce::ERglEnum func, bool update_enable) noexcept {
|
|
||||||
g_depthCompare = compare_enable;
|
|
||||||
g_depthFunc = func;
|
|
||||||
g_depthUpdate = update_enable;
|
|
||||||
}
|
|
||||||
void set_gx_reg1_color(const zeus::CColor& color) noexcept { g_colorRegs[1] = color; }
|
|
||||||
void set_alpha_update(bool enabled) noexcept { g_alphaUpdate = enabled; }
|
|
||||||
void set_dst_alpha(bool enabled, float value) noexcept {
|
|
||||||
if (enabled) {
|
|
||||||
g_dstAlpha = value;
|
|
||||||
} else {
|
|
||||||
g_dstAlpha.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void set_clear_color(const zeus::CColor& color) noexcept { g_clearColor = color; }
|
|
||||||
|
|
||||||
// Model state
|
|
||||||
void set_alpha_discard(bool v) {}
|
|
||||||
|
|
||||||
void update_model_view(const zeus::CMatrix4f& mv, const zeus::CMatrix4f& mv_inv) noexcept {
|
|
||||||
g_mv = mv;
|
|
||||||
g_mvInv = mv_inv;
|
|
||||||
}
|
|
||||||
constexpr zeus::CMatrix4f DepthCorrect{
|
|
||||||
// clang-format off
|
|
||||||
1.f, 0.f, 0.f, 0.f,
|
|
||||||
0.f, 1.f, 0.f, 0.f,
|
|
||||||
0.f, 0.f, 0.5f, 0.5f,
|
|
||||||
0.f, 0.f, 0.f, 1.f,
|
|
||||||
// clang-format on
|
|
||||||
};
|
|
||||||
void update_projection(const zeus::CMatrix4f& proj) noexcept { g_proj = DepthCorrect * proj; }
|
|
||||||
void update_fog_state(const metaforce::CFogState& state) noexcept { g_fogState = state; }
|
|
||||||
void set_viewport(const zeus::CRectangle& rect, float znear, float zfar) noexcept {
|
void set_viewport(const zeus::CRectangle& rect, float znear, float zfar) noexcept {
|
||||||
g_commands.push_back({CommandType::SetViewport, {.setViewport = {rect, znear, zfar}}});
|
g_commands.push_back({CommandType::SetViewport, {.setViewport = {rect, znear, zfar}}});
|
||||||
}
|
}
|
||||||
|
@ -243,9 +183,8 @@ PipelineRef pipeline_ref(colored_quad::PipelineConfig config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v,
|
void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v,
|
||||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
float h_pad, float v_pad) noexcept {
|
||||||
const zeus::CVector3f& v4) noexcept {
|
auto data = movie_player::make_draw_data(g_state.moviePlayer, tex_y, tex_u, tex_v, h_pad, v_pad);
|
||||||
auto data = movie_player::make_draw_data(g_state.moviePlayer, tex_y, tex_u, tex_v, v1, v2, v3, v4);
|
|
||||||
push_draw_command({.type = ShaderType::MoviePlayer, .moviePlayer = data});
|
push_draw_command({.type = ShaderType::MoviePlayer, .moviePlayer = data});
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
|
|
|
@ -142,24 +142,6 @@ constexpr Mat4x4<float> Mat4x4_Identity{
|
||||||
} // namespace aurora
|
} // namespace aurora
|
||||||
|
|
||||||
namespace aurora::gfx {
|
namespace aurora::gfx {
|
||||||
extern zeus::CMatrix4f g_mv;
|
|
||||||
extern zeus::CMatrix4f g_mvInv;
|
|
||||||
extern zeus::CMatrix4f g_proj;
|
|
||||||
extern metaforce::CFogState g_fogState;
|
|
||||||
// GX state
|
|
||||||
extern metaforce::ERglCullMode g_cullMode;
|
|
||||||
extern metaforce::ERglBlendMode g_blendMode;
|
|
||||||
extern metaforce::ERglBlendFactor g_blendFacSrc;
|
|
||||||
extern metaforce::ERglBlendFactor g_blendFacDst;
|
|
||||||
extern metaforce::ERglLogicOp g_blendOp;
|
|
||||||
extern bool g_depthCompare;
|
|
||||||
extern bool g_depthUpdate;
|
|
||||||
extern metaforce::ERglEnum g_depthFunc;
|
|
||||||
extern std::array<zeus::CColor, 4> g_colorRegs;
|
|
||||||
extern bool g_alphaUpdate;
|
|
||||||
extern std::optional<float> g_dstAlpha;
|
|
||||||
extern zeus::CColor g_clearColor;
|
|
||||||
|
|
||||||
extern wgpu::Buffer g_vertexBuffer;
|
extern wgpu::Buffer g_vertexBuffer;
|
||||||
extern wgpu::Buffer g_uniformBuffer;
|
extern wgpu::Buffer g_uniformBuffer;
|
||||||
extern wgpu::Buffer g_indexBuffer;
|
extern wgpu::Buffer g_indexBuffer;
|
||||||
|
@ -232,6 +214,4 @@ const wgpu::BindGroup& find_bind_group(BindGroupRef id);
|
||||||
const wgpu::Sampler& sampler_ref(const wgpu::SamplerDescriptor& descriptor);
|
const wgpu::Sampler& sampler_ref(const wgpu::SamplerDescriptor& descriptor);
|
||||||
|
|
||||||
uint32_t align_uniform(uint32_t value);
|
uint32_t align_uniform(uint32_t value);
|
||||||
|
|
||||||
static inline Mat4x4<float> get_combined_matrix() { return g_proj * g_mv; }
|
|
||||||
} // namespace aurora::gfx
|
} // namespace aurora::gfx
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include "gx.hpp"
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
#include "../gpu.hpp"
|
||||||
|
|
||||||
|
#include <magic_enum.hpp>
|
||||||
|
|
||||||
|
namespace aurora::gfx {
|
||||||
|
static logvisor::Module Log("aurora::gfx::gx");
|
||||||
|
|
||||||
|
zeus::CMatrix4f g_mv;
|
||||||
|
zeus::CMatrix4f g_mvInv;
|
||||||
|
zeus::CMatrix4f g_proj;
|
||||||
|
metaforce::CFogState g_fogState;
|
||||||
|
metaforce::ERglCullMode g_cullMode;
|
||||||
|
metaforce::ERglBlendMode g_blendMode;
|
||||||
|
metaforce::ERglBlendFactor g_blendFacSrc;
|
||||||
|
metaforce::ERglBlendFactor g_blendFacDst;
|
||||||
|
metaforce::ERglLogicOp g_blendOp;
|
||||||
|
bool g_depthCompare;
|
||||||
|
bool g_depthUpdate;
|
||||||
|
metaforce::ERglEnum g_depthFunc;
|
||||||
|
std::array<zeus::CColor, 3> g_colorRegs;
|
||||||
|
std::array<zeus::CColor, GX::MAX_KCOLOR> g_kcolors;
|
||||||
|
bool g_alphaUpdate;
|
||||||
|
std::optional<float> g_dstAlpha;
|
||||||
|
zeus::CColor g_clearColor = zeus::skClear;
|
||||||
|
|
||||||
|
std::array<SChannelState, 2> g_colorChannels;
|
||||||
|
std::array<LightVariant, MaxLights> g_lights;
|
||||||
|
std::bitset<MaxLights> g_lightState;
|
||||||
|
|
||||||
|
std::array<std::optional<STevStage>, maxTevStages> g_tevStages;
|
||||||
|
|
||||||
|
// GX state
|
||||||
|
void set_cull_mode(metaforce::ERglCullMode mode) noexcept { g_cullMode = mode; }
|
||||||
|
void set_blend_mode(metaforce::ERglBlendMode mode, metaforce::ERglBlendFactor src, metaforce::ERglBlendFactor dst,
|
||||||
|
metaforce::ERglLogicOp op) noexcept {
|
||||||
|
g_blendMode = mode;
|
||||||
|
g_blendFacSrc = src;
|
||||||
|
g_blendFacDst = dst;
|
||||||
|
g_blendOp = op;
|
||||||
|
}
|
||||||
|
void set_depth_mode(bool compare_enable, metaforce::ERglEnum func, bool update_enable) noexcept {
|
||||||
|
g_depthCompare = compare_enable;
|
||||||
|
g_depthFunc = func;
|
||||||
|
g_depthUpdate = update_enable;
|
||||||
|
}
|
||||||
|
void set_tev_reg_color(GX::TevRegID id, const zeus::CColor& color) noexcept {
|
||||||
|
if (id < GX::TEVREG0 || id > GX::TEVREG2) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_tev_reg_color: bad reg {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
g_colorRegs[id - 1] = color;
|
||||||
|
}
|
||||||
|
void set_tev_k_color(GX::TevKColorID id, const zeus::CColor& color) noexcept {
|
||||||
|
if (id >= GX::MAX_KCOLOR) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_tev_k_color: bad reg {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
g_kcolors[id] = color;
|
||||||
|
}
|
||||||
|
void set_alpha_update(bool enabled) noexcept { g_alphaUpdate = enabled; }
|
||||||
|
void set_dst_alpha(bool enabled, float value) noexcept {
|
||||||
|
if (enabled) {
|
||||||
|
g_dstAlpha = value;
|
||||||
|
} else {
|
||||||
|
g_dstAlpha.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void set_clear_color(const zeus::CColor& color) noexcept { g_clearColor = color; }
|
||||||
|
void set_alpha_discard(bool v) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_model_view(const zeus::CMatrix4f& mv, const zeus::CMatrix4f& mv_inv) noexcept {
|
||||||
|
g_mv = mv;
|
||||||
|
g_mvInv = mv_inv;
|
||||||
|
}
|
||||||
|
constexpr zeus::CMatrix4f DepthCorrect{
|
||||||
|
// clang-format off
|
||||||
|
1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 1.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 0.5f, 0.5f,
|
||||||
|
0.f, 0.f, 0.f, 1.f,
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
void update_projection(const zeus::CMatrix4f& proj) noexcept { g_proj = DepthCorrect * proj; }
|
||||||
|
void update_fog_state(const metaforce::CFogState& state) noexcept { g_fogState = state; }
|
||||||
|
|
||||||
|
void disable_tev_stage(metaforce::ERglTevStage stage) noexcept { g_tevStages[static_cast<size_t>(stage)].reset(); }
|
||||||
|
void update_tev_stage(metaforce::ERglTevStage stage, const metaforce::CTevCombiners::ColorPass& colPass,
|
||||||
|
const metaforce::CTevCombiners::AlphaPass& alphaPass,
|
||||||
|
const metaforce::CTevCombiners::CTevOp& colorOp,
|
||||||
|
const metaforce::CTevCombiners::CTevOp& alphaOp) noexcept {
|
||||||
|
g_tevStages[static_cast<size_t>(stage)] = {colPass, alphaPass, colorOp, alphaOp};
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_tev_order(GX::TevStageID id, GX::TexCoordID tcid, GX::TexMapID tmid, GX::ChannelID cid) noexcept {
|
||||||
|
auto& stage = g_tevStages[id];
|
||||||
|
if (!stage) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_tev_order: disabled stage {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
stage->texCoordId = tcid;
|
||||||
|
stage->texMapId = tmid;
|
||||||
|
stage->channelId = cid;
|
||||||
|
}
|
||||||
|
void set_tev_k_color_sel(GX::TevStageID id, GX::TevKColorSel sel) noexcept {
|
||||||
|
auto& stage = g_tevStages[id];
|
||||||
|
if (!stage) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_tev_k_color_sel: disabled stage {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
stage->kcSel = sel;
|
||||||
|
}
|
||||||
|
void set_tev_k_alpha_sel(GX::TevStageID id, GX::TevKAlphaSel sel) noexcept {
|
||||||
|
auto& stage = g_tevStages[id];
|
||||||
|
if (!stage) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_tev_k_alpha_sel: disabled stage {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
stage->kaSel = sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_chan_amb_color(GX::ChannelID id, const zeus::CColor& color) noexcept {
|
||||||
|
if (id < GX::COLOR0A0 || id > GX::COLOR1A1) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_chan_amb_color: invalid channel {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
g_colorChannels[id - GX::COLOR0A0].ambColor = color;
|
||||||
|
}
|
||||||
|
void set_chan_mat_color(GX::ChannelID id, const zeus::CColor& color) noexcept {
|
||||||
|
if (id < GX::COLOR0A0 || id > GX::COLOR1A1) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("set_chan_mat_color: invalid channel {}"), id);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
g_colorChannels[id - GX::COLOR0A0].matColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_light(GX::LightID id, const Light& light) noexcept {
|
||||||
|
g_lights[id] = light;
|
||||||
|
}
|
||||||
|
void load_light_ambient(GX::LightID id, const zeus::CColor& ambient) noexcept {
|
||||||
|
g_lights[id] = ambient;
|
||||||
|
}
|
||||||
|
void set_light_state(std::bitset<MaxLights> bits) noexcept {
|
||||||
|
g_lightState = bits;
|
||||||
|
}
|
||||||
|
} // namespace aurora::gfx
|
|
@ -0,0 +1,60 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
namespace aurora::gfx {
|
||||||
|
extern zeus::CMatrix4f g_mv;
|
||||||
|
extern zeus::CMatrix4f g_mvInv;
|
||||||
|
extern zeus::CMatrix4f g_proj;
|
||||||
|
extern metaforce::CFogState g_fogState;
|
||||||
|
extern metaforce::ERglCullMode g_cullMode;
|
||||||
|
extern metaforce::ERglBlendMode g_blendMode;
|
||||||
|
extern metaforce::ERglBlendFactor g_blendFacSrc;
|
||||||
|
extern metaforce::ERglBlendFactor g_blendFacDst;
|
||||||
|
extern metaforce::ERglLogicOp g_blendOp;
|
||||||
|
extern bool g_depthCompare;
|
||||||
|
extern bool g_depthUpdate;
|
||||||
|
extern metaforce::ERglEnum g_depthFunc;
|
||||||
|
extern std::array<zeus::CColor, 3> g_colorRegs;
|
||||||
|
extern std::array<zeus::CColor, GX::MAX_KCOLOR> g_kcolors;
|
||||||
|
extern bool g_alphaUpdate;
|
||||||
|
extern std::optional<float> g_dstAlpha;
|
||||||
|
extern zeus::CColor g_clearColor;
|
||||||
|
|
||||||
|
struct SChannelState {
|
||||||
|
zeus::CColor matColor;
|
||||||
|
zeus::CColor ambColor;
|
||||||
|
};
|
||||||
|
extern std::array<SChannelState, 2> g_colorChannels;
|
||||||
|
using LightVariant = std::variant<std::monostate, Light, zeus::CColor>;
|
||||||
|
extern std::array<LightVariant, MaxLights> g_lights;
|
||||||
|
extern std::bitset<MaxLights> g_lightState;
|
||||||
|
|
||||||
|
struct STevStage {
|
||||||
|
metaforce::CTevCombiners::ColorPass colorPass;
|
||||||
|
metaforce::CTevCombiners::AlphaPass alphaPass;
|
||||||
|
metaforce::CTevCombiners::CTevOp colorOp;
|
||||||
|
metaforce::CTevCombiners::CTevOp alphaOp;
|
||||||
|
GX::TevKColorSel kcSel = GX::TEV_KCSEL_1;
|
||||||
|
GX::TevKAlphaSel kaSel = GX::TEV_KASEL_1;
|
||||||
|
GX::TexCoordID texCoordId = GX::TEXCOORD_NULL;
|
||||||
|
GX::TexMapID texMapId = GX::TEXMAP_NULL;
|
||||||
|
GX::ChannelID channelId = GX::COLOR_NULL;
|
||||||
|
|
||||||
|
STevStage(const metaforce::CTevCombiners::ColorPass& colPass, const metaforce::CTevCombiners::AlphaPass& alphaPass,
|
||||||
|
const metaforce::CTevCombiners::CTevOp& colorOp, const metaforce::CTevCombiners::CTevOp& alphaOp)
|
||||||
|
: colorPass(colPass), alphaPass(alphaPass), colorOp(colorOp), alphaOp(alphaOp) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr u32 maxTevStages = GX::MAX_TEVSTAGE;
|
||||||
|
extern std::array<std::optional<STevStage>, maxTevStages> g_tevStages;
|
||||||
|
|
||||||
|
static inline XXH64_hash_t hash_tev_stages(XXH64_hash_t seed = 0) {
|
||||||
|
const auto end = std::find_if(g_tevStages.cbegin(), g_tevStages.cend(), [](const auto& a) { return !a; });
|
||||||
|
return xxh3_hash(g_tevStages.data(), (end - g_tevStages.begin()) * sizeof(STevStage), seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Mat4x4<float> get_combined_matrix() { return g_proj * g_mv; }
|
||||||
|
} // namespace aurora::gfx
|
|
@ -12,13 +12,7 @@ using gpu::utils::make_vertex_state;
|
||||||
State construct_state() {
|
State construct_state() {
|
||||||
wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{};
|
wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{};
|
||||||
wgslDescriptor.source = R"""(
|
wgslDescriptor.source = R"""(
|
||||||
struct Uniform {
|
|
||||||
xf: mat4x4<f32>;
|
|
||||||
color: vec4<f32>;
|
|
||||||
};
|
|
||||||
@group(0) @binding(0)
|
@group(0) @binding(0)
|
||||||
var<uniform> ubuf: Uniform;
|
|
||||||
@group(0) @binding(1)
|
|
||||||
var tex_sampler: sampler;
|
var tex_sampler: sampler;
|
||||||
@group(1) @binding(0)
|
@group(1) @binding(0)
|
||||||
var tex_y: texture_2d<f32>;
|
var tex_y: texture_2d<f32>;
|
||||||
|
@ -35,7 +29,7 @@ struct VertexOutput {
|
||||||
@stage(vertex)
|
@stage(vertex)
|
||||||
fn vs_main(@location(0) in_pos: vec3<f32>, @location(1) in_uv: vec2<f32>) -> VertexOutput {
|
fn vs_main(@location(0) in_pos: vec3<f32>, @location(1) in_uv: vec2<f32>) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.pos = ubuf.xf * vec4<f32>(in_pos, 1.0);
|
out.pos = vec4<f32>(in_pos, 1.0);
|
||||||
out.uv = in_uv;
|
out.uv = in_uv;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +41,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
textureSample(tex_u, tex_sampler, in.uv).x - 0.5,
|
textureSample(tex_u, tex_sampler, in.uv).x - 0.5,
|
||||||
textureSample(tex_v, tex_sampler, in.uv).x - 0.5
|
textureSample(tex_v, tex_sampler, in.uv).x - 0.5
|
||||||
);
|
);
|
||||||
return ubuf.color * vec4<f32>(
|
return vec4<f32>(
|
||||||
yuv.x + 1.5958 * yuv.z,
|
yuv.x + 1.5958 * yuv.z,
|
||||||
yuv.x - 0.39173 * yuv.y - 0.8129 * yuv.z,
|
yuv.x - 0.39173 * yuv.y - 0.8129 * yuv.z,
|
||||||
yuv.x + 2.017 * yuv.y,
|
yuv.x + 2.017 * yuv.y,
|
||||||
|
@ -61,24 +55,9 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
};
|
};
|
||||||
auto shader = g_device.CreateShaderModule(&shaderDescriptor);
|
auto shader = g_device.CreateShaderModule(&shaderDescriptor);
|
||||||
|
|
||||||
wgpu::SupportedLimits limits;
|
|
||||||
g_device.GetLimits(&limits);
|
|
||||||
const auto uniform_alignment = limits.limits.minUniformBufferOffsetAlignment;
|
|
||||||
const auto uniform_size = ALIGN(sizeof(Uniform), uniform_alignment);
|
|
||||||
|
|
||||||
const std::array uniformLayoutEntries{
|
const std::array uniformLayoutEntries{
|
||||||
wgpu::BindGroupLayoutEntry{
|
wgpu::BindGroupLayoutEntry{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
|
|
||||||
.buffer =
|
|
||||||
wgpu::BufferBindingLayout{
|
|
||||||
.type = wgpu::BufferBindingType::Uniform,
|
|
||||||
.hasDynamicOffset = true,
|
|
||||||
.minBindingSize = uniform_size,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wgpu::BindGroupLayoutEntry{
|
|
||||||
.binding = 1,
|
|
||||||
.visibility = wgpu::ShaderStage::Fragment,
|
.visibility = wgpu::ShaderStage::Fragment,
|
||||||
.sampler =
|
.sampler =
|
||||||
wgpu::SamplerBindingLayout{
|
wgpu::SamplerBindingLayout{
|
||||||
|
@ -107,11 +86,6 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
const std::array uniformBindGroupEntries{
|
const std::array uniformBindGroupEntries{
|
||||||
wgpu::BindGroupEntry{
|
wgpu::BindGroupEntry{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.buffer = g_uniformBuffer,
|
|
||||||
.size = uniform_size,
|
|
||||||
},
|
|
||||||
wgpu::BindGroupEntry{
|
|
||||||
.binding = 1,
|
|
||||||
.sampler = sampler,
|
.sampler = sampler,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -219,24 +193,17 @@ wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] Pipeli
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const TextureHandle& tex_u,
|
DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const TextureHandle& tex_u,
|
||||||
const TextureHandle& tex_v, const zeus::CVector3f& v1, const zeus::CVector3f& v2,
|
const TextureHandle& tex_v, float h_pad, float v_pad) {
|
||||||
const zeus::CVector3f& v3, const zeus::CVector3f& v4) {
|
|
||||||
auto pipeline = pipeline_ref(PipelineConfig{});
|
auto pipeline = pipeline_ref(PipelineConfig{});
|
||||||
|
|
||||||
const std::array verts{
|
const std::array verts{
|
||||||
Vert{{v1.x(), v1.z(), v1.y()}, {0.0, 0.0}},
|
Vert{{-h_pad, v_pad, 0.f}, {0.0, 0.0}},
|
||||||
Vert{{v2.x(), v2.z(), v2.y()}, {0.0, 1.0}},
|
Vert{{-h_pad, -v_pad, 0.f}, {0.0, 1.0}},
|
||||||
Vert{{v3.x(), v3.z(), v3.y()}, {1.0, 0.0}},
|
Vert{{h_pad, v_pad, 0.f}, {1.0, 0.0}},
|
||||||
Vert{{v4.x(), v4.z(), v4.y()}, {1.0, 1.0}},
|
Vert{{h_pad, -v_pad, 0.f}, {1.0, 1.0}},
|
||||||
};
|
};
|
||||||
const auto vertRange = push_verts(ArrayRef{verts});
|
const auto vertRange = push_verts(ArrayRef{verts});
|
||||||
|
|
||||||
const auto uniform = Uniform{
|
|
||||||
.xf = Mat4x4_Identity,
|
|
||||||
.color = zeus::skWhite,
|
|
||||||
};
|
|
||||||
const auto uniformRange = push_uniform(uniform);
|
|
||||||
|
|
||||||
const std::array entries{
|
const std::array entries{
|
||||||
wgpu::BindGroupEntry{
|
wgpu::BindGroupEntry{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
|
@ -261,7 +228,6 @@ DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const Te
|
||||||
return {
|
return {
|
||||||
.pipeline = pipeline,
|
.pipeline = pipeline,
|
||||||
.vertRange = vertRange,
|
.vertRange = vertRange,
|
||||||
.uniformRange = uniformRange,
|
|
||||||
.textureBindGroup = textureBindGroup,
|
.textureBindGroup = textureBindGroup,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -271,8 +237,7 @@ void render(const State& state, const DrawData& data, const wgpu::RenderPassEnco
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array offsets{data.uniformRange.first};
|
pass.SetBindGroup(0, state.uniformBindGroup);
|
||||||
pass.SetBindGroup(0, state.uniformBindGroup, offsets.size(), offsets.data());
|
|
||||||
pass.SetBindGroup(1, find_bind_group(data.textureBindGroup));
|
pass.SetBindGroup(1, find_bind_group(data.textureBindGroup));
|
||||||
pass.SetVertexBuffer(0, g_vertexBuffer, data.vertRange.first, data.vertRange.second);
|
pass.SetVertexBuffer(0, g_vertexBuffer, data.vertRange.first, data.vertRange.second);
|
||||||
pass.Draw(4);
|
pass.Draw(4);
|
||||||
|
|
|
@ -30,15 +30,10 @@ struct alignas(4) Vert {
|
||||||
Vec3<float> pos;
|
Vec3<float> pos;
|
||||||
Vec2<float> uv;
|
Vec2<float> uv;
|
||||||
};
|
};
|
||||||
struct alignas(4) Uniform {
|
|
||||||
Mat4x4<float> xf;
|
|
||||||
Vec4<float> color;
|
|
||||||
};
|
|
||||||
|
|
||||||
State construct_state();
|
State construct_state();
|
||||||
wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config);
|
wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config);
|
||||||
DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const TextureHandle& tex_u,
|
DrawData make_draw_data(const State& state, const TextureHandle& tex_y, const TextureHandle& tex_u,
|
||||||
const TextureHandle& tex_v, const zeus::CVector3f& v1, const zeus::CVector3f& v2,
|
const TextureHandle& tex_v, float h_pad, float v_pad);
|
||||||
const zeus::CVector3f& v3, const zeus::CVector3f& v4);
|
|
||||||
void render(const State& state, const DrawData& data, const wgpu::RenderPassEncoder& pass);
|
void render(const State& state, const DrawData& data, const wgpu::RenderPassEncoder& pass);
|
||||||
} // namespace aurora::gfx::movie_player
|
} // namespace aurora::gfx::movie_player
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "../gpu.hpp"
|
#include "../gpu.hpp"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "gx.hpp"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -12,28 +13,6 @@ using namespace fmt::literals;
|
||||||
|
|
||||||
static logvisor::Module Log("aurora::gfx::stream");
|
static logvisor::Module Log("aurora::gfx::stream");
|
||||||
|
|
||||||
struct STevStage {
|
|
||||||
metaforce::CTevCombiners::ColorPass colorPass;
|
|
||||||
metaforce::CTevCombiners::AlphaPass alphaPass;
|
|
||||||
metaforce::CTevCombiners::CTevOp colorOp;
|
|
||||||
metaforce::CTevCombiners::CTevOp alphaOp;
|
|
||||||
|
|
||||||
STevStage(const metaforce::CTevCombiners::ColorPass& colPass, const metaforce::CTevCombiners::AlphaPass& alphaPass,
|
|
||||||
const metaforce::CTevCombiners::CTevOp& colorOp, const metaforce::CTevCombiners::CTevOp& alphaOp)
|
|
||||||
: colorPass(colPass), alphaPass(alphaPass), colorOp(colorOp), alphaOp(alphaOp) {}
|
|
||||||
};
|
|
||||||
constexpr u32 maxTevStages = 2;
|
|
||||||
static std::array<std::optional<STevStage>, maxTevStages> sTevStages;
|
|
||||||
|
|
||||||
void disable_tev_stage(metaforce::ERglTevStage stage) noexcept { sTevStages[static_cast<size_t>(stage)].reset(); }
|
|
||||||
|
|
||||||
void update_tev_stage(metaforce::ERglTevStage stage, const metaforce::CTevCombiners::ColorPass& colPass,
|
|
||||||
const metaforce::CTevCombiners::AlphaPass& alphaPass,
|
|
||||||
const metaforce::CTevCombiners::CTevOp& colorOp,
|
|
||||||
const metaforce::CTevCombiners::CTevOp& alphaOp) noexcept {
|
|
||||||
sTevStages[static_cast<size_t>(stage)] = {colPass, alphaPass, colorOp, alphaOp};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SStreamState {
|
struct SStreamState {
|
||||||
GX::Primitive primitive;
|
GX::Primitive primitive;
|
||||||
metaforce::EStreamFlags flags;
|
metaforce::EStreamFlags flags;
|
||||||
|
@ -218,7 +197,7 @@ std::unordered_map<ShaderRef, wgpu::ShaderModule> g_streamCachedShaders;
|
||||||
|
|
||||||
static ShaderRef generate_shader() {
|
static ShaderRef generate_shader() {
|
||||||
auto flags = sStreamState->flags;
|
auto flags = sStreamState->flags;
|
||||||
const auto hash = xxh3_hash(sTevStages, static_cast<metaforce::EStreamFlags::MaskType>(flags));
|
const auto hash = hash_tev_stages(static_cast<metaforce::EStreamFlags::MaskType>(flags));
|
||||||
if (g_streamCachedShaders.contains(hash)) {
|
if (g_streamCachedShaders.contains(hash)) {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +243,7 @@ static ShaderRef generate_shader() {
|
||||||
}
|
}
|
||||||
std::string fragmentFn;
|
std::string fragmentFn;
|
||||||
bool hasRast = false;
|
bool hasRast = false;
|
||||||
for (size_t idx = 0; const auto& stage : sTevStages) {
|
for (size_t idx = 0; const auto& stage : g_tevStages) {
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
idx++;
|
idx++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -288,7 +267,7 @@ static ShaderRef generate_shader() {
|
||||||
}
|
}
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
for (size_t idx = 0; const auto& stage : sTevStages) {
|
for (size_t idx = 0; const auto& stage : g_tevStages) {
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
idx++;
|
idx++;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "shader.hpp"
|
#include "shader.hpp"
|
||||||
|
|
||||||
|
#include "../gx.hpp"
|
||||||
#include "../../gpu.hpp"
|
#include "../../gpu.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
Loading…
Reference in New Issue