mirror of https://github.com/AxioDL/metaforce.git
Transition all Textured/ColoredQuad usages
- Upload textures using staging buffer - Fixes SetOrtho logic - More work on thermal visor rendering (still WIP) - Rework Dawn backend initialization - Support MoltenVK on Metal - Various fixes & cleanup
This commit is contained in:
parent
36a7bfc464
commit
f80813b9cc
|
@ -1450,17 +1450,17 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo
|
|||
if (IsInMapperState(EAutoMapperState::MapScreen)) {
|
||||
CAssetId wldMlvl = x24_world->IGetWorldAssetId();
|
||||
const CMapWorld* mw = x24_world->IGetMapWorld();
|
||||
std::vector<CTexturedQuadFilter>& hintBeaconFilters = m_hintBeaconFilters;
|
||||
if (hintBeaconFilters.size() < x1f8_hintLocations.size()) {
|
||||
hintBeaconFilters.reserve(x1f8_hintLocations.size());
|
||||
for (u32 i = hintBeaconFilters.size(); i < x1f8_hintLocations.size(); ++i)
|
||||
hintBeaconFilters.emplace_back(EFilterType::Add, x3c_hintBeacon);
|
||||
}
|
||||
// std::vector<CTexturedQuadFilter>& hintBeaconFilters = m_hintBeaconFilters;
|
||||
// if (hintBeaconFilters.size() < x1f8_hintLocations.size()) {
|
||||
// hintBeaconFilters.reserve(x1f8_hintLocations.size());
|
||||
// for (u32 i = hintBeaconFilters.size(); i < x1f8_hintLocations.size(); ++i)
|
||||
// hintBeaconFilters.emplace_back(EFilterType::Add, x3c_hintBeacon);
|
||||
// }
|
||||
auto locIt = x1f8_hintLocations.cbegin();
|
||||
auto filterIt = hintBeaconFilters.begin();
|
||||
for (; locIt != x1f8_hintLocations.cend(); ++locIt, ++filterIt) {
|
||||
// auto filterIt = hintBeaconFilters.begin();
|
||||
for (; locIt != x1f8_hintLocations.cend(); ++locIt/*, ++filterIt*/) {
|
||||
const SAutoMapperHintLocation& loc = *locIt;
|
||||
CTexturedQuadFilter& filter = *filterIt;
|
||||
// CTexturedQuadFilter& filter = *filterIt;
|
||||
if (loc.x8_worldId != wldMlvl)
|
||||
continue;
|
||||
const CMapArea* mapa = mw->GetMapArea(loc.xc_areaId);
|
||||
|
@ -1475,12 +1475,12 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo
|
|||
beaconAlpha = loc.x4_beaconAlpha;
|
||||
}
|
||||
if (beaconAlpha > 0.f) {
|
||||
constexpr std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
{{-4.f, -8.f, 8.f}, {0.f, 1.f}},
|
||||
{{-4.f, -8.f, 0.f}, {0.f, 0.f}},
|
||||
{{4.f, -8.f, 8.f}, {1.f, 1.f}},
|
||||
{{4.f, -8.f, 0.f}, {1.f, 0.f}},
|
||||
}};
|
||||
// constexpr std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
// {{-4.f, -8.f, 8.f}, {0.f, 1.f}},
|
||||
// {{-4.f, -8.f, 0.f}, {0.f, 0.f}},
|
||||
// {{4.f, -8.f, 8.f}, {1.f, 1.f}},
|
||||
// {{4.f, -8.f, 0.f}, {1.f, 0.f}},
|
||||
// }};
|
||||
float colorAlpha = beaconAlpha;
|
||||
if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) {
|
||||
} else {
|
||||
|
@ -1489,7 +1489,8 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo
|
|||
colorAlpha *= mapAlpha;
|
||||
zeus::CColor color = zeus::skWhite;
|
||||
color.a() = colorAlpha;
|
||||
filter.drawVerts(color, verts);
|
||||
// TODO
|
||||
// filter.drawVerts(color, verts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,6 @@ private:
|
|||
bool m_frmeInitialized = false;
|
||||
TLockedToken<CModel> x30_miniMapSamus;
|
||||
TLockedToken<CTexture> x3c_hintBeacon;
|
||||
std::vector<CTexturedQuadFilter> m_hintBeaconFilters;
|
||||
rstl::reserved_vector<TLockedToken<CTexture>, 5> x48_mapIcons;
|
||||
CAssetId x74_areaHintDescId;
|
||||
TLockedToken<CStringTable> x78_areaHintDesc;
|
||||
|
|
|
@ -167,16 +167,16 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha
|
|||
iconColor.a() *= alpha;
|
||||
|
||||
TLockedToken<CTexture> tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), iconRes});
|
||||
if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) {
|
||||
// if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) {
|
||||
//m_texQuadFilter.emplace(EFilterType::Add, tex, CTexturedQuadFilter::ZTest::GEqual);
|
||||
}
|
||||
// }
|
||||
|
||||
constexpr std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
{{-2.6f, 0.f, 2.6f}, {0.f, 1.f}},
|
||||
{{-2.6f, 0.f, -2.6f}, {0.f, 0.f}},
|
||||
{{2.6f, 0.f, 2.6f}, {1.f, 1.f}},
|
||||
{{2.6f, 0.f, -2.6f}, {1.f, 0.f}},
|
||||
}};
|
||||
// constexpr std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
// {{-2.6f, 0.f, 2.6f}, {0.f, 1.f}},
|
||||
// {{-2.6f, 0.f, -2.6f}, {0.f, 0.f}},
|
||||
// {{2.6f, 0.f, 2.6f}, {1.f, 1.f}},
|
||||
// {{2.6f, 0.f, -2.6f}, {1.f, 0.f}},
|
||||
// }};
|
||||
//m_texQuadFilter->drawVerts(iconColor, verts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "Runtime/GameGlobalObjects.hpp"
|
||||
#include "Runtime/Graphics/CLineRenderer.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CMapSurfaceShader.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
|
||||
#include <zeus/CAABox.hpp>
|
||||
|
@ -67,7 +66,6 @@ private:
|
|||
, m_outline(CLineRenderer::EPrimitiveMode::LineLoop, 5, {}, false, false, true) {}
|
||||
};
|
||||
std::optional<DoorSurface> m_doorSurface;
|
||||
std::optional<CTexturedQuadFilter> m_texQuadFilter;
|
||||
|
||||
zeus::CTransform AdjustTransformForType() const;
|
||||
std::pair<zeus::CColor, zeus::CColor> GetDoorColors(int idx, const CMapWorldInfo& mwInfo, float alpha) const;
|
||||
|
|
|
@ -623,7 +623,7 @@ void CStateManager::DrawE3DeathEffect() {
|
|||
const float whiteAmt = zeus::clamp(0.f, 1.f - player.x9f4_deathTime / (0.05f * 6.f), 1.f);
|
||||
zeus::CColor color = zeus::skWhite;
|
||||
color.a() = whiteAmt;
|
||||
m_deathWhiteout.draw(color);
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Add, EFilterShape::Fullscreen, color, nullptr, 1.f);
|
||||
}
|
||||
|
||||
void CStateManager::DrawAdditionalFilters() {
|
||||
|
@ -633,7 +633,7 @@ void CStateManager::DrawAdditionalFilters() {
|
|||
|
||||
zeus::CColor color = zeus::skWhite;
|
||||
color.a() = 1.f - xf0c_escapeTimer;
|
||||
m_escapeWhiteout.draw(color);
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Add, EFilterShape::Fullscreen, color, nullptr, 1.f);
|
||||
}
|
||||
|
||||
zeus::CFrustum CStateManager::SetupDrawFrustum(const SViewport& vp) const {
|
||||
|
@ -674,32 +674,13 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const {
|
|||
proj.setPersp(zeus::SProjPersp{fov, width / height, cam->GetNearClipDistance(), cam->GetFarClipDistance()});
|
||||
frustum.updatePlanes(camXf, proj);
|
||||
g_Renderer->SetClippingPlanes(frustum);
|
||||
// g_Renderer->PrimColor(zeus::skWhite);
|
||||
g_Renderer->PrimColor(zeus::skWhite);
|
||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||
x87c_fluidPlaneManager->StartFrame(false);
|
||||
g_Renderer->SetDebugOption(IRenderer::EDebugOption::PVSState, int(EPVSVisSetState::NodeFound));
|
||||
return frustum;
|
||||
}
|
||||
|
||||
zeus::CFrustum CStateManager::SetupViewForCubeFaceDraw(const zeus::CVector3f& pos, int face) const {
|
||||
const zeus::CTransform mainCamXf = x870_cameraManager->GetCurrentCameraTransform(*this);
|
||||
const zeus::CTransform camXf = zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], pos);
|
||||
g_Renderer->SetWorldViewpoint(camXf);
|
||||
CCubeModel::SetNewPlayerPositionAndTime(x84c_player->GetTranslation(), CStopwatch::GetGlobalTimerObj());
|
||||
constexpr float width = CUBEMAP_RES;
|
||||
g_Renderer->SetViewport(0, 0, width, width);
|
||||
CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR);
|
||||
constexpr float fov = zeus::degToRad(90.f);
|
||||
g_Renderer->SetPerspective(zeus::radToDeg(fov), width, width, 0.2f, 750.f);
|
||||
zeus::CFrustum frustum;
|
||||
zeus::CProjection proj;
|
||||
proj.setPersp(zeus::SProjPersp{fov, 1.f, 0.2f, 750.f});
|
||||
frustum.updatePlanes(camXf, proj);
|
||||
g_Renderer->SetClippingPlanes(frustum);
|
||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||
return frustum;
|
||||
}
|
||||
|
||||
void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport,
|
||||
const zeus::CTransform& backupViewMatrix) const {
|
||||
g_Renderer->SetViewport(backupViewport.x0_left, backupViewport.x4_top, backupViewport.x8_width,
|
||||
|
@ -725,8 +706,6 @@ void CStateManager::DrawWorld() {
|
|||
|
||||
x850_world->TouchSky();
|
||||
|
||||
DrawWorldCubeFaces();
|
||||
|
||||
const zeus::CFrustum frustum = SetupViewForDraw(CGraphics::g_Viewport);
|
||||
const zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix;
|
||||
|
||||
|
@ -983,120 +962,6 @@ void CStateManager::DrawWorld() {
|
|||
DrawAdditionalFilters();
|
||||
}
|
||||
|
||||
void CStateManager::DrawActorCubeFaces(CActor& actor, int& cubeInst) const {
|
||||
// if (!actor.m_reflectionCube ||
|
||||
// (!TCastToPtr<CPlayer>(actor) && (!actor.GetActive() || !actor.IsDrawEnabled() || actor.xe4_30_outOfFrustum)))
|
||||
// return;
|
||||
//
|
||||
// const TAreaId visAreaId = actor.GetAreaIdAlways();
|
||||
// const SViewport backupVp = g_Viewport;
|
||||
//
|
||||
// int areaCount = 0;
|
||||
// std::array<const CGameArea*, 10> areaArr;
|
||||
// for (const CGameArea& area : *x850_world) {
|
||||
// if (areaCount == 10) {
|
||||
// break;
|
||||
// }
|
||||
// auto occState = CGameArea::EOcclusionState::Occluded;
|
||||
// if (area.IsPostConstructed()) {
|
||||
// occState = area.GetOcclusionState();
|
||||
// }
|
||||
// if (occState == CGameArea::EOcclusionState::Visible) {
|
||||
// areaArr[areaCount++] = &area;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (int f = 0; f < 6; ++f) {
|
||||
// SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CStateManager::DrawActorCubeFaces [{}] {} {} {}"), f,
|
||||
// actor.GetUniqueId(), actor.GetEditorId(), actor.GetName())
|
||||
// .c_str(),
|
||||
// zeus::skOrange);
|
||||
// CGraphics::g_BooMainCommandQueue->setRenderTarget(actor.m_reflectionCube, f);
|
||||
// SetupViewForCubeFaceDraw(actor.GetRenderBounds().center(), f);
|
||||
// CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
//
|
||||
// std::sort(areaArr.begin(), areaArr.begin() + areaCount, [visAreaId](const CGameArea* a, const CGameArea* b) {
|
||||
// if (a->x4_selfIdx == b->x4_selfIdx) {
|
||||
// return false;
|
||||
// }
|
||||
// if (visAreaId == a->x4_selfIdx) {
|
||||
// return false;
|
||||
// }
|
||||
// if (visAreaId == b->x4_selfIdx) {
|
||||
// return true;
|
||||
// }
|
||||
// return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > CGraphics::g_ViewPoint.dot(b->GetAABB().center());
|
||||
// });
|
||||
//
|
||||
// int pvsCount = 0;
|
||||
// std::array<CPVSVisSet, 10> pvsArr;
|
||||
// for (auto area = areaArr.cbegin(); area != areaArr.cbegin() + areaCount; ++area) {
|
||||
// const CGameArea* areaPtr = *area;
|
||||
// CPVSVisSet& pvsSet = pvsArr[pvsCount++];
|
||||
// pvsSet.Reset(EPVSVisSetState::OutOfBounds);
|
||||
// GetVisSetForArea(areaPtr->x4_selfIdx, visAreaId, pvsSet);
|
||||
// }
|
||||
//
|
||||
// for (int i = areaCount - 1; i >= 0; --i) {
|
||||
// const CGameArea& area = *areaArr[i];
|
||||
// SetupFogForArea(area);
|
||||
// g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx);
|
||||
// g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel);
|
||||
// g_Renderer->UpdateAreaUniforms(area.x4_selfIdx, EWorldShadowMode::None, true, cubeInst * 6 + f);
|
||||
// g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, 0x2, 0x0);
|
||||
// }
|
||||
//
|
||||
// if (!SetupFogForDraw()) {
|
||||
// g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::skBlack);
|
||||
// }
|
||||
//
|
||||
// x850_world->DrawSky(zeus::CTransform::Translate(CGraphics::g_ViewPoint));
|
||||
//
|
||||
// for (int i = 0; i < areaCount; ++i) {
|
||||
// const CGameArea& area = *areaArr[i];
|
||||
// CPVSVisSet& pvs = pvsArr[i];
|
||||
// SetupFogForArea(area);
|
||||
// g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel);
|
||||
// g_Renderer->EnablePVS(pvs, area.x4_selfIdx);
|
||||
// g_Renderer->DrawSortedGeometry(area.x4_selfIdx, 0x2, 0x0);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// CGraphics::g_BooMainCommandQueue->generateMipmaps(actor.m_reflectionCube);
|
||||
//
|
||||
// CBooRenderer::BindMainDrawTarget();
|
||||
// g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
|
||||
//
|
||||
// ++cubeInst;
|
||||
}
|
||||
|
||||
void CStateManager::DrawWorldCubeFaces() const {
|
||||
size_t areaCount = 0;
|
||||
std::array<const CGameArea*, 10> areaArr;
|
||||
for (const CGameArea& area : *x850_world) {
|
||||
if (areaCount == areaArr.size()) {
|
||||
break;
|
||||
}
|
||||
auto occState = CGameArea::EOcclusionState::Occluded;
|
||||
if (area.IsPostConstructed()) {
|
||||
occState = area.GetOcclusionState();
|
||||
}
|
||||
if (occState == CGameArea::EOcclusionState::Visible) {
|
||||
areaArr[areaCount++] = &area;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t ai = 0; ai < areaCount; ++ai) {
|
||||
const CGameArea& area = *areaArr[ai];
|
||||
int cubeInst = 0;
|
||||
for (CEntity* ent : *area.GetAreaObjects()) {
|
||||
if (const TCastToPtr<CActor> actor = ent) {
|
||||
DrawActorCubeFaces(*actor, cubeInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CStateManager::SetupFogForArea3XRange(TAreaId area) const {
|
||||
if (area == kInvalidAreaId) {
|
||||
area = x8cc_nextAreaId;
|
||||
|
@ -2490,7 +2355,7 @@ void CStateManager::FrameBegin(s32 frameCount) {
|
|||
x8d4_inputFrameIdx = frameCount;
|
||||
CTexture::SetCurrentFrameCount(frameCount);
|
||||
CGraphicsPalette::SetCurrentFrameCount(frameCount);
|
||||
//SwapOutTexturesToARAM(2, 0x180000);
|
||||
// SwapOutTexturesToARAM(2, 0x180000);
|
||||
}
|
||||
|
||||
void CStateManager::InitializeState(CAssetId mlvlId, TAreaId aid, CAssetId mreaId) {
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "Runtime/Camera/CCameraManager.hpp"
|
||||
#include "Runtime/Camera/CCameraShakeData.hpp"
|
||||
#include "Runtime/GameObjectLists.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/Input/CFinalInput.hpp"
|
||||
#include "Runtime/Input/CRumbleManager.hpp"
|
||||
#include "Runtime/Weapon/CWeaponMgr.hpp"
|
||||
|
@ -211,8 +210,6 @@ private:
|
|||
bool xf94_29_cinematicPause : 1 = false;
|
||||
bool xf94_30_fullThreat : 1 = false;
|
||||
|
||||
CColoredQuadFilter m_deathWhiteout{EFilterType::Add};
|
||||
CColoredQuadFilter m_escapeWhiteout{EFilterType::Add};
|
||||
bool m_warping = false;
|
||||
std::map<TEditorId, std::set<SConnection>> m_incomingConnections;
|
||||
|
||||
|
@ -258,11 +255,8 @@ public:
|
|||
void DrawAdditionalFilters();
|
||||
zeus::CFrustum SetupDrawFrustum(const SViewport& vp) const;
|
||||
zeus::CFrustum SetupViewForDraw(const SViewport& vp) const;
|
||||
zeus::CFrustum SetupViewForCubeFaceDraw(const zeus::CVector3f& pos, int face) const;
|
||||
void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const;
|
||||
void DrawWorld();
|
||||
void DrawActorCubeFaces(CActor& actor, int& cubeInst) const;
|
||||
void DrawWorldCubeFaces() const;
|
||||
void SetupFogForArea3XRange(TAreaId area) const;
|
||||
void SetupFogForArea(TAreaId area) const;
|
||||
void SetupFogForAreaNonCurrent(TAreaId area) const;
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
#include "Runtime/GameGlobalObjects.hpp"
|
||||
#include "Runtime/Graphics/CCubeRenderer.hpp"
|
||||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CRandomStaticFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CScanLinesFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/CGX.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
|
|
@ -682,16 +682,16 @@ void CCubeRenderer::SetPerspective(float fovy, float width, float height, float
|
|||
std::pair<zeus::CVector2f, zeus::CVector2f> CCubeRenderer::SetViewportOrtho(bool centered, float znear, float zfar) {
|
||||
auto left = static_cast<float>(centered ? CGraphics::GetViewportLeft() - CGraphics::GetViewportHalfWidth()
|
||||
: CGraphics::GetViewportLeft());
|
||||
auto top = static_cast<float>(centered ? CGraphics::GetViewportTop() - CGraphics::GetViewportHalfHeight()
|
||||
: CGraphics::GetViewportHeight());
|
||||
auto bottom = static_cast<float>(centered ? CGraphics::GetViewportTop() - CGraphics::GetViewportHalfHeight()
|
||||
: CGraphics::GetViewportTop());
|
||||
auto right = static_cast<float>(CGraphics::GetViewportLeft() +
|
||||
(centered ? CGraphics::GetViewportWidth() / 2 : CGraphics::GetViewportWidth()));
|
||||
auto bottom = static_cast<float>(CGraphics::GetViewportTop() +
|
||||
(centered ? CGraphics::GetViewportHeight() / 2 : CGraphics::GetViewportHeight()));
|
||||
auto top = static_cast<float>(CGraphics::GetViewportTop() +
|
||||
(centered ? CGraphics::GetViewportHeight() / 2 : CGraphics::GetViewportHeight()));
|
||||
CGraphics::SetOrtho(left, right, top, bottom, znear, zfar);
|
||||
CGraphics::SetViewPointMatrix({});
|
||||
CGraphics::SetModelMatrix({});
|
||||
return {{left, top}, {right, bottom}};
|
||||
return {{left, bottom}, {right, top}};
|
||||
}
|
||||
|
||||
void CCubeRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) { x44_frustumPlanes = frustum; }
|
||||
|
@ -896,6 +896,8 @@ void CCubeRenderer::SetThermal(bool thermal, float level, const zeus::CColor& co
|
|||
void CCubeRenderer::SetThermalColdScale(float scale) { x2f8_thermColdScale = zeus::clamp(0.f, scale, 1.f); }
|
||||
|
||||
void CCubeRenderer::DoThermalBlendCold() {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CCubeRenderer::DoThermalBlendCold", zeus::skBlue);
|
||||
|
||||
// Capture EFB
|
||||
x318_26_requestRGBA6 = true;
|
||||
GXSetAlphaUpdate(true);
|
||||
|
@ -908,12 +910,14 @@ void CCubeRenderer::DoThermalBlendCold() {
|
|||
// GXSetTexCopySrc(left, top, width, height);
|
||||
// GXSetTexCopyDst(width, height, GX::TF_I4, false);
|
||||
// GXCopyTex(sSpareTextureData, true);
|
||||
CGraphics::ResolveSpareTexture(aurora::gfx::ClipRect{
|
||||
.x = static_cast<int32_t>(left),
|
||||
.y = static_cast<int32_t>(top),
|
||||
.width = static_cast<int32_t>(width),
|
||||
.height = static_cast<int32_t>(height),
|
||||
}, 0, GX::TF_I4);
|
||||
CGraphics::ResolveSpareTexture(
|
||||
aurora::gfx::ClipRect{
|
||||
.x = static_cast<int32_t>(left),
|
||||
.y = static_cast<int32_t>(top),
|
||||
.width = static_cast<int32_t>(width),
|
||||
.height = static_cast<int32_t>(height),
|
||||
},
|
||||
0, GX::TF_I4);
|
||||
// CGraphics::LoadDolphinSpareTexture(width, height, GX::TF_I4, nullptr, GX::TEXMAP7);
|
||||
CGraphics::LoadDolphinSpareTexture(0, GX::TF_I4, GX::TEXMAP7);
|
||||
|
||||
|
@ -1019,14 +1023,7 @@ void CCubeRenderer::DoThermalBlendCold() {
|
|||
}
|
||||
|
||||
void CCubeRenderer::DoThermalBlendHot() {
|
||||
CGX::SetNumIndStages(0);
|
||||
CGX::SetTevDirect(GX::TEVSTAGE0);
|
||||
GXSetAlphaUpdate(true);
|
||||
// CGraphics::SetProjectionState(backupProjectionState);
|
||||
// CGraphics::SetViewPointMatrix(backupViewMatrix);
|
||||
CDecal::SetMoveRedToAlphaBuffer(false);
|
||||
CElementGen::SetMoveRedToAlphaBuffer(false);
|
||||
return; // TODO
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CCubeRenderer::DoThermalBlendHot", zeus::skRed);
|
||||
|
||||
GXSetAlphaUpdate(false);
|
||||
GXSetDstAlpha(true, 0);
|
||||
|
@ -1041,7 +1038,7 @@ void CCubeRenderer::DoThermalBlendHot() {
|
|||
CGraphics::ResolveSpareTexture(CGraphics::g_Viewport, 0, GX::TF_I4);
|
||||
x288_thermoPalette.Load();
|
||||
// CGraphics::LoadDolphinSpareTexture(width, height, GX::TF_C4, GX::TLUT0, nullptr, GX::TEXMAP7);
|
||||
CGraphics::LoadDolphinSpareTexture(0, GX::TF_C4, GX::TEXMAP7);
|
||||
CGraphics::LoadDolphinSpareTexture(0, GX_TF_C4, GX_TLUT0, GX::TEXMAP7);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_TEXA, GX::CC_TEXC, GX::CC_ZERO);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_TEXA);
|
||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE0);
|
||||
|
@ -1080,7 +1077,14 @@ void CCubeRenderer::DoThermalBlendHot() {
|
|||
GXTexCoord2f32(1.f, 0.f);
|
||||
CGX::End();
|
||||
|
||||
// move prologue here
|
||||
// Cleanup
|
||||
CGX::SetNumIndStages(0);
|
||||
CGX::SetTevDirect(GX::TEVSTAGE0);
|
||||
GXSetAlphaUpdate(true);
|
||||
CGraphics::SetProjectionState(backupProjectionState);
|
||||
CGraphics::SetViewPointMatrix(backupViewMatrix);
|
||||
CDecal::SetMoveRedToAlphaBuffer(false);
|
||||
CElementGen::SetMoveRedToAlphaBuffer(false);
|
||||
}
|
||||
|
||||
u32 CCubeRenderer::GetStaticWorldDataSize() {
|
||||
|
|
|
@ -316,7 +316,13 @@ public:
|
|||
}
|
||||
static void LoadDolphinSpareTexture(int bindIdx, GX::TextureFormat format, GX::TexMapID id) {
|
||||
GXTexObj obj;
|
||||
GXInitTexObjResolved(&obj, bindIdx, format, GX_CLAMP, GX_CLAMP);
|
||||
GXInitTexObjResolved(&obj, bindIdx, format, GX_CLAMP, GX_CLAMP, GX_TLUT0);
|
||||
GXInitTexObjLOD(&obj, GX_NEAR, GX_NEAR, 0.f, 0.f, 0.f, false, false, GX_ANISO_1);
|
||||
GXLoadTexObj(&obj, id);
|
||||
}
|
||||
static void LoadDolphinSpareTexture(int bindIdx, GXCITexFmt format, GXTlut tlut, GX::TexMapID id) {
|
||||
GXTexObj obj;
|
||||
GXInitTexObjResolved(&obj, bindIdx, static_cast<GX::TextureFormat>(format), GX_CLAMP, GX_CLAMP, tlut);
|
||||
GXInitTexObjLOD(&obj, GX_NEAR, GX_NEAR, 0.f, 0.f, 0.f, false, false, GX_ANISO_1);
|
||||
GXLoadTexObj(&obj, id);
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ set(GRAPHICS_SOURCES
|
|||
CRainSplashGenerator.hpp CRainSplashGenerator.cpp
|
||||
CFont.hpp CFont.cpp
|
||||
Shaders/CLineRendererShaders.hpp Shaders/CLineRendererShaders.cpp
|
||||
Shaders/CTexturedQuadFilter.hpp Shaders/CTexturedQuadFilter.cpp
|
||||
Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp
|
||||
Shaders/CColoredStripShader.hpp Shaders/CColoredStripShader.cpp
|
||||
Shaders/CModelShaders.hpp Shaders/CModelShaders.cpp
|
||||
Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "CDvdRequest.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "Graphics/CCubeRenderer.hpp"
|
||||
#include "Graphics/CGX.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
|
||||
#include <amuse/DSPCodec.hpp>
|
||||
|
@ -11,6 +12,110 @@
|
|||
|
||||
namespace metaforce {
|
||||
|
||||
static void MyTHPYuv2RgbTextureSetup(void* dataY, void* dataU, void* dataV, u16 width, u16 height) {
|
||||
GXTexObj texV;
|
||||
GXTexObj texU;
|
||||
GXTexObj texY;
|
||||
GXInitTexObj(&texY, dataY, width, height, GX::TF_I8, GX_CLAMP, GX_CLAMP, false);
|
||||
GXInitTexObjLOD(&texY, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1);
|
||||
GXLoadTexObj(&texY, GX::TEXMAP0);
|
||||
GXInitTexObj(&texU, dataU, width / 2, height / 2, GX::TF_I8, GX_CLAMP, GX_CLAMP, false);
|
||||
GXInitTexObjLOD(&texU, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1);
|
||||
GXLoadTexObj(&texU, GX::TEXMAP1);
|
||||
GXInitTexObj(&texV, dataV, width / 2, height / 2, GX::TF_I8, GX_CLAMP, GX_CLAMP, false);
|
||||
GXInitTexObjLOD(&texV, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1);
|
||||
GXLoadTexObj(&texV, GX::TEXMAP2);
|
||||
CTexture::InvalidateTexMap(GX::TEXMAP0);
|
||||
CTexture::InvalidateTexMap(GX::TEXMAP1);
|
||||
CTexture::InvalidateTexMap(GX::TEXMAP2);
|
||||
}
|
||||
|
||||
const std::array<u8, 32> InterlaceTex{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
static void MyTHPGXYuv2RgbSetup(bool interlaced2ndFrame, bool fieldFlip) {
|
||||
CGX::SetZMode(true, GX::ALWAYS, false);
|
||||
CGX::SetBlendMode(GX::BM_NONE, GX::BL_ONE, GX::BL_ZERO, GX::LO_CLEAR);
|
||||
CGX::SetNumChans(0);
|
||||
CGX::SetTexCoordGen(GX::TEXCOORD0, GX::TG_MTX2x4, GX::TG_TEX0, GX::IDENTITY, false, GX::PTIDENTITY);
|
||||
CGX::SetTexCoordGen(GX::TEXCOORD1, GX::TG_MTX2x4, GX::TG_TEX0, GX::IDENTITY, false, GX::PTIDENTITY);
|
||||
if (!fieldFlip) {
|
||||
CGX::SetNumTexGens(3);
|
||||
CGX::SetTexCoordGen(GX::TEXCOORD2, GX::TG_MTX2x4, GX::TG_POS, GX::TEXMTX0, false, GX::PTIDENTITY);
|
||||
aurora::Mat4x2<float> mtx;
|
||||
mtx.m0.x = 0.125f;
|
||||
mtx.m2.y = 0.25f;
|
||||
if (interlaced2ndFrame) {
|
||||
mtx.m3.y = 0.25f;
|
||||
}
|
||||
GXLoadTexMtxImm(&mtx, GX::TEXMTX0, GX::MTX2x4);
|
||||
GXTexObj texObj;
|
||||
GXInitTexObj(&texObj, InterlaceTex.data(), 8, 4, GX::TF_I8, GX_REPEAT, GX_REPEAT, false);
|
||||
GXInitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.f, 0.f, 0.f, false, false, GX_ANISO_1);
|
||||
GXLoadTexObj(&texObj, GX::TEXMAP3);
|
||||
CTexture::InvalidateTexMap(GX::TEXMAP3);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE4, GX::TEXCOORD2, GX::TEXMAP3, GX::COLOR_NULL);
|
||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE4);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE4, GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_CPREV);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE4, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_TEXA);
|
||||
CGX::SetAlphaCompare(GX::LESS, 128, GX::AOP_AND, GX::ALWAYS, 0);
|
||||
CGX::SetNumTevStages(5);
|
||||
} else {
|
||||
CGX::SetNumTexGens(2);
|
||||
CGX::SetNumTevStages(4);
|
||||
}
|
||||
constexpr std::array vtxDescList{
|
||||
GX::VtxDescList{GX::VA_POS, GX::DIRECT},
|
||||
GX::VtxDescList{GX::VA_TEX0, GX::DIRECT},
|
||||
GX::VtxDescList{},
|
||||
};
|
||||
CGX::SetVtxDescv(vtxDescList.data());
|
||||
GXSetColorUpdate(true);
|
||||
GXSetAlphaUpdate(false);
|
||||
GXInvalidateTexAll();
|
||||
GXSetVtxAttrFmt(GX::VTXFMT7, GX::VA_POS, GX::CLR_RGBA, GX::F32, 0);
|
||||
GXSetVtxAttrFmt(GX::VTXFMT7, GX::VA_TEX0, GX::CLR_RGBA, GX::RGBX8, 0);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD1, GX::TEXMAP1, GX::COLOR_NULL);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_TEXC, GX::CC_KONST, GX::CC_C0);
|
||||
CGX::SetTevColorOp(GX::TEVSTAGE0, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, false, GX::TEVPREV);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_TEXA, GX::CA_KONST, GX::CA_A0);
|
||||
CGX::SetTevAlphaOp(GX::TEVSTAGE0, GX::TEV_SUB, GX::TB_ZERO, GX::CS_SCALE_1, false, GX::TEVPREV);
|
||||
CGX::SetTevKColorSel(GX::TEVSTAGE0, GX::TEV_KCSEL_K0);
|
||||
CGX::SetTevKAlphaSel(GX::TEVSTAGE0, GX::TEV_KASEL_K0_A);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE1, GX::TEXCOORD1, GX::TEXMAP2, GX::COLOR_NULL);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE1, GX::CC_ZERO, GX::CC_TEXC, GX::CC_KONST, GX::CC_CPREV);
|
||||
CGX::SetTevColorOp(GX::TEVSTAGE1, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_2, false, GX::TEVPREV);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE1, GX::CA_ZERO, GX::CA_TEXA, GX::CA_KONST, GX::CA_APREV);
|
||||
CGX::SetTevAlphaOp(GX::TEVSTAGE1, GX::TEV_SUB, GX::TB_ZERO, GX::CS_SCALE_1, false, GX::TEVPREV);
|
||||
CGX::SetTevKColorSel(GX::TEVSTAGE1, GX::TEV_KCSEL_K1);
|
||||
CGX::SetTevKAlphaSel(GX::TEVSTAGE1, GX::TEV_KASEL_K1_A);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE2, GX::TEXCOORD0, GX::TEXMAP0, GX::COLOR_NULL);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE2, GX::CC_ZERO, GX::CC_TEXC, GX::CC_ONE, GX::CC_CPREV);
|
||||
CGX::SetTevColorOp(GX::TEVSTAGE2, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE2, GX::CA_TEXA, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV);
|
||||
CGX::SetTevAlphaOp(GX::TEVSTAGE2, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE3, GX::TEXCOORD_NULL, GX::TEXMAP_NULL, GX::COLOR_NULL);
|
||||
CGX::SetTevColorIn(GX::TEVSTAGE3, GX::CC_APREV, GX::CC_CPREV, GX::CC_KONST, GX::CC_ZERO);
|
||||
CGX::SetTevColorOp(GX::TEVSTAGE3, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
CGX::SetTevAlphaIn(GX::TEVSTAGE3, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO);
|
||||
CGX::SetTevAlphaOp(GX::TEVSTAGE3, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, true, GX::TEVPREV);
|
||||
CGX::SetTevKColorSel(GX::TEVSTAGE3, GX::TEV_KCSEL_K2);
|
||||
GXSetTevColorS10(GX::TEVREG0, 0xffa60000ff8e0087u);
|
||||
CGX::SetTevKColor(GX::KCOLOR0, zeus::Comp32(0x0000e258));
|
||||
CGX::SetTevKColor(GX::KCOLOR1, zeus::Comp32(0xb30000b6));
|
||||
CGX::SetTevKColor(GX::KCOLOR2, zeus::Comp32(0xff00ff80));
|
||||
}
|
||||
static void MyTHPGXRestore() {
|
||||
CGX::SetZMode(true, GX::ALWAYS, false);
|
||||
CGX::SetBlendMode(GX::BM_NONE, GX::BL_ONE, GX::BL_ZERO, GX::LO_SET);
|
||||
CGX::SetNumTexGens(1);
|
||||
CGX::SetNumChans(0);
|
||||
CGX::SetNumTevStages(1);
|
||||
CGX::SetTevOrder(GX::TEVSTAGE0, GX::TEXCOORD0, GX::TEXMAP0, GX::COLOR_NULL);
|
||||
CGX::SetAlphaCompare(GX::ALWAYS, 0, GX::AOP_AND, GX::ALWAYS, 0);
|
||||
}
|
||||
|
||||
/* used in the original to look up fixed-point dividends on a
|
||||
* MIDI-style volume scale (0-127) -> (n/0x8000) */
|
||||
static const std::array<u16, 128> StaticVolumeLookup = {
|
||||
|
@ -359,29 +464,92 @@ void CMoviePlayer::Rewind() {
|
|||
xe8_curSeconds = 0.f;
|
||||
}
|
||||
|
||||
void CMoviePlayer::Draw() {
|
||||
bool CMoviePlayer::DrawVideo() {
|
||||
// TODO
|
||||
// if (!xa0_bufferQueue.empty()) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
g_Renderer->SetDepthReadWrite(false, false);
|
||||
g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f);
|
||||
|
||||
const s32 vpHeight = CGraphics::GetViewportHeight();
|
||||
const s32 vpWidth = CGraphics::GetViewportWidth();
|
||||
const s32 vpTop = CGraphics::GetViewportTop();
|
||||
const s32 vpLeft = CGraphics::GetViewportLeft();
|
||||
const s32 vidWidth = x6c_videoInfo.width;
|
||||
const s32 vidHeight = x6c_videoInfo.height;
|
||||
const s32 centerX = (vidWidth - vpWidth) / 2;
|
||||
const s32 centerY = (vidHeight - vpHeight) / 2;
|
||||
const s32 vl = vpLeft - centerX;
|
||||
const s32 vr = vpLeft + vpWidth + centerX;
|
||||
const s32 vb = vpTop + vpHeight + centerY;
|
||||
const s32 vt = vpTop - centerY;
|
||||
aurora::Vec3<float> v1;
|
||||
aurora::Vec3<float> v2;
|
||||
aurora::Vec3<float> v3;
|
||||
aurora::Vec3<float> v4;
|
||||
v1.x = vl;
|
||||
v1.y = 0.0;
|
||||
v1.z = vb;
|
||||
v2.x = vr;
|
||||
v2.y = 0.0;
|
||||
v2.z = vb;
|
||||
v3.x = vl;
|
||||
v3.y = 0.0;
|
||||
v3.z = vt;
|
||||
v4.x = vr;
|
||||
v4.y = 0.0;
|
||||
v4.z = vt;
|
||||
|
||||
DrawFrame(v1, v2, v3, v4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMoviePlayer::DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
||||
const zeus::CVector3f& v4) {
|
||||
if (xd0_drawTexSlot == UINT32_MAX || !GetIsFullyCached()) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
CGraphics::SetUseVideoFilter(xf4_26_fieldFlip);
|
||||
|
||||
/* draw appropriate field */
|
||||
CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot];
|
||||
aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, hPad, vPad);
|
||||
/* 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 */
|
||||
// CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot];
|
||||
// aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, hPad, vPad);
|
||||
|
||||
MyTHPGXYuv2RgbSetup(CGraphics::g_LastFrameUsedAbove, xf4_26_fieldFlip);
|
||||
uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height;
|
||||
uintptr_t planeSizeQuarter = planeSize / 4;
|
||||
MyTHPYuv2RgbTextureSetup(m_yuvBuf.get(), m_yuvBuf.get() + planeSize, m_yuvBuf.get() + planeSize + planeSizeQuarter,
|
||||
x6c_videoInfo.width, x6c_videoInfo.height);
|
||||
|
||||
CGX::Begin(GX::TRIANGLEFAN, GX::VTXFMT7, 4);
|
||||
GXPosition3f32(v1);
|
||||
GXTexCoord2f32(0.f, 0.f);
|
||||
GXPosition3f32(v3);
|
||||
GXTexCoord2f32(0.f, 1.f);
|
||||
GXPosition3f32(v4);
|
||||
GXTexCoord2f32(1.f, 1.f);
|
||||
GXPosition3f32(v2);
|
||||
GXTexCoord2f32(1.f, 0.f);
|
||||
CGX::End();
|
||||
MyTHPGXRestore();
|
||||
|
||||
/* ensure second field is being displayed by VI to signal advance
|
||||
* (faked in metaforce with continuous xor) */
|
||||
if (!xfc_fieldIndex && CGraphics::g_LastFrameUsedAbove)
|
||||
if (xfc_fieldIndex == 0 && CGraphics::g_LastFrameUsedAbove)
|
||||
xf4_26_fieldFlip = true;
|
||||
|
||||
++xfc_fieldIndex;
|
||||
|
@ -487,29 +655,29 @@ void CMoviePlayer::DecodeFromRead(const void* data) {
|
|||
tjDecompressToYUV(TjHandle, (u8*)inptr, frameHeader.imageSize, m_yuvBuf.get(), 0);
|
||||
inptr += frameHeader.imageSize;
|
||||
|
||||
uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height;
|
||||
uintptr_t planeSizeHalf = planeSize / 2;
|
||||
uintptr_t planeSizeQuarter = planeSizeHalf / 2;
|
||||
// uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height;
|
||||
// uintptr_t planeSizeHalf = planeSize / 2;
|
||||
// uintptr_t planeSizeQuarter = planeSizeHalf / 2;
|
||||
|
||||
if (m_deinterlace) {
|
||||
/* Deinterlace into 2 discrete 60-fps half-res textures */
|
||||
auto buffer = std::make_unique<u8[]>(planeSizeHalf);
|
||||
for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) {
|
||||
memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2),
|
||||
x6c_videoInfo.width);
|
||||
}
|
||||
aurora::gfx::write_texture(*tex.Y[0], {buffer.get(), planeSizeHalf});
|
||||
for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) {
|
||||
memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2 + 1),
|
||||
x6c_videoInfo.width);
|
||||
}
|
||||
aurora::gfx::write_texture(*tex.Y[1], {buffer.get(), planeSizeHalf});
|
||||
} else {
|
||||
/* Direct planar load */
|
||||
aurora::gfx::write_texture(*tex.Y[0], {m_yuvBuf.get(), planeSize});
|
||||
}
|
||||
aurora::gfx::write_texture(*tex.U, {m_yuvBuf.get() + planeSize, planeSizeQuarter});
|
||||
aurora::gfx::write_texture(*tex.V, {m_yuvBuf.get() + planeSize + planeSizeQuarter, planeSizeQuarter});
|
||||
// if (m_deinterlace) {
|
||||
// /* Deinterlace into 2 discrete 60-fps half-res textures */
|
||||
// auto buffer = std::make_unique<u8[]>(planeSizeHalf);
|
||||
// for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) {
|
||||
// memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2),
|
||||
// x6c_videoInfo.width);
|
||||
// }
|
||||
// aurora::gfx::write_texture(*tex.Y[0], {buffer.get(), planeSizeHalf});
|
||||
// for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) {
|
||||
// memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2 + 1),
|
||||
// x6c_videoInfo.width);
|
||||
// }
|
||||
// aurora::gfx::write_texture(*tex.Y[1], {buffer.get(), planeSizeHalf});
|
||||
// } else {
|
||||
// /* Direct planar load */
|
||||
// aurora::gfx::write_texture(*tex.Y[0], {m_yuvBuf.get(), planeSize});
|
||||
// }
|
||||
// aurora::gfx::write_texture(*tex.U, {m_yuvBuf.get() + planeSize, planeSizeQuarter});
|
||||
// aurora::gfx::write_texture(*tex.V, {m_yuvBuf.get() + planeSize + planeSizeQuarter, planeSizeQuarter});
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -136,9 +136,12 @@ public:
|
|||
float GetPlayedSeconds() const { return xdc_frameRem + xe8_curSeconds; }
|
||||
float GetTotalSeconds() const { return xe4_totalSeconds; }
|
||||
void SetPlayMode(EPlayMode mode) { xe0_playMode = mode; }
|
||||
void Draw();
|
||||
bool DrawVideo();
|
||||
void DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
||||
const zeus::CVector3f& v4);
|
||||
void Update(float dt);
|
||||
std::pair<u32, u32> GetVideoDimensions() const { return {x6c_videoInfo.width, x6c_videoInfo.height}; }
|
||||
u32 GetWidth() const { return x6c_videoInfo.width; }
|
||||
u32 GetHeight() const { return x6c_videoInfo.width; }
|
||||
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
|
|
@ -19,29 +19,40 @@ zeus::CAABox CSimpleShadow::GetMaxShadowBox(const zeus::CAABox& aabb) const {
|
|||
|
||||
zeus::CAABox CSimpleShadow::GetBounds() const {
|
||||
float extent = x34_radius * x30_scale;
|
||||
return {{x0_xf.origin.x() - extent, x0_xf.origin.y() - extent, x0_xf.origin.z() - extent},
|
||||
{x0_xf.origin.x() + extent, x0_xf.origin.y() + extent, x0_xf.origin.z() + extent}};
|
||||
return {
|
||||
{x0_xf.origin.x() - extent, x0_xf.origin.y() - extent, x0_xf.origin.z() - extent},
|
||||
{x0_xf.origin.x() + extent, x0_xf.origin.y() + extent, x0_xf.origin.z() + extent},
|
||||
};
|
||||
}
|
||||
|
||||
void CSimpleShadow::Render(const TLockedToken<CTexture>& tex) {
|
||||
void CSimpleShadow::Render(TLockedToken<CTexture>& tex) {
|
||||
if (!x48_24_collision)
|
||||
return;
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CSimpleShadow::Render", zeus::skGrey);
|
||||
|
||||
CGraphics::DisableAllLights();
|
||||
CGraphics::SetModelMatrix(x0_xf);
|
||||
tex->Load(GX::TEXMAP0, EClampMode::Repeat);
|
||||
|
||||
//if (!m_filter || m_filter->GetTex().GetObj() != tex.GetObj())
|
||||
//m_filter.emplace(EFilterType::InvDstMultiply, tex, CTexturedQuadFilter::ZTest::LEqual);
|
||||
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru);
|
||||
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
||||
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, false);
|
||||
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha,
|
||||
ERglLogicOp::Clear);
|
||||
CGraphics::StreamBegin(GX::QUADS);
|
||||
float radius = x34_radius * x30_scale;
|
||||
const std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
{{-radius, 0.f, -radius}, {0.f, 0.f}},
|
||||
{{radius, 0.f, -radius}, {0.f, 1.f}},
|
||||
{{-radius, 0.f, radius}, {1.f, 0.f}},
|
||||
{{radius, 0.f, radius}, {1.f, 1.f}},
|
||||
}};
|
||||
//m_filter->drawVerts(zeus::skWhite, verts);
|
||||
float t = x3c_heightAlpha * x38_userAlpha;
|
||||
CGraphics::StreamColor(zeus::CColor{t, t} /* TODO double check */);
|
||||
CGraphics::StreamTexcoord(0.f, 0.f);
|
||||
CGraphics::StreamVertex(-radius, 0.f, -radius);
|
||||
CGraphics::StreamTexcoord(0.f, 1.f);
|
||||
CGraphics::StreamVertex(radius, 0.f, -radius);
|
||||
CGraphics::StreamTexcoord(1.f, 1.f);
|
||||
CGraphics::StreamVertex(radius, 0.f, radius);
|
||||
CGraphics::StreamTexcoord(1.f, 0.f);
|
||||
CGraphics::StreamVertex(-radius, 0.f, radius);
|
||||
CGraphics::StreamEnd();
|
||||
}
|
||||
|
||||
void CSimpleShadow::Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include "Runtime/CToken.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include <optional>
|
||||
|
||||
#include <zeus/CAABox.hpp>
|
||||
#include <zeus/CTransform.hpp>
|
||||
|
@ -22,7 +23,6 @@ class CSimpleShadow {
|
|||
bool x48_24_collision : 1 = false;
|
||||
bool x48_25_alwaysCalculateRadius : 1 = true;
|
||||
bool x48_26_radiusCalculated : 1 = false;
|
||||
std::optional<CTexturedQuadFilter> m_filter;
|
||||
|
||||
public:
|
||||
CSimpleShadow(float scale, float userAlpha, float maxObjHeight, float displacement);
|
||||
|
@ -33,7 +33,7 @@ public:
|
|||
float GetMaxObjectHeight() const { return x40_maxObjHeight; }
|
||||
void SetUserAlpha(float a) { x38_userAlpha = a; }
|
||||
const zeus::CTransform& GetTransform() const { return x0_xf; }
|
||||
void Render(const TLockedToken<CTexture>& tex);
|
||||
void Render(TLockedToken<CTexture>& tex);
|
||||
void Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr);
|
||||
};
|
||||
} // namespace metaforce
|
||||
|
|
|
@ -741,6 +741,19 @@ enum DistAttnFn {
|
|||
using GXColor = zeus::CColor;
|
||||
using GXBool = bool;
|
||||
|
||||
struct GXColorS10 {
|
||||
s16 r;
|
||||
s16 g;
|
||||
s16 b;
|
||||
s16 a;
|
||||
|
||||
constexpr GXColorS10(u64 c) noexcept
|
||||
: r(static_cast<s16>((c >> 48) & 0xFFFF))
|
||||
, g(static_cast<s16>((c >> 32) & 0xFFFF))
|
||||
, b(static_cast<s16>((c >> 16) & 0xFFFF))
|
||||
, a(static_cast<s16>(c & 0xFFFF)) {}
|
||||
};
|
||||
|
||||
enum GXTlutFmt {
|
||||
GX_TL_IA8 = 0x0,
|
||||
GX_TL_RGB565 = 0x1,
|
||||
|
@ -845,7 +858,9 @@ 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 GXSetTevColorS10(GX::TevRegID id, const GXColorS10& color) noexcept;
|
||||
void GXSetTevKColor(GX::TevKColorID id, const GXColor& color) noexcept;
|
||||
void GXSetColorUpdate(GXBool enabled) noexcept;
|
||||
void GXSetAlphaUpdate(GXBool enabled) noexcept;
|
||||
void GXSetDstAlpha(GXBool enabled, u8 value) noexcept;
|
||||
void GXSetCopyClear(const GXColor& color, float depth) noexcept;
|
||||
|
@ -898,7 +913,7 @@ void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, GX::Te
|
|||
GXTexWrapMode wrapT, GXBool mipmap) noexcept;
|
||||
// Addition for binding render textures
|
||||
void GXInitTexObjResolved(GXTexObj* obj, u32 bindIdx, GX::TextureFormat format, GXTexWrapMode wrapS,
|
||||
GXTexWrapMode wrapT);
|
||||
GXTexWrapMode wrapT, GXTlut tlut);
|
||||
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilt, GXTexFilter magFilt, float minLod, float maxLod, float lodBias,
|
||||
GXBool biasClamp, GXBool doEdgeLod, GXAnisotropy maxAniso) noexcept;
|
||||
void GXInitTexObjCI(GXTexObj* obj, void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS,
|
||||
|
@ -912,6 +927,7 @@ void GXSetTexCopyDst(u16 wd, u16 ht, GX::TextureFormat fmt, GXBool mipmap) noexc
|
|||
u32 GXGetTexBufferSize(u16 width, u16 height, u32 fmt, GXBool mips, u8 maxLod) noexcept;
|
||||
void GXCopyTex(void* dest, GXBool clear) noexcept;
|
||||
static inline void GXPixModeSync() noexcept {} // no-op
|
||||
void GXInvalidateTexAll() noexcept;
|
||||
void GXSetIndTexMtx(GX::IndTexMtxID id, const void* mtx /* Mat4x2<float> */, s8 scaleExp) noexcept;
|
||||
void GXSetTevIndirect(GX::TevStageID tevStage, GX::IndTexStageID indStage, GX::IndTexFormat fmt,
|
||||
GX::IndTexBiasSel biasSel, GX::IndTexMtxID matrixSel, GX::IndTexWrap wrapS, GX::IndTexWrap wrapT,
|
||||
|
|
|
@ -76,10 +76,10 @@ void CWorldShadowShader::lightenShadow() {
|
|||
void CWorldShadowShader::blendPreviousShadow() {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CWorldShadowShader::blendPreviousShadow", zeus::skMagenta);
|
||||
|
||||
if (!m_prevQuad)
|
||||
m_prevQuad.emplace(EFilterType::Blend, m_tex);
|
||||
zeus::CRectangle rect(0.f, 1.f, 1.f, -1.f);
|
||||
m_prevQuad->draw({1.f, 0.85f}, 1.f, rect);
|
||||
// if (!m_prevQuad)
|
||||
// m_prevQuad.emplace(EFilterType::Blend, m_tex);
|
||||
// zeus::CRectangle rect(0.f, 1.f, 1.f, -1.f);
|
||||
// m_prevQuad->draw({1.f, 0.85f}, 1.f, rect);
|
||||
}
|
||||
|
||||
void CWorldShadowShader::resolveTexture() {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <optional>
|
||||
|
||||
#include "Runtime/GCNTypes.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
|
||||
//#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
|
||||
|
||||
|
@ -13,8 +12,8 @@
|
|||
namespace metaforce {
|
||||
|
||||
class CWorldShadowShader {
|
||||
aurora::gfx::TextureHandle m_tex;
|
||||
std::optional<CTexturedQuadFilter> m_prevQuad;
|
||||
// aurora::gfx::TextureHandle m_tex;
|
||||
// std::optional<CTexturedQuadFilter> m_prevQuad;
|
||||
u32 m_w, m_h;
|
||||
|
||||
struct Uniform {
|
||||
|
@ -40,7 +39,7 @@ public:
|
|||
u32 GetWidth() const { return m_w; }
|
||||
u32 GetHeight() const { return m_h; }
|
||||
|
||||
const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; }
|
||||
// const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; }
|
||||
};
|
||||
|
||||
} // namespace metaforce
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "Runtime/CToken.hpp"
|
||||
#include "Runtime/rstl.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/GuiSys/CGuiWidget.hpp"
|
||||
|
||||
#include <zeus/CVector2f.hpp>
|
||||
|
|
|
@ -322,8 +322,9 @@ void CHudDecoInterfaceScan::Update(float dt, const CStateManager& stateMgr) {
|
|||
}
|
||||
|
||||
void CHudDecoInterfaceScan::Draw() {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CHudDecoInterfaceScan::Draw", zeus::skGreen);
|
||||
x18_scanDisplay.Draw();
|
||||
if (x10_loadedScanHudFlat) {
|
||||
if (x10_loadedScanHudFlat != nullptr) {
|
||||
x10_loadedScanHudFlat->Draw(CGuiWidgetDrawParms::Default());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,23 +36,25 @@ void CScanDisplay::CDataDot::Update(float dt) {
|
|||
}
|
||||
|
||||
void CScanDisplay::CDataDot::Draw(const zeus::CColor& col, float radius) {
|
||||
if (x24_alpha == 0.f) {
|
||||
if (x24_alpha == 0.f || x0_dotState == EDotState::Hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x0_dotState != EDotState::Hidden) {
|
||||
const zeus::CTransform xf = zeus::CTransform::Translate(xc_curPos.x(), 0.f, xc_curPos.y());
|
||||
CGraphics::SetModelMatrix(xf);
|
||||
zeus::CColor useColor = col;
|
||||
useColor.a() *= x24_alpha;
|
||||
const std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
{{-radius, 0.f, radius}, {0.f, 1.f}},
|
||||
{{-radius, 0.f, -radius}, {0.f, 0.f}},
|
||||
{{radius, 0.f, radius}, {1.f, 1.f}},
|
||||
{{radius, 0.f, -radius}, {1.f, 0.f}},
|
||||
}};
|
||||
m_quad.drawVerts(useColor, verts);
|
||||
}
|
||||
const zeus::CTransform xf = zeus::CTransform::Translate(xc_curPos.x(), 0.f, xc_curPos.y());
|
||||
g_Renderer->SetModelMatrix(xf);
|
||||
CGraphics::StreamBegin(GX::TRIANGLESTRIP);
|
||||
zeus::CColor useColor = col;
|
||||
useColor.a() *= x24_alpha;
|
||||
CGraphics::StreamColor(useColor);
|
||||
CGraphics::StreamTexcoord(0.f, 1.f);
|
||||
CGraphics::StreamVertex(-radius, 0.f, radius);
|
||||
CGraphics::StreamTexcoord(0.f, 0.f);
|
||||
CGraphics::StreamVertex(-radius, 0.f, -radius);
|
||||
CGraphics::StreamTexcoord(1.f, 1.f);
|
||||
CGraphics::StreamVertex(radius, 0.f, radius);
|
||||
CGraphics::StreamTexcoord(1.f, 0.f);
|
||||
CGraphics::StreamVertex(radius, 0.f, -radius);
|
||||
CGraphics::StreamEnd();
|
||||
}
|
||||
|
||||
void CScanDisplay::CDataDot::StartTransitionTo(const zeus::CVector2f& vec, float dur) {
|
||||
|
@ -444,10 +446,13 @@ void CScanDisplay::Draw() {
|
|||
if (!x0_dataDot.IsLoaded()) {
|
||||
return;
|
||||
}
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CScanDisplay::Draw", zeus::skGreen);
|
||||
|
||||
// No Z-test or write
|
||||
g_Renderer->SetDepthReadWrite(false, false);
|
||||
g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f);
|
||||
// Additive alpha
|
||||
g_Renderer->SetBlendMode_AdditiveAlpha();
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc);
|
||||
x0_dataDot->Load(GX::TEXMAP0, EClampMode::Repeat);
|
||||
|
||||
const float vpRatio = CGraphics::GetViewportHeight() / 480.f;
|
||||
for (CDataDot& dot : xbc_dataDots) {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "Runtime/rstl.hpp"
|
||||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
|
||||
#include <zeus/CColor.hpp>
|
||||
#include <zeus/CQuaternion.hpp>
|
||||
|
@ -40,10 +39,9 @@ public:
|
|||
float x20_remTime = 0.f;
|
||||
float x24_alpha = 0.f;
|
||||
float x28_desiredAlpha = 0.f;
|
||||
CTexturedQuadFilter m_quad;
|
||||
|
||||
public:
|
||||
explicit CDataDot(const TLockedToken<CTexture>& dataDotTex) : m_quad(EFilterType::Add, dataDotTex) {}
|
||||
explicit CDataDot(const TLockedToken<CTexture>& dataDotTex) {}
|
||||
void Update(float dt);
|
||||
void Draw(const zeus::CColor& color, float radius);
|
||||
float GetTransitionFactor() const { return x1c_transDur > 0.f ? x20_remTime / x1c_transDur : 0.f; }
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "Runtime/CIOWin.hpp"
|
||||
#include "Runtime/CToken.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
|
||||
|
|
|
@ -198,20 +198,17 @@ CIOWin::EMessageReturn CCredits::ProcessUserInput(const CFinalInput& input) {
|
|||
}
|
||||
|
||||
void CCredits::DrawVideo() {
|
||||
if (x28_) {
|
||||
/* Render movie */
|
||||
x28_->Draw();
|
||||
if (x5c_27_ || x5c_28_) {
|
||||
float alpha = x58_ / g_tweakGui->x310_;
|
||||
if (x5c_27_) {
|
||||
alpha = 1.f - alpha;
|
||||
}
|
||||
|
||||
alpha = zeus::clamp(0.f, alpha, 1.f);
|
||||
zeus::CColor filterCol = zeus::skBlack;
|
||||
filterCol.a() = alpha;
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Blend, EFilterShape::Fullscreen, filterCol, nullptr, 1.f);
|
||||
/* Render movie */
|
||||
if (x28_ && x28_->DrawVideo() && (x5c_27_ || x5c_28_)) {
|
||||
float alpha = x58_ / g_tweakGui->x310_;
|
||||
if (x5c_27_) {
|
||||
alpha = 1.f - alpha;
|
||||
}
|
||||
|
||||
alpha = zeus::clamp(0.f, alpha, 1.f);
|
||||
zeus::CColor filterCol = zeus::skBlack;
|
||||
filterCol.a() = alpha;
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Blend, EFilterShape::Fullscreen, filterCol, nullptr, 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,30 +16,26 @@ void CFaceplateDecoration::Update(float dt, CStateManager& stateMgr) {
|
|||
if (xc_ready) {
|
||||
x4_tex.Unlock();
|
||||
x0_id = txtrId;
|
||||
if (m_texFilter)
|
||||
m_texFilter = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (x0_id != txtrId && txtrId.IsValid()) {
|
||||
if (m_texFilter)
|
||||
m_texFilter = std::nullopt;
|
||||
x0_id = txtrId;
|
||||
x4_tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), txtrId});
|
||||
xc_ready = true;
|
||||
x4_tex.Lock();
|
||||
}
|
||||
|
||||
if (!m_texFilter && x4_tex.IsLoaded())
|
||||
m_texFilter.emplace(EFilterType::Blend, x4_tex);
|
||||
}
|
||||
|
||||
void CFaceplateDecoration::Draw(CStateManager& stateMgr) {
|
||||
if (xc_ready && m_texFilter) {
|
||||
if (xc_ready && x4_tex) {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CFaceplateDecoration::Draw", zeus::skPurple);
|
||||
zeus::CColor color = zeus::skWhite;
|
||||
color.a() = stateMgr.GetPlayer().GetVisorSteam().GetAlpha();
|
||||
m_texFilter->DrawFilter(EFilterShape::FullscreenQuarters, color, 1.f);
|
||||
float alpha = stateMgr.GetPlayer().GetVisorSteam().GetAlpha();
|
||||
if (!zeus::close_enough(alpha, 0.f)) {
|
||||
zeus::CColor color = zeus::skWhite;
|
||||
color.a() = alpha;
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Blend, EFilterShape::FullscreenQuarters, color, x4_tex.GetObj(), 1.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "Runtime/CToken.hpp"
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
class CStateManager;
|
||||
|
@ -15,7 +15,6 @@ class CFaceplateDecoration {
|
|||
CAssetId x0_id;
|
||||
TToken<CTexture> x4_tex;
|
||||
bool xc_ready = false;
|
||||
std::optional<CTexturedQuadFilter> m_texFilter;
|
||||
|
||||
public:
|
||||
explicit CFaceplateDecoration(CStateManager& stateMgr);
|
||||
|
|
|
@ -1805,7 +1805,7 @@ void CFrontEndUI::Draw() {
|
|||
} else {
|
||||
if ((xcc_curMoviePtr != nullptr)) {
|
||||
/* Render movie */
|
||||
xcc_curMoviePtr->Draw();
|
||||
xcc_curMoviePtr->DrawVideo();
|
||||
}
|
||||
|
||||
if (x50_curScreen == EScreen::FileSelect && x54_nextScreen == EScreen::FileSelect) {
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#include "Runtime/Audio/CSfxManager.hpp"
|
||||
#include "Runtime/Audio/CStaticAudioPlayer.hpp"
|
||||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/GuiSys/CGuiTextSupport.hpp"
|
||||
#include "Runtime/Input/CRumbleGenerator.hpp"
|
||||
#include "Runtime/MP1/CGBASupport.hpp"
|
||||
|
|
|
@ -601,6 +601,7 @@ void CInGameGuiManager::Draw(CStateManager& stateMgr) {
|
|||
float z = 0.5f * (zT * zT * zT * zT * zT * (CGraphics::GetViewportHeight() - 12.f) + 12.f);
|
||||
float x = 0.5f * (xT * (CGraphics::GetViewportWidth() - 12.f) + 12.f);
|
||||
|
||||
// TODO
|
||||
// const std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
// {{-x, 0.f, z}, {0.f, 0.f}},
|
||||
// {{-x, 0.f, -z}, {0.f, 1.f}},
|
||||
|
|
|
@ -214,7 +214,8 @@ void CMFGame::Draw() {
|
|||
|
||||
if (x1c_flowState == EGameFlowState::CinematicSkip) {
|
||||
const float c = std::min(1.f, 1.f - x20_cineSkipTime);
|
||||
m_fadeToBlack.draw(zeus::CColor{c, c, c, c});
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Multiply, EFilterShape::Fullscreen, zeus::CColor{c, c, c, c}, nullptr,
|
||||
1.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "Runtime/CMFGameBase.hpp"
|
||||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/MP1/CInGameGuiManager.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
|
@ -26,8 +25,6 @@ class CMFGame : public CMFGameBase {
|
|||
bool x2a_24_initialized : 1 = false;
|
||||
bool x2a_25_samusAlive : 1 = true;
|
||||
|
||||
CColoredQuadFilter m_fadeToBlack{EFilterType::Multiply};
|
||||
|
||||
bool IsCameraActiveFlow() const {
|
||||
return (x1c_flowState == EGameFlowState::InGame || x1c_flowState == EGameFlowState::SamusDied);
|
||||
}
|
||||
|
|
|
@ -85,12 +85,15 @@ void CPauseScreenBlur::Update(float dt, const CStateManager& stateMgr, bool b) {
|
|||
void CPauseScreenBlur::Draw(const CStateManager&) {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CPauseScreenBlur::Draw", zeus::skPurple);
|
||||
x1c_camBlur.Draw(true);
|
||||
CGraphics::DisableAllLights();
|
||||
CGraphics::SetAmbientColor(zeus::skWhite);
|
||||
const float t = std::fabs(x18_blurAmt);
|
||||
if (x1c_camBlur.GetCurrType() != EBlurType::NoBlur) {
|
||||
const auto filterColor = zeus::CColor::lerp(zeus::skWhite, g_tweakGuiColors->GetPauseBlurFilterColor(), t);
|
||||
m_quarterFilter.DrawFilter(EFilterShape::FullscreenQuarters, filterColor, t);
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Multiply, EFilterShape::FullscreenQuarters, filterColor,
|
||||
x4_mapLightQuarter.GetObj(), t);
|
||||
const auto scanLinesColor = zeus::CColor::lerp(zeus::skWhite, zeus::CColor(0.75f, 1.f), t);
|
||||
m_linesFilter.draw(scanLinesColor);
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Multiply, EFilterShape::ScanLinesEven, scanLinesColor, nullptr, t);
|
||||
}
|
||||
|
||||
if (x50_24_blurring /*&& x1c_camBlur.x2d_noPersistentCopy*/) {
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "Runtime/CToken.hpp"
|
||||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CScanLinesFilter.hpp"
|
||||
#include "Runtime/MP1/CInGameGuiManagerCommon.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
|
@ -23,9 +21,6 @@ class CPauseScreenBlur {
|
|||
bool x50_24_blurring : 1 = false;
|
||||
bool x50_25_gameDraw : 1 = true;
|
||||
|
||||
CTexturedQuadFilter m_quarterFilter{EFilterType::Multiply, x4_mapLightQuarter};
|
||||
CScanLinesFilterEven m_linesFilter{EFilterType::Multiply};
|
||||
|
||||
void OnBlurComplete(bool);
|
||||
void SetState(EState state);
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
namespace metaforce::MP1 {
|
||||
|
||||
const char* kMovies[] = {"Video/wingame.thp", "Video/wingame_good.thp", "Video/wingame_best.thp",
|
||||
"Video/losegame.thp", "Video/05_tallonText.thp", "Video/AfterCredits.thp",
|
||||
"Video/SpecialEnding.thp", "Video/creditBG.thp"};
|
||||
const char* kMovies[] = {
|
||||
"Video/wingame.thp", "Video/wingame_good.thp", "Video/wingame_best.thp", "Video/losegame.thp",
|
||||
"Video/05_tallonText.thp", "Video/AfterCredits.thp", "Video/SpecialEnding.thp", "Video/creditBG.thp",
|
||||
};
|
||||
|
||||
bool CPlayMovie::IsResultsScreen(EWhichMovie which) { return int(which) <= 2; }
|
||||
|
||||
|
@ -15,6 +16,7 @@ CPlayMovie::CPlayMovie(EWhichMovie which) : CIOWin("CPlayMovie"), x18_which(whic
|
|||
CIOWin::EMessageReturn CPlayMovie::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) {
|
||||
return EMessageReturn::RemoveIOWinAndExit;
|
||||
}
|
||||
|
||||
void CPlayMovie::Draw() {
|
||||
if (x14_ != 3) {
|
||||
return;
|
||||
|
@ -28,7 +30,14 @@ void CPlayMovie::Draw() {
|
|||
}
|
||||
}
|
||||
|
||||
void CPlayMovie::DrawVideo() {}
|
||||
void CPlayMovie::DrawText() {}
|
||||
void CPlayMovie::DrawVideo() {
|
||||
if (x38_moviePlayer) {
|
||||
x38_moviePlayer->DrawVideo();
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayMovie::DrawText() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // namespace metaforce::MP1
|
||||
|
|
|
@ -355,9 +355,6 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, CTargetingManager* t
|
|||
rect.x10_height = int(vpH);
|
||||
CGraphics::ResolveSpareTexture(rect, 0, GX::TF_RGB565);
|
||||
|
||||
// TODO hack; figure out why needed
|
||||
CGraphics::SetCullMode(ERglCullMode::None);
|
||||
|
||||
{
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("x64_scanDim Draw", zeus::skMagenta);
|
||||
x64_scanDim.Draw();
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include "Runtime/CPlayerState.hpp"
|
||||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Graphics/CModel.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
#include "Runtime/rstl.hpp"
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ EQuitAction CQuitGameScreen::Update(float dt) {
|
|||
void CQuitGameScreen::Draw() {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CQuitGameScreen::Draw", zeus::skPurple);
|
||||
if (x0_type == EQuitType::QuitGame) {
|
||||
m_blackScreen->draw(zeus::CColor(0.f, 0.5f));
|
||||
CCameraFilterPass::DrawFilter(EFilterType::Blend, EFilterShape::Fullscreen, zeus::CColor{0.f, 0.5f}, nullptr, 1.f);
|
||||
}
|
||||
|
||||
if (x10_loadedFrame) {
|
||||
|
@ -111,10 +111,6 @@ void CQuitGameScreen::ProcessUserInput(const CFinalInput& input) {
|
|||
}
|
||||
}
|
||||
|
||||
CQuitGameScreen::CQuitGameScreen(EQuitType tp) : x0_type(tp) {
|
||||
x4_frame = g_SimplePool->GetObj("FRME_QuitScreen");
|
||||
if (tp == EQuitType::QuitGame)
|
||||
m_blackScreen.emplace(EFilterType::Blend);
|
||||
}
|
||||
CQuitGameScreen::CQuitGameScreen(EQuitType tp) : x0_type(tp) { x4_frame = g_SimplePool->GetObj("FRME_QuitScreen"); }
|
||||
|
||||
} // namespace metaforce::MP1
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "Runtime/CToken.hpp"
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/GuiSys/CGuiFrame.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
|
@ -25,7 +24,7 @@ class CQuitGameScreen {
|
|||
CGuiFrame* x10_loadedFrame = nullptr;
|
||||
CGuiTableGroup* x14_tablegroup_quitgame = nullptr;
|
||||
EQuitAction x18_action = EQuitAction::None;
|
||||
std::optional<CColoredQuadFilter> m_blackScreen;
|
||||
|
||||
void SetColors();
|
||||
|
||||
public:
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "Runtime/World/CGameLight.hpp"
|
||||
#include "Runtime/World/CPlayer.hpp"
|
||||
#include "Runtime/World/CScriptTrigger.hpp"
|
||||
#include "Runtime/Graphics/CCubeRenderer.hpp"
|
||||
|
||||
#include "TCastTo.hpp" // Generated file, do not modify include path
|
||||
|
||||
|
@ -23,8 +24,7 @@ CSamusHud::CSamusHud(CStateManager& stateMgr)
|
|||
: x8_targetingMgr(stateMgr)
|
||||
, x258_frmeHelmet(g_SimplePool->GetObj("FRME_Helmet"))
|
||||
, x268_frmeBaseHud(g_SimplePool->GetObj("FRME_BaseHud"))
|
||||
, x2e0_27_energyLow(stateMgr.GetPlayer().IsEnergyLow(stateMgr))
|
||||
, m_energyDrainFilter(g_tweakGui->GetEnergyDrainFilterAdditive() ? EFilterType::Add : EFilterType::Blend) {
|
||||
, x2e0_27_energyLow(stateMgr.GetPlayer().IsEnergyLow(stateMgr)) {
|
||||
x33c_lights = std::make_unique<CActorLights>(8, zeus::skZero3f, 4, 1, true, 0, 0, 0.1f);
|
||||
x340_hudLights.resize(3, SCachedHudLight(zeus::skZero3f, zeus::skWhite, 0.f, 0.f, 0.f, 0.f));
|
||||
x46c_.resize(3);
|
||||
|
@ -1387,7 +1387,8 @@ void CSamusHud::DrawAttachedEnemyEffect(const CStateManager& mgr) {
|
|||
|
||||
zeus::CColor filterColor = g_tweakGuiColors->GetEnergyDrainFilterColor();
|
||||
filterColor.a() *= alpha;
|
||||
m_energyDrainFilter.draw(filterColor);
|
||||
EFilterType filterType = g_tweakGui->GetEnergyDrainFilterAdditive() ? EFilterType::Add : EFilterType::Blend;
|
||||
CCameraFilterPass::DrawFilter(filterType, EFilterShape::Fullscreen, filterColor, nullptr, 1.f);
|
||||
}
|
||||
|
||||
void CSamusHud::Draw(const CStateManager& mgr, float alpha, CInGameGuiManager::EHelmetVisMode helmetVis, bool hudVis,
|
||||
|
@ -1408,7 +1409,8 @@ void CSamusHud::Draw(const CStateManager& mgr, float alpha, CInGameGuiManager::E
|
|||
if (helmetVis != CInGameGuiManager::EHelmetVisMode::ReducedUpdate &&
|
||||
helmetVis < CInGameGuiManager::EHelmetVisMode::HelmetOnly) {
|
||||
if (alpha < 1.f) {
|
||||
m_cookieCutterStatic.draw(zeus::skWhite, 1.f - alpha);
|
||||
CCameraFilterPass::DrawFilter(EFilterType::NoColor, EFilterShape::CookieCutterDepthRandomStatic, zeus::skWhite,
|
||||
nullptr, 1.f - alpha);
|
||||
}
|
||||
|
||||
if (x288_loadedSelectedHud) {
|
||||
|
@ -1447,8 +1449,10 @@ void CSamusHud::Draw(const CStateManager& mgr, float alpha, CInGameGuiManager::E
|
|||
}
|
||||
x2ac_radarIntf->Draw(mgr, t * alpha);
|
||||
}
|
||||
// Depth read/write enable
|
||||
g_Renderer->SetDepthReadWrite(true, true);
|
||||
}
|
||||
|
||||
// TODO timer stuff?
|
||||
}
|
||||
|
||||
void CSamusHud::DrawHelmet(const CStateManager& mgr, float camYOff) {
|
||||
|
|
|
@ -166,9 +166,6 @@ class CSamusHud {
|
|||
std::array<float, 32> x72c_camZTweaks;
|
||||
rstl::reserved_vector<SProfileInfo, 15> x7ac_;
|
||||
|
||||
CColoredQuadFilter m_energyDrainFilter;
|
||||
CCookieCutterDepthRandomStaticFilter m_cookieCutterStatic{EFilterType::NoColor};
|
||||
|
||||
static CSamusHud* g_SamusHud;
|
||||
static rstl::reserved_vector<bool, 4> BuildPlayerHasVisors(const CStateManager& mgr);
|
||||
static rstl::reserved_vector<bool, 4> BuildPlayerHasBeams(const CStateManager& mgr);
|
||||
|
|
|
@ -120,15 +120,16 @@ CIOWin::EMessageReturn CSlideShow::OnMessage(const CArchitectureMessage& msg, CA
|
|||
}
|
||||
|
||||
void CSlideShow::SSlideData::Draw() {
|
||||
if (!IsLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const zeus::CRectangle rect;
|
||||
m_texQuad->draw(x30_mulColor, 1.f, rect);
|
||||
|
||||
const zeus::CVector2f centeredOffset((x28_canvasSize.x() - m_texQuad->GetTex()->GetWidth()) * 0.5f,
|
||||
(x28_canvasSize.y() - m_texQuad->GetTex()->GetHeight()) * 0.5f);
|
||||
// TODO
|
||||
// if (!IsLoaded()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// const zeus::CRectangle rect;
|
||||
// m_texQuad->draw(x30_mulColor, 1.f, rect);
|
||||
//
|
||||
// const zeus::CVector2f centeredOffset((x28_canvasSize.x() - m_texQuad->GetTex()->GetWidth()) * 0.5f,
|
||||
// (x28_canvasSize.y() - m_texQuad->GetTex()->GetHeight()) * 0.5f);
|
||||
}
|
||||
|
||||
void CSlideShow::Draw() {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "Runtime/RetroTypes.hpp"
|
||||
#include "Runtime/Audio/CSfxManager.hpp"
|
||||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/GuiSys/CGuiTextSupport.hpp"
|
||||
|
||||
#include <zeus/CColor.hpp>
|
||||
|
@ -27,7 +26,6 @@ public:
|
|||
u32 x4_ = -1;
|
||||
u32 x8_ = -1;
|
||||
|
||||
std::optional<CTexturedQuadFilterAlpha> m_texQuad;
|
||||
zeus::CVector2f x18_vpOffset;
|
||||
zeus::CVector2f x20_vpSize;
|
||||
zeus::CVector2f x28_canvasSize;
|
||||
|
@ -35,8 +33,6 @@ public:
|
|||
|
||||
explicit SSlideData(CSlideShow& parent) : x0_parent(parent) { x30_mulColor.a() = 0.f; }
|
||||
|
||||
void SetTexture(const TLockedToken<CTexture>& tex) { m_texQuad.emplace(EFilterType::Blend, tex); }
|
||||
bool IsLoaded() const { return m_texQuad && m_texQuad->GetTex().IsLoaded(); }
|
||||
void Draw();
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Runtime/CSimplePool.hpp"
|
||||
#include "Runtime/GameGlobalObjects.hpp"
|
||||
#include "Runtime/Graphics/CCubeRenderer.hpp"
|
||||
#include "Runtime/Graphics/CGX.hpp"
|
||||
#include "Runtime/Weapon/CGameProjectile.hpp"
|
||||
#include "Runtime/World/CPlayer.hpp"
|
||||
#include "Runtime/World/CScriptEffect.hpp"
|
||||
|
@ -42,9 +43,7 @@ COmegaPirate::CFlash::CFlash(TUniqueId uid, const CEntityInfo& info, const zeus:
|
|||
TLockedToken<CTexture>& thermalSpot, float delay)
|
||||
: CActor(uid, true, "Omega Pirate Flash", info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), {},
|
||||
CActorParameters::None(), kInvalidUniqueId)
|
||||
, xf4_delay(delay)
|
||||
, m_thermalSpotAdd(EFilterType::Add, thermalSpot)
|
||||
, m_thermalSpotSubtract(EFilterType::Subtract, thermalSpot) {}
|
||||
, xf4_delay(delay) {}
|
||||
|
||||
void COmegaPirate::CFlash::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
|
@ -77,9 +76,9 @@ void COmegaPirate::CFlash::Think(float dt, CStateManager& mgr) {
|
|||
|
||||
void COmegaPirate::CFlash::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
|
||||
mgr.RenderLast(GetUniqueId());
|
||||
// if (xf0_thermalSpot == nullptr && xe8_thermalSpotToken.IsLocked() && xe8_thermalSpotToken.HasReference()) {
|
||||
// xf0_thermalSpot = xe8_thermalSpotToken.GetObj();
|
||||
// }
|
||||
if (xf0_thermalSpot == nullptr && xe8_thermalSpotToken.IsLocked() && xe8_thermalSpotToken.HasReference()) {
|
||||
xf0_thermalSpot = xe8_thermalSpotToken.GetObj();
|
||||
}
|
||||
}
|
||||
|
||||
void COmegaPirate::CFlash::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) {}
|
||||
|
@ -89,18 +88,17 @@ void COmegaPirate::CFlash::Render(CStateManager& mgr) {
|
|||
if (visor == CPlayerState::EPlayerVisor::Thermal) {
|
||||
return;
|
||||
}
|
||||
if (xf0_thermalSpot == nullptr || !xe8_thermalSpotToken) {
|
||||
return;
|
||||
}
|
||||
xf0_thermalSpot->Load(GX::TEXMAP0, EClampMode::Repeat);
|
||||
|
||||
float sizeMul = 35.f;
|
||||
CTexturedQuadFilter* filter = nullptr;
|
||||
if (visor == CPlayerState::EPlayerVisor::XRay) {
|
||||
// CGraphics::SetBlendMode(ERglBlendMode::Subtract, ERglBlendFactor::One, ERglBlendFactor::Zero,
|
||||
// ERglLogicOp::Clear);
|
||||
filter = &m_thermalSpotSubtract;
|
||||
CGX::SetBlendMode(GX::BM_SUBTRACT, GX::BL_ONE, GX::BL_ZERO, GX::LO_CLEAR);
|
||||
sizeMul = 60.f;
|
||||
} else {
|
||||
// CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One,
|
||||
// ERglLogicOp::Clear);
|
||||
filter = &m_thermalSpotAdd;
|
||||
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||
}
|
||||
|
||||
float size = xfc_size * sizeMul;
|
||||
|
@ -109,13 +107,20 @@ void COmegaPirate::CFlash::Render(CStateManager& mgr) {
|
|||
const auto rvS = GetTranslation() - rightVec;
|
||||
const auto rvP = GetTranslation() + rightVec;
|
||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||
const std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
{rvS + upVec, {0.f, 0.f}},
|
||||
{rvP + upVec, {0.f, 1.f}},
|
||||
{rvS - upVec, {1.f, 0.f}},
|
||||
{rvP - upVec, {1.f, 1.f}},
|
||||
}};
|
||||
filter->drawVerts(zeus::CColor{1.f, std::min(1.f, size)}, verts);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru);
|
||||
CGraphics::SetDepthWriteMode(false, ERglEnum::Always, false);
|
||||
CGraphics::StreamColor(zeus::CColor{1.f, std::min(1.f, size)});
|
||||
CGraphics::StreamBegin(GX::TRIANGLEFAN);
|
||||
CGraphics::StreamTexcoord(0.f, 0.f);
|
||||
CGraphics::StreamVertex(rvS + upVec);
|
||||
CGraphics::StreamTexcoord(1.f, 0.f);
|
||||
CGraphics::StreamVertex(rvP + upVec);
|
||||
CGraphics::StreamTexcoord(1.f, 1.f);
|
||||
CGraphics::StreamVertex(rvP - upVec);
|
||||
CGraphics::StreamTexcoord(0.f, 1.f);
|
||||
CGraphics::StreamVertex(rvS - upVec);
|
||||
CGraphics::StreamEnd();
|
||||
}
|
||||
|
||||
COmegaPirate::COmegaPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
|
|
|
@ -7,15 +7,12 @@ class COmegaPirate : public CElitePirate {
|
|||
private:
|
||||
class CFlash : public CActor {
|
||||
private:
|
||||
// TToken<CTexture> xe8_thermalSpotToken;
|
||||
// CTexture* xf0_thermalSpot = nullptr;
|
||||
TToken<CTexture> xe8_thermalSpotToken;
|
||||
CTexture* xf0_thermalSpot = nullptr;
|
||||
float xf4_delay;
|
||||
float xf8_time = 0.f;
|
||||
float xfc_size = 0.f;
|
||||
|
||||
CTexturedQuadFilter m_thermalSpotAdd;
|
||||
CTexturedQuadFilter m_thermalSpotSubtract;
|
||||
|
||||
public:
|
||||
DEFINE_ENTITY
|
||||
CFlash(TUniqueId uid, const CEntityInfo& info, const zeus::CVector3f& pos, TLockedToken<CTexture>& thermalSpot,
|
||||
|
|
|
@ -1386,44 +1386,29 @@ void CThardus::RenderFlare(const CStateManager& mgr, float t) {
|
|||
if (!x91c_flareTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_flareFilter) {
|
||||
m_flareFilter.emplace(EFilterType::Add, x91c_flareTexture);
|
||||
}
|
||||
x91c_flareTexture->Load(GX::TEXMAP0, EClampMode::Repeat);
|
||||
|
||||
const float scale = 30.f * t;
|
||||
zeus::CVector3f offset = scale * CGraphics::g_ViewMatrix.basis[2];
|
||||
zeus::CVector3f max = x92c_currentRockPos + (scale * CGraphics::g_ViewMatrix.basis[0]);
|
||||
zeus::CVector3f min = x92c_currentRockPos - (scale * CGraphics::g_ViewMatrix.basis[0]);
|
||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||
const std::array<CTexturedQuadFilter::Vert, 4> verts{{
|
||||
{{max.x() + offset.x(), max.y() + offset.y(), max.z() + offset.z()}, {0.f, 1.f}},
|
||||
{{min.x() + offset.x(), min.y() + offset.y(), min.z() + offset.z()}, {0.f, 0.f}},
|
||||
{{max.x() - offset.x(), max.y() - offset.y(), max.z() - offset.z()}, {1.f, 1.f}},
|
||||
{{min.x() - offset.x(), min.y() - offset.y(), min.z() - offset.z()}, {1.f, 0.f}},
|
||||
}};
|
||||
|
||||
m_flareFilter->drawVerts({t, t}, verts);
|
||||
}
|
||||
|
||||
#if 0
|
||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||
CGraphics::SetModelMatrix({});
|
||||
CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear);
|
||||
CGraphics::SetTevOp(0, CGraphics::sTevPass805a5ebc);
|
||||
CGraphics::SetTevOp(1, CGraphics::skPassThru);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc);
|
||||
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru);
|
||||
CGraphics::SetDepthWriteMode(false, ERglEnum::Always, false);
|
||||
CGraphics::StreamColor(zeus::CColor(f1, f1));
|
||||
CGraphics::StreamBegin(0xa0);
|
||||
CGraphics::StreamTexCoord(0.f, 0.f);
|
||||
CGraphics::StreamColor({t, t});
|
||||
CGraphics::StreamBegin(GX::TRIANGLEFAN);
|
||||
CGraphics::StreamTexcoord(0.f, 0.f);
|
||||
CGraphics::StreamVertex(min + offset);
|
||||
CGraphics::StreamTexCoord(1.f, 0.f);
|
||||
CGraphics::StreamTexcoord(1.f, 0.f);
|
||||
CGraphics::StreamVertex(min - offset);
|
||||
CGraphics::StreamTexCoord(1.f, 1.f);
|
||||
CGraphics::StreamTexcoord(1.f, 1.f);
|
||||
CGraphics::StreamVertex(max - offset);
|
||||
CGraphics::StreamTexCoord(0.f, 1.f);
|
||||
CGraphics::StreamTexcoord(0.f, 1.f);
|
||||
CGraphics::StreamVertex(max + offset);
|
||||
CGraphics::StreamEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
zeus::CVector3f CThardus::sub801de550(CStateManager& mgr) {
|
||||
|
||||
|
|
|
@ -171,8 +171,6 @@ class CThardus : public CPatterned {
|
|||
zeus::CVector2f GetTargetVector(float arg, CStateManager& mgr);
|
||||
void sub801dbc40();
|
||||
|
||||
std::optional<CTexturedQuadFilter> m_flareFilter;
|
||||
|
||||
void DoDoubleSnap(CStateManager& mgr) {
|
||||
x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "DoubleSnap"sv);
|
||||
}
|
||||
|
|
|
@ -175,8 +175,6 @@ CPlayerGun::CPlayerGun(TUniqueId playerId)
|
|||
x550_camBob.SetPlayerVelocity(zeus::skZero3f);
|
||||
x550_camBob.SetBobMagnitude(0.f);
|
||||
x550_camBob.SetBobTimeScale(0.f);
|
||||
|
||||
m_aaboxShader.setAABB(x6c8_hologramClipCube);
|
||||
}
|
||||
|
||||
void CPlayerGun::InitBeamData() {
|
||||
|
@ -2140,13 +2138,17 @@ void CPlayerGun::DrawScreenTex(float z) {
|
|||
// Use CopyScreenTex rendering to draw over framebuffer pixels in front of `z`
|
||||
// This is accomplished using orthographic projection quad with sweeping `y` coordinates
|
||||
// Depth is set to GEQUAL to obscure pixels in front rather than behind
|
||||
// m_screenQuad.draw(zeus::skWhite, 1.f, CTexturedQuadFilter::DefaultRect, z);
|
||||
|
||||
// TODO
|
||||
// m_screenQuad.draw(zeus::skWhite, 1.f, CTexturedQuadFilter::DefaultRect, z);
|
||||
}
|
||||
|
||||
void CPlayerGun::DrawClipCube(const zeus::CAABox& aabb) {
|
||||
// Render AABB as completely transparent object, only modifying Z-buffer
|
||||
// AABB has already been set in constructor (since it's constant)
|
||||
m_aaboxShader.draw(zeus::skClear);
|
||||
|
||||
// TODO
|
||||
// m_aaboxShader.draw(zeus::skClear);
|
||||
}
|
||||
|
||||
void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) {
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "Runtime/Character/CActorLights.hpp"
|
||||
#include "Runtime/Character/CModelData.hpp"
|
||||
#include "Runtime/Graphics/CRainSplashGenerator.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CAABoxShader.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/Particle/CElementGen.hpp"
|
||||
#include "Runtime/Weapon/CAuxWeapon.hpp"
|
||||
#include "Runtime/Weapon/CFidget.hpp"
|
||||
|
@ -255,10 +253,6 @@ private:
|
|||
bool x835_30_inPhazonPool : 1 = false;
|
||||
bool x835_31_actorAttached : 1 = false;
|
||||
|
||||
// CTexturedQuadFilter m_screenQuad{EFilterType::Blend, CGraphics::g_SpareTexture.get(),
|
||||
// CTexturedQuadFilter::ZTest::GEqualZWrite};
|
||||
CAABoxShader m_aaboxShader{true};
|
||||
|
||||
void InitBeamData();
|
||||
void InitBombData();
|
||||
void InitMuzzleData();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CWorldShadowShader.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
|
||||
#include <zeus/CAABox.hpp>
|
||||
#include <zeus/CTransform.hpp>
|
||||
|
|
|
@ -194,6 +194,7 @@ void CWorldTransManager::DrawPlatformModels(CActorLights* lights) {
|
|||
}
|
||||
|
||||
void CWorldTransManager::DrawAllModels(CActorLights* lights) {
|
||||
// TODO this needs reimpl
|
||||
DrawPlatformModels(lights);
|
||||
|
||||
if (!x4_modelData->x1c_samusModelData.IsNull()) {
|
||||
|
@ -210,7 +211,6 @@ void CWorldTransManager::DrawAllModels(CActorLights* lights) {
|
|||
}
|
||||
|
||||
void CWorldTransManager::DrawFirstPass(CActorLights* lights) {
|
||||
// CBooModel::SetReflectionCube(m_reflectionCube[0]);
|
||||
zeus::CTransform translateXf = zeus::CTransform::Translate(
|
||||
x4_modelData->x1b4_shakeResult.x(), -3.5f * (1.f - zeus::clamp(0.f, x0_curTime / 10.f, 1.f)) - 3.5f,
|
||||
x4_modelData->x1b4_shakeResult.y() + 2.f);
|
||||
|
@ -228,7 +228,6 @@ void CWorldTransManager::DrawFirstPass(CActorLights* lights) {
|
|||
}
|
||||
|
||||
void CWorldTransManager::DrawSecondPass(CActorLights* lights) {
|
||||
// CBooModel::SetReflectionCube(m_reflectionCube[1]);
|
||||
const zeus::CVector3f& samusScale = x4_modelData->x0_samusRes.GetScale();
|
||||
zeus::CTransform translateXf =
|
||||
zeus::CTransform::Translate(-0.1f * samusScale.x(), -0.5f * samusScale.y(), 1.5f * samusScale.z());
|
||||
|
@ -243,46 +242,7 @@ void CWorldTransManager::DrawEnabled() {
|
|||
CActorLights lights(0, zeus::skZero3f, 4, 4, 0, 0, 0, 0.1f);
|
||||
lights.BuildFakeLightList(x4_modelData->x1a0_lights, zeus::CColor{0.1f, 0.1f, 0.1f, 1.0f});
|
||||
|
||||
// if (m_reflectionCube[0]) {
|
||||
// SViewport backupVp = g_Viewport;
|
||||
// constexpr float width = CUBEMAP_RES;
|
||||
// CGraphics::g_BooMainCommandQueue->setRenderTarget(m_reflectionCube[0], 0);
|
||||
// g_Renderer->SetViewport(0, 0, width, width);
|
||||
// g_Renderer->SetPerspective(90.f, width, width, 0.2f, 750.f);
|
||||
//
|
||||
// if (x0_curTime < x4_modelData->x1d4_dissolveEndTime) {
|
||||
// zeus::CTransform mainCamXf =
|
||||
// zeus::CTransform::RotateZ(zeus::degToRad(zeus::clamp(0.f, x0_curTime / 25.f, 100.f) * 360.f + 180.f - 90.f));
|
||||
// for (int face = 0; face < 6; ++face) {
|
||||
// CGraphics::g_BooMainCommandQueue->setRenderTarget(m_reflectionCube[0], face);
|
||||
// CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
// zeus::CTransform camXf =
|
||||
// zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], zeus::CVector3f(0.f, 0.f, 1.5f));
|
||||
// g_Renderer->SetWorldViewpoint(camXf);
|
||||
// DrawPlatformModels(&lights);
|
||||
// }
|
||||
// CGraphics::g_BooMainCommandQueue->generateMipmaps(m_reflectionCube[0]);
|
||||
// }
|
||||
// if (x0_curTime > x4_modelData->x1d0_dissolveStartTime) {
|
||||
// zeus::CTransform mainCamXf = zeus::CTransform::RotateZ(
|
||||
// zeus::degToRad(48.f * zeus::clamp(0.f, (x0_curTime - x4_modelData->x1d0_dissolveStartTime + 2.f) / 5.f, 1.f) +
|
||||
// 180.f - 24.f));
|
||||
// for (int face = 0; face < 6; ++face) {
|
||||
// CGraphics::g_BooMainCommandQueue->setRenderTarget(m_reflectionCube[1], face);
|
||||
// CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
// zeus::CTransform camXf =
|
||||
// zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], zeus::CVector3f(0.f, 0.f, 1.5f));
|
||||
// g_Renderer->SetWorldViewpoint(camXf);
|
||||
// DrawPlatformModels(&lights);
|
||||
// }
|
||||
// CGraphics::g_BooMainCommandQueue->generateMipmaps(m_reflectionCube[1]);
|
||||
// }
|
||||
//
|
||||
// CBooRenderer::BindMainDrawTarget();
|
||||
// g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
|
||||
// }
|
||||
|
||||
float wsAspect = CWideScreenFilter::SetViewportToMatch(1.f);
|
||||
float wsAspect = 1.7777f; // TODO
|
||||
|
||||
g_Renderer->SetPerspective(CCameraManager::FirstPersonFOV(), wsAspect, CCameraManager::NearPlane(),
|
||||
CCameraManager::FarPlane());
|
||||
|
@ -402,13 +362,6 @@ void CWorldTransManager::EnableTransition(const CAnimRes& samusRes, CAssetId pla
|
|||
x30_type = ETransType::Enabled;
|
||||
x4_modelData = std::make_unique<SModelDatas>(samusRes);
|
||||
|
||||
// if (!m_reflectionCube[0] && hecl::com_cubemaps->toBoolean())
|
||||
// CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
// m_reflectionCube[0] = ctx.newCubeRenderTexture(CUBEMAP_RES, CUBEMAP_MIPS);
|
||||
// m_reflectionCube[1] = ctx.newCubeRenderTexture(CUBEMAP_RES, CUBEMAP_MIPS);
|
||||
// return true;
|
||||
// } BooTrace);
|
||||
|
||||
x8_textData.reset();
|
||||
x20_random.SetSeed(99);
|
||||
|
||||
|
|
|
@ -10,9 +10,6 @@
|
|||
#include "Runtime/Camera/CCameraFilter.hpp"
|
||||
#include "Runtime/Character/CModelData.hpp"
|
||||
#include "Runtime/Graphics/CLight.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CCameraBlurFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp"
|
||||
#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Runtime/GuiSys/CGuiTextSupport.hpp"
|
||||
#include "Runtime/GuiSys/CStringTable.hpp"
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ target_include_directories(aurora PRIVATE ../imgui ../extern/imgui)
|
|||
target_link_libraries(aurora PRIVATE dawn_native dawncpp webgpu_dawn zeus logvisor SDL2-static xxhash
|
||||
absl::btree absl::flat_hash_map)
|
||||
if (APPLE)
|
||||
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_METAL)
|
||||
target_sources(aurora PRIVATE lib/dawn/MetalBinding.mm)
|
||||
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_METAL DAWN_ENABLE_BACKEND_VULKAN)
|
||||
target_sources(aurora PRIVATE lib/dawn/MetalBinding.mm lib/dawn/VulkanBinding.cpp)
|
||||
set_source_files_properties(lib/dawn/MetalBinding.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
|
||||
elseif (WIN32)
|
||||
target_compile_definitions(aurora PRIVATE
|
||||
|
|
|
@ -30,6 +30,7 @@ struct Vec3 {
|
|||
constexpr Vec3() = default;
|
||||
constexpr Vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||
constexpr Vec3(const zeus::CVector3f& vec) : x(vec.x()), y(vec.y()), z(vec.z()) {}
|
||||
operator zeus::CVector3f() const { return {x, y, z}; }
|
||||
|
||||
bool operator==(const Vec3&) const = default;
|
||||
};
|
||||
|
|
|
@ -221,6 +221,30 @@ static bool poll_events() noexcept {
|
|||
return true;
|
||||
}
|
||||
|
||||
static SDL_Window* create_window(wgpu::BackendType type) {
|
||||
Uint32 flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;
|
||||
switch (type) {
|
||||
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||
case wgpu::BackendType::Vulkan:
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_METAL
|
||||
case wgpu::BackendType::Metal:
|
||||
flags |= SDL_WINDOW_METAL;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_OPENGL
|
||||
case wgpu::BackendType::OpenGL:
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SDL_CreateWindow("Metaforce", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 960, flags);
|
||||
}
|
||||
|
||||
void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv) noexcept {
|
||||
g_AppDelegate = std::move(app);
|
||||
/* Lets gather arguments skipping the program filename */
|
||||
|
@ -244,34 +268,25 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv)
|
|||
/* TODO: Make this an option rather than hard coding it */
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
|
||||
Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;
|
||||
switch (gpu::preferredBackendType) {
|
||||
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||
case wgpu::BackendType::Vulkan:
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_METAL
|
||||
case wgpu::BackendType::Metal:
|
||||
flags |= SDL_WINDOW_METAL;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_OPENGL
|
||||
case wgpu::BackendType::OpenGL:
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
for (const auto backendType : gpu::PreferredBackendOrder) {
|
||||
auto* window = create_window(backendType);
|
||||
if (window == nullptr) {
|
||||
continue;
|
||||
}
|
||||
g_window = window;
|
||||
if (gpu::initialize(window, backendType)) {
|
||||
break;
|
||||
}
|
||||
g_window = nullptr;
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
g_window = SDL_CreateWindow("Metaforce", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 960, flags);
|
||||
if (g_window == nullptr) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Error creating window: {}"), SDL_GetError());
|
||||
unreachable();
|
||||
}
|
||||
set_window_icon(std::move(icon));
|
||||
SDL_ShowWindow(g_window);
|
||||
|
||||
gpu::initialize(g_window);
|
||||
gfx::initialize();
|
||||
|
||||
imgui::create_context();
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
#include "BackendBinding.hpp"
|
||||
|
||||
#if defined(DAWN_ENABLE_BACKEND_D3D12)
|
||||
#include <dawn/native/D3D12Backend.h>
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_BACKEND_METAL)
|
||||
#include <dawn/native/MetalBackend.h>
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
#include <dawn/native/VulkanBackend.h>
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_BACKEND_OPENGL)
|
||||
#include <SDL_video.h>
|
||||
#include <dawn/native/OpenGLBackend.h>
|
||||
|
@ -25,23 +34,44 @@ BackendBinding* CreateVulkanBinding(SDL_Window* window, WGPUDevice device);
|
|||
|
||||
BackendBinding::BackendBinding(SDL_Window* window, WGPUDevice device) : m_window(window), m_device(device) {}
|
||||
|
||||
void DiscoverAdapter(dawn::native::Instance* instance, SDL_Window* window, wgpu::BackendType type) {
|
||||
if (type == wgpu::BackendType::OpenGL || type == wgpu::BackendType::OpenGLES) {
|
||||
bool DiscoverAdapter(dawn::native::Instance* instance, SDL_Window* window, wgpu::BackendType type) {
|
||||
switch (type) {
|
||||
#if defined(DAWN_ENABLE_BACKEND_D3D12)
|
||||
case wgpu::BackendType::D3D12: {
|
||||
dawn::native::d3d12::AdapterDiscoveryOptions options;
|
||||
return instance->DiscoverAdapters(&options);
|
||||
}
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_BACKEND_METAL)
|
||||
case wgpu::BackendType::Metal: {
|
||||
dawn::native::metal::AdapterDiscoveryOptions options;
|
||||
return instance->DiscoverAdapters(&options);
|
||||
}
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
case wgpu::BackendType::Vulkan: {
|
||||
dawn::native::vulkan::AdapterDiscoveryOptions options;
|
||||
return instance->DiscoverAdapters(&options);
|
||||
}
|
||||
#endif
|
||||
#if defined(DAWN_ENABLE_BACKEND_OPENGL)
|
||||
case wgpu::BackendType::OpenGL:
|
||||
case wgpu::BackendType::OpenGLES: {
|
||||
SDL_GL_CreateContext(window);
|
||||
auto getProc = reinterpret_cast<void* (*)(const char*)>(SDL_GL_GetProcAddress);
|
||||
if (type == wgpu::BackendType::OpenGL) {
|
||||
dawn::native::opengl::AdapterDiscoveryOptions adapterOptions;
|
||||
adapterOptions.getProc = getProc;
|
||||
instance->DiscoverAdapters(&adapterOptions);
|
||||
return instance->DiscoverAdapters(&adapterOptions);
|
||||
} else {
|
||||
dawn::native::opengl::AdapterDiscoveryOptionsES adapterOptions;
|
||||
adapterOptions.getProc = getProc;
|
||||
instance->DiscoverAdapters(&adapterOptions);
|
||||
return instance->DiscoverAdapters(&adapterOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
instance->DiscoverDefaultAdapters();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ protected:
|
|||
WGPUDevice m_device = nullptr;
|
||||
};
|
||||
|
||||
void DiscoverAdapter(dawn::native::Instance* instance, SDL_Window* window, wgpu::BackendType type);
|
||||
bool DiscoverAdapter(dawn::native::Instance* instance, SDL_Window* window, wgpu::BackendType type);
|
||||
BackendBinding* CreateBinding(wgpu::BackendType type, SDL_Window* window, WGPUDevice device);
|
||||
|
||||
} // namespace aurora::gpu::utils
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
#include <cassert>
|
||||
#include <dawn/native/VulkanBackend.h>
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace aurora::gpu::utils {
|
||||
static logvisor::Module Log("aurora::gpu::utils::VulkanBinding");
|
||||
|
||||
class VulkanBinding : public BackendBinding {
|
||||
public:
|
||||
VulkanBinding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
|
||||
|
@ -29,7 +33,7 @@ private:
|
|||
void CreateSwapChainImpl() {
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
if (SDL_Vulkan_CreateSurface(m_window, dawn::native::vulkan::GetInstance(m_device), &surface) != SDL_TRUE) {
|
||||
assert(false);
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Failed to create Vulkan surface: {}"), SDL_GetError());
|
||||
}
|
||||
m_swapChainImpl = dawn::native::vulkan::CreateNativeSwapChainImpl(m_device, surface);
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@ constexpr uint64_t UniformBufferSize = 3145728; // 3mb
|
|||
constexpr uint64_t VertexBufferSize = 3145728; // 3mb
|
||||
constexpr uint64_t IndexBufferSize = 1048576; // 1mb
|
||||
constexpr uint64_t StorageBufferSize = 8388608; // 8mb
|
||||
constexpr uint64_t TextureUploadSize = 8388608; // 8mb
|
||||
|
||||
constexpr uint64_t StagingBufferSize = UniformBufferSize + VertexBufferSize + IndexBufferSize + StorageBufferSize;
|
||||
constexpr uint64_t StagingBufferSize =
|
||||
UniformBufferSize + VertexBufferSize + IndexBufferSize + StorageBufferSize + TextureUploadSize;
|
||||
|
||||
struct ShaderState {
|
||||
movie_player::State moviePlayer;
|
||||
|
@ -112,6 +114,7 @@ static ByteBuffer g_uniforms;
|
|||
static ByteBuffer g_indices;
|
||||
static ByteBuffer g_storage;
|
||||
static ByteBuffer g_staticStorage;
|
||||
static ByteBuffer g_textureUpload;
|
||||
wgpu::Buffer g_vertexBuffer;
|
||||
wgpu::Buffer g_uniformBuffer;
|
||||
wgpu::Buffer g_indexBuffer;
|
||||
|
@ -134,6 +137,7 @@ struct RenderPass {
|
|||
static std::vector<RenderPass> g_renderPasses;
|
||||
static u32 g_currentRenderPass;
|
||||
std::vector<TextureHandle> g_resolvedTextures;
|
||||
std::vector<TextureUpload> g_textureUploads;
|
||||
|
||||
static ByteBuffer g_serializedPipelines{};
|
||||
static u32 g_serializedPipelineCount = 0;
|
||||
|
@ -420,6 +424,7 @@ void shutdown() {
|
|||
|
||||
gx::shutdown();
|
||||
|
||||
g_resolvedTextures.clear();
|
||||
g_cachedBindGroups.clear();
|
||||
g_cachedSamplers.clear();
|
||||
g_pipelines.clear();
|
||||
|
@ -464,6 +469,7 @@ void begin_frame() {
|
|||
mapBuffer(g_uniforms, UniformBufferSize);
|
||||
mapBuffer(g_indices, IndexBufferSize);
|
||||
mapBuffer(g_storage, StorageBufferSize);
|
||||
mapBuffer(g_textureUpload, TextureUploadSize);
|
||||
|
||||
g_renderPasses.emplace_back();
|
||||
g_currentRenderPass = 0;
|
||||
|
@ -491,6 +497,23 @@ void end_frame(const wgpu::CommandEncoder& cmd) {
|
|||
g_lastUniformSize = writeBuffer(g_uniforms, g_uniformBuffer, UniformBufferSize, "Uniform");
|
||||
g_lastIndexSize = writeBuffer(g_indices, g_indexBuffer, IndexBufferSize, "Index");
|
||||
g_lastStorageSize = writeBuffer(g_storage, g_storageBuffer, StorageBufferSize, "Storage");
|
||||
{
|
||||
// Perform texture copies
|
||||
for (const auto& item : g_textureUploads) {
|
||||
const wgpu::ImageCopyBuffer buf{
|
||||
.layout =
|
||||
wgpu::TextureDataLayout{
|
||||
.offset = item.layout.offset + bufferOffset,
|
||||
.bytesPerRow = ALIGN(item.layout.bytesPerRow, 256),
|
||||
.rowsPerImage = item.layout.rowsPerImage,
|
||||
},
|
||||
.buffer = g_stagingBuffers[currentStagingBuffer],
|
||||
};
|
||||
cmd.CopyBufferToTexture(&buf, &item.tex, &item.size);
|
||||
}
|
||||
g_textureUploads.clear();
|
||||
g_textureUpload.clear();
|
||||
}
|
||||
currentStagingBuffer = (currentStagingBuffer + 1) % g_stagingBuffers.size();
|
||||
map_staging_buffer();
|
||||
}
|
||||
|
@ -676,6 +699,18 @@ Range push_static_storage(const uint8_t* data, size_t length) {
|
|||
range.isStatic = true;
|
||||
return range;
|
||||
}
|
||||
Range push_texture_data(const uint8_t* data, size_t length, u32 bytesPerRow, u32 rowsPerImage) {
|
||||
// For CopyBufferToTexture, we need an alignment of 256 per row (see Dawn kTextureBytesPerRowAlignment)
|
||||
const auto copyBytesPerRow = ALIGN(bytesPerRow, 256);
|
||||
const auto range = map(g_textureUpload, copyBytesPerRow * rowsPerImage, 0);
|
||||
u8* dst = g_textureUpload.data() + range.offset;
|
||||
for (u32 i = 0; i < rowsPerImage; ++i) {
|
||||
memcpy(dst, data, bytesPerRow);
|
||||
data += bytesPerRow;
|
||||
dst += copyBytesPerRow;
|
||||
}
|
||||
return range;
|
||||
}
|
||||
std::pair<ByteBuffer, Range> map_verts(size_t length) {
|
||||
const auto range = map(g_verts, length, 4);
|
||||
return {ByteBuffer{g_verts.data() + range.offset, range.size}, range};
|
||||
|
|
|
@ -125,6 +125,15 @@ extern wgpu::Buffer g_uniformBuffer;
|
|||
extern wgpu::Buffer g_indexBuffer;
|
||||
extern wgpu::Buffer g_storageBuffer;
|
||||
extern size_t g_staticStorageLastSize;
|
||||
struct TextureUpload {
|
||||
wgpu::TextureDataLayout layout;
|
||||
wgpu::ImageCopyTexture tex;
|
||||
wgpu::Extent3D size;
|
||||
|
||||
TextureUpload(wgpu::TextureDataLayout layout, wgpu::ImageCopyTexture tex, wgpu::Extent3D size) noexcept
|
||||
: layout(std::move(layout)), tex(std::move(tex)), size(std::move(size)) {}
|
||||
};
|
||||
extern std::vector<TextureUpload> g_textureUploads;
|
||||
// TODO this is a bad place for this...
|
||||
extern std::vector<TextureHandle> g_resolvedTextures;
|
||||
|
||||
|
@ -210,6 +219,7 @@ template <typename T>
|
|||
static inline Range push_static_storage(const T& data) {
|
||||
return push_static_storage(reinterpret_cast<const uint8_t*>(&data), sizeof(T));
|
||||
}
|
||||
Range push_texture_data(const uint8_t* data, size_t length, u32 bytesPerRow, u32 rowsPerImage);
|
||||
std::pair<ByteBuffer, Range> map_verts(size_t length);
|
||||
std::pair<ByteBuffer, Range> map_indices(size_t length);
|
||||
std::pair<ByteBuffer, Range> map_uniform(size_t length);
|
||||
|
|
|
@ -515,7 +515,7 @@ void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, GX::Te
|
|||
obj->dataInvalidated = true;
|
||||
}
|
||||
void GXInitTexObjResolved(GXTexObj* obj, u32 bindIdx, GX::TextureFormat format, GXTexWrapMode wrapS,
|
||||
GXTexWrapMode wrapT) {
|
||||
GXTexWrapMode wrapT, GXTlut tlut) {
|
||||
const auto& ref = aurora::gfx::g_resolvedTextures[bindIdx];
|
||||
obj->ref = ref;
|
||||
obj->data = nullptr;
|
||||
|
@ -525,7 +525,8 @@ void GXInitTexObjResolved(GXTexObj* obj, u32 bindIdx, GX::TextureFormat format,
|
|||
obj->fmt = format;
|
||||
obj->wrapS = wrapS;
|
||||
obj->wrapT = wrapT;
|
||||
obj->hasMips = false; // TODO
|
||||
obj->hasMips = false;
|
||||
obj->tlut = tlut;
|
||||
// TODO default values?
|
||||
obj->minFilter = GX_LINEAR;
|
||||
obj->magFilter = GX_LINEAR;
|
||||
|
@ -535,7 +536,6 @@ void GXInitTexObjResolved(GXTexObj* obj, u32 bindIdx, GX::TextureFormat format,
|
|||
obj->biasClamp = false;
|
||||
obj->doEdgeLod = false;
|
||||
obj->maxAniso = GX_ANISO_4;
|
||||
obj->tlut = GX_TLUT0;
|
||||
obj->dataInvalidated = false;
|
||||
}
|
||||
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilt, GXTexFilter magFilt, float minLod, float maxLod, float lodBias,
|
||||
|
@ -545,6 +545,7 @@ void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilt, GXTexFilter magFilt, fl
|
|||
obj->minLod = minLod;
|
||||
obj->maxLod = maxLod;
|
||||
obj->lodBias = lodBias;
|
||||
obj->biasClamp = biasClamp;
|
||||
obj->doEdgeLod = doEdgeLod;
|
||||
obj->maxAniso = maxAniso;
|
||||
}
|
||||
|
@ -611,6 +612,18 @@ void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entri
|
|||
"GXInitTlutObj");
|
||||
}
|
||||
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx) noexcept { g_gxState.tluts[idx] = *obj; }
|
||||
void GXSetColorUpdate(GXBool enabled) noexcept { g_gxState.colorUpdate = enabled; }
|
||||
void GXSetTevColorS10(GX::TevRegID id, const GXColorS10& color) noexcept {
|
||||
g_gxState.colorRegs[id] = zeus::CColor{
|
||||
static_cast<float>(color.r) / 1023.f,
|
||||
static_cast<float>(color.g) / 1023.f,
|
||||
static_cast<float>(color.b) / 1023.f,
|
||||
static_cast<float>(color.a) / 1023.f,
|
||||
};
|
||||
}
|
||||
void GXInvalidateTexAll() noexcept {
|
||||
// no-op?
|
||||
}
|
||||
|
||||
namespace aurora::gfx {
|
||||
static logvisor::Module Log("aurora::gfx::gx");
|
||||
|
@ -771,10 +784,13 @@ static inline wgpu::BlendState to_blend_state(GX::BlendMode mode, GX::BlendFacto
|
|||
};
|
||||
}
|
||||
|
||||
static inline wgpu::ColorWriteMask to_write_mask(bool alphaUpdate) {
|
||||
auto writeMask = wgpu::ColorWriteMask::Red | wgpu::ColorWriteMask::Green | wgpu::ColorWriteMask::Blue;
|
||||
static inline wgpu::ColorWriteMask to_write_mask(bool colorUpdate, bool alphaUpdate) {
|
||||
auto writeMask = wgpu::ColorWriteMask::None;
|
||||
if (colorUpdate) {
|
||||
writeMask |= wgpu::ColorWriteMask::Red | wgpu::ColorWriteMask::Green | wgpu::ColorWriteMask::Blue;
|
||||
}
|
||||
if (alphaUpdate) {
|
||||
writeMask = writeMask | wgpu::ColorWriteMask::Alpha;
|
||||
writeMask |= wgpu::ColorWriteMask::Alpha;
|
||||
}
|
||||
return writeMask;
|
||||
}
|
||||
|
@ -791,25 +807,23 @@ static inline wgpu::PrimitiveState to_primitive_state(GX::Primitive gx_prim, GX:
|
|||
Log.report(logvisor::Fatal, FMT_STRING("Unsupported primitive type {}"), gx_prim);
|
||||
unreachable();
|
||||
}
|
||||
wgpu::FrontFace frontFace = wgpu::FrontFace::CCW;
|
||||
wgpu::CullMode cullMode = wgpu::CullMode::None;
|
||||
switch (gx_cullMode) {
|
||||
case GX::CULL_FRONT:
|
||||
frontFace = wgpu::FrontFace::CW;
|
||||
cullMode = wgpu::CullMode::Front;
|
||||
break;
|
||||
case GX::CULL_BACK:
|
||||
cullMode = wgpu::CullMode::Back;
|
||||
break;
|
||||
case GX::CULL_ALL:
|
||||
case GX::CULL_NONE:
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Unsupported cull mode {}"), gx_cullMode);
|
||||
unreachable();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return {
|
||||
.topology = primitive,
|
||||
.frontFace = frontFace,
|
||||
.frontFace = wgpu::FrontFace::CW,
|
||||
.cullMode = cullMode,
|
||||
};
|
||||
}
|
||||
|
@ -827,7 +841,7 @@ wgpu::RenderPipeline build_pipeline(const PipelineConfig& config, const ShaderIn
|
|||
const std::array colorTargets{wgpu::ColorTargetState{
|
||||
.format = g_graphicsConfig.colorFormat,
|
||||
.blend = &blendState,
|
||||
.writeMask = to_write_mask(config.alphaUpdate),
|
||||
.writeMask = to_write_mask(config.colorUpdate, config.alphaUpdate),
|
||||
}};
|
||||
const auto fragmentState = wgpu::FragmentState{
|
||||
.module = shader,
|
||||
|
@ -888,22 +902,13 @@ void populate_pipeline_config(PipelineConfig& config, GX::Primitive primitive) n
|
|||
[](const auto type) { return type == GX::INDEX8 || type == GX::INDEX16; });
|
||||
for (u8 i = 0; i < MaxTextures; ++i) {
|
||||
const auto& bind = g_gxState.textures[i];
|
||||
GX::TextureFormat copyFmt, bindFmt;
|
||||
bool flipUV = false;
|
||||
if (!bind.texObj.ref) {
|
||||
config.shaderConfig.textureConfig[i] = {};
|
||||
continue;
|
||||
} else if (bind.texObj.ref->isRenderTexture) {
|
||||
// EFB copy
|
||||
copyFmt = bind.texObj.ref->gxFormat;
|
||||
bindFmt = bind.texObj.fmt;
|
||||
flipUV = true;
|
||||
} else {
|
||||
// Loaded texture object, no conversion necessary
|
||||
copyFmt = InvalidTextureFormat;
|
||||
bindFmt = bind.texObj.fmt;
|
||||
TextureConfig texConfig{};
|
||||
if (bind.texObj.ref) {
|
||||
texConfig.copyFmt = bind.texObj.ref->gxFormat;
|
||||
texConfig.loadFmt = bind.texObj.fmt;
|
||||
texConfig.renderTex = bind.texObj.ref->isRenderTexture;
|
||||
}
|
||||
config.shaderConfig.textureConfig[i] = {copyFmt, bindFmt, flipUV};
|
||||
config.shaderConfig.textureConfig[i] = texConfig;
|
||||
}
|
||||
config = {
|
||||
.shaderConfig = config.shaderConfig,
|
||||
|
@ -918,6 +923,7 @@ void populate_pipeline_config(PipelineConfig& config, GX::Primitive primitive) n
|
|||
.depthCompare = g_gxState.depthCompare,
|
||||
.depthUpdate = g_gxState.depthUpdate,
|
||||
.alphaUpdate = g_gxState.alphaUpdate,
|
||||
.colorUpdate = g_gxState.colorUpdate,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -983,7 +989,7 @@ Range build_uniform(const ShaderInfo& info) noexcept {
|
|||
const auto& mat = std::get<Mat4x4<float>>(g_gxState.texMtxs[i]);
|
||||
buf.append(&mat, 64);
|
||||
} else {
|
||||
// Log.report(logvisor::Fatal, FMT_STRING("expected 3x4 mtx in idx {}"), i);
|
||||
Log.report(logvisor::Fatal, FMT_STRING("expected 3x4 mtx in idx {}"), i);
|
||||
buf.append(&Mat4x4_Identity, 64);
|
||||
}
|
||||
break;
|
||||
|
@ -1073,28 +1079,28 @@ GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& confi
|
|||
std::array<wgpu::BindGroupEntry, MaxTextures * 2> textureEntries;
|
||||
u32 samplerCount = 0;
|
||||
u32 textureCount = 0;
|
||||
for (u32 texIdx = 0, i = 0; texIdx < info.sampledTextures.size(); ++texIdx) {
|
||||
if (!info.sampledTextures.test(texIdx)) {
|
||||
for (u32 i = 0; i < info.sampledTextures.size(); ++i) {
|
||||
if (!info.sampledTextures.test(i)) {
|
||||
continue;
|
||||
}
|
||||
const auto& tex = g_gxState.textures[texIdx];
|
||||
const auto& tex = g_gxState.textures[i];
|
||||
if (!tex) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("unbound texture {}"), texIdx);
|
||||
Log.report(logvisor::Fatal, FMT_STRING("unbound texture {}"), i);
|
||||
unreachable();
|
||||
}
|
||||
samplerEntries[i] = {
|
||||
.binding = i,
|
||||
samplerEntries[samplerCount] = {
|
||||
.binding = samplerCount,
|
||||
.sampler = sampler_ref(tex.get_descriptor()),
|
||||
};
|
||||
++samplerCount;
|
||||
textureEntries[i] = {
|
||||
.binding = i,
|
||||
textureEntries[textureCount] = {
|
||||
.binding = textureCount,
|
||||
.textureView = tex.texObj.ref->view,
|
||||
};
|
||||
++textureCount;
|
||||
// Load palette
|
||||
const auto& texConfig = config.textureConfig[i];
|
||||
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||
++i;
|
||||
u32 tlut = tex.texObj.tlut;
|
||||
if (tlut < GX_TLUT0 || tlut > GX_TLUT7) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("tlut out of bounds {}"), tlut);
|
||||
|
@ -1103,15 +1109,12 @@ GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& confi
|
|||
Log.report(logvisor::Fatal, FMT_STRING("tlut unbound {}"), tlut);
|
||||
unreachable();
|
||||
}
|
||||
textureEntries[i] = {
|
||||
.binding = i,
|
||||
textureEntries[textureCount] = {
|
||||
.binding = textureCount,
|
||||
.textureView = g_gxState.tluts[tlut].ref->view,
|
||||
};
|
||||
textureCount += 2;
|
||||
} else {
|
||||
++textureCount;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return {
|
||||
.uniformBindGroup = bind_group_ref(wgpu::BindGroupDescriptor{
|
||||
|
@ -1199,77 +1202,82 @@ GXBindGroupLayouts build_bind_group_layouts(const ShaderInfo& info, const Shader
|
|||
sUniformBindGroupLayouts.try_emplace(uniformSizeKey, out.uniformLayout);
|
||||
}
|
||||
|
||||
u32 textureCount = info.sampledTextures.count();
|
||||
// const auto textureIt = sTextureBindGroupLayouts.find(textureCount);
|
||||
// if (textureIt != sTextureBindGroupLayouts.end()) {
|
||||
// const auto& [sl, tl] = textureIt->second;
|
||||
// out.samplerLayout = sl;
|
||||
// out.textureLayout = tl;
|
||||
// } else {
|
||||
u32 numSamplers = 0;
|
||||
u32 numTextures = 0;
|
||||
std::array<wgpu::BindGroupLayoutEntry, MaxTextures> samplerEntries;
|
||||
std::array<wgpu::BindGroupLayoutEntry, MaxTextures * 2> textureEntries;
|
||||
for (u32 i = 0, t = 0; i < textureCount; ++i, ++t) {
|
||||
samplerEntries[i] = {
|
||||
.binding = i,
|
||||
// u32 textureCount = info.sampledTextures.count();
|
||||
// const auto textureIt = sTextureBindGroupLayouts.find(textureCount);
|
||||
// if (textureIt != sTextureBindGroupLayouts.end()) {
|
||||
// const auto& [sl, tl] = textureIt->second;
|
||||
// out.samplerLayout = sl;
|
||||
// out.textureLayout = tl;
|
||||
// } else {
|
||||
u32 numSamplers = 0;
|
||||
u32 numTextures = 0;
|
||||
std::array<wgpu::BindGroupLayoutEntry, MaxTextures> samplerEntries;
|
||||
std::array<wgpu::BindGroupLayoutEntry, MaxTextures * 2> textureEntries;
|
||||
for (u32 i = 0; i < info.sampledTextures.size(); ++i) {
|
||||
if (!info.sampledTextures.test(i)) {
|
||||
continue;
|
||||
}
|
||||
samplerEntries[numSamplers] = {
|
||||
.binding = numSamplers,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.sampler = {.type = wgpu::SamplerBindingType::Filtering},
|
||||
};
|
||||
++numSamplers;
|
||||
const auto& texConfig = config.textureConfig[i];
|
||||
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||
bool isPaletted =
|
||||
texConfig.copyFmt == GX::TF_C4 || texConfig.copyFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2;
|
||||
textureEntries[numTextures] = {
|
||||
.binding = numTextures,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.sampler = {.type = wgpu::SamplerBindingType::Filtering},
|
||||
.texture =
|
||||
{
|
||||
.sampleType = isPaletted ? wgpu::TextureSampleType::Sint : wgpu::TextureSampleType::Float,
|
||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
},
|
||||
};
|
||||
++numSamplers;
|
||||
const auto& texConfig = config.textureConfig[i];
|
||||
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||
textureEntries[t] = {
|
||||
.binding = t,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.texture =
|
||||
{
|
||||
.sampleType = wgpu::TextureSampleType::Sint,
|
||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
},
|
||||
};
|
||||
++t;
|
||||
textureEntries[t] = {
|
||||
.binding = t,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.texture =
|
||||
{
|
||||
.sampleType = wgpu::TextureSampleType::Float,
|
||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
},
|
||||
};
|
||||
numTextures += 2;
|
||||
} else {
|
||||
textureEntries[t] = {
|
||||
.binding = t,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.texture =
|
||||
{
|
||||
.sampleType = wgpu::TextureSampleType::Float,
|
||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
},
|
||||
};
|
||||
++numTextures;
|
||||
}
|
||||
}
|
||||
{
|
||||
const wgpu::BindGroupLayoutDescriptor descriptor{
|
||||
.label = "GX Sampler Bind Group",
|
||||
.entryCount = numSamplers,
|
||||
.entries = samplerEntries.data(),
|
||||
++numTextures;
|
||||
textureEntries[numTextures] = {
|
||||
.binding = numTextures,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.texture =
|
||||
{
|
||||
.sampleType = wgpu::TextureSampleType::Float,
|
||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
},
|
||||
};
|
||||
out.samplerLayout = g_device.CreateBindGroupLayout(&descriptor);
|
||||
}
|
||||
{
|
||||
const wgpu::BindGroupLayoutDescriptor descriptor{
|
||||
.label = "GX Texture Bind Group",
|
||||
.entryCount = numTextures,
|
||||
.entries = textureEntries.data(),
|
||||
++numTextures;
|
||||
} else {
|
||||
textureEntries[numTextures] = {
|
||||
.binding = numTextures,
|
||||
.visibility = wgpu::ShaderStage::Fragment,
|
||||
.texture =
|
||||
{
|
||||
.sampleType = wgpu::TextureSampleType::Float,
|
||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||
},
|
||||
};
|
||||
out.textureLayout = g_device.CreateBindGroupLayout(&descriptor);
|
||||
++numTextures;
|
||||
}
|
||||
// sTextureBindGroupLayouts.try_emplace(textureCount, out.samplerLayout, out.textureLayout);
|
||||
// }
|
||||
}
|
||||
{
|
||||
const wgpu::BindGroupLayoutDescriptor descriptor{
|
||||
.label = "GX Sampler Bind Group Layout",
|
||||
.entryCount = numSamplers,
|
||||
.entries = samplerEntries.data(),
|
||||
};
|
||||
out.samplerLayout = g_device.CreateBindGroupLayout(&descriptor);
|
||||
}
|
||||
{
|
||||
const wgpu::BindGroupLayoutDescriptor descriptor{
|
||||
.label = "GX Texture Bind Group Layout",
|
||||
.entryCount = numTextures,
|
||||
.entries = textureEntries.data(),
|
||||
};
|
||||
out.textureLayout = g_device.CreateBindGroupLayout(&descriptor);
|
||||
}
|
||||
// sTextureBindGroupLayouts.try_emplace(textureCount, out.samplerLayout, out.textureLayout);
|
||||
// }
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ struct GXState {
|
|||
std::array<IndTexMtxInfo, MaxIndTexMtxs> indTexMtxs;
|
||||
bool depthCompare = true;
|
||||
bool depthUpdate = true;
|
||||
bool colorUpdate = true;
|
||||
bool alphaUpdate = true;
|
||||
u8 numChans = 0;
|
||||
u8 numIndStages = 0;
|
||||
|
@ -202,9 +203,9 @@ void shutdown() noexcept;
|
|||
const TextureBind& get_texture(GX::TexMapID id) noexcept;
|
||||
|
||||
struct TextureConfig {
|
||||
GX::TextureFormat copyFmt = InvalidTextureFormat; // GXSetTexCopyDst
|
||||
GX::TextureFormat loadFmt = InvalidTextureFormat; // GXTexObj format
|
||||
bool flipUV = false; // For render textures
|
||||
GX::TextureFormat copyFmt = InvalidTextureFormat; // Underlying texture format
|
||||
GX::TextureFormat loadFmt = InvalidTextureFormat; // Texture format being bound
|
||||
bool renderTex = false; // Perform conversion / flip UVs
|
||||
u8 _p1 = 0;
|
||||
u8 _p2 = 0;
|
||||
u8 _p3 = 0;
|
||||
|
@ -225,7 +226,7 @@ struct ShaderConfig {
|
|||
};
|
||||
static_assert(std::has_unique_object_representations_v<ShaderConfig>);
|
||||
|
||||
constexpr u32 GXPipelineConfigVersion = 3;
|
||||
constexpr u32 GXPipelineConfigVersion = 4;
|
||||
struct PipelineConfig {
|
||||
u32 version = GXPipelineConfigVersion;
|
||||
ShaderConfig shaderConfig;
|
||||
|
@ -236,8 +237,7 @@ struct PipelineConfig {
|
|||
GX::BlendFactor blendFacSrc, blendFacDst;
|
||||
GX::LogicOp blendOp;
|
||||
u32 dstAlpha;
|
||||
bool depthCompare, depthUpdate, alphaUpdate;
|
||||
u8 _pad = 0;
|
||||
bool depthCompare, depthUpdate, alphaUpdate, colorUpdate;
|
||||
};
|
||||
static_assert(std::has_unique_object_representations_v<PipelineConfig>);
|
||||
|
||||
|
|
|
@ -564,6 +564,7 @@ static inline std::string vtx_attr(const ShaderConfig& config, GX::Attr attr) {
|
|||
|
||||
static inline std::string texture_conversion(const TextureConfig& tex, u32 stageIdx, u32 texMapId) {
|
||||
std::string out;
|
||||
if (tex.renderTex)
|
||||
switch (tex.copyFmt) {
|
||||
default:
|
||||
break;
|
||||
|
@ -573,13 +574,12 @@ static inline std::string texture_conversion(const TextureConfig& tex, u32 stage
|
|||
break;
|
||||
case GX::TF_I4:
|
||||
case GX::TF_I8:
|
||||
// Perform intensity conversion
|
||||
out += fmt::format(
|
||||
FMT_STRING("\n {{"
|
||||
"\n var intensity = dot(sampled{0}.rgb, vec3(0.257, 0.504, 0.098)) + 16.0 / 255.0;"
|
||||
"\n sampled{0} = vec4<f32>(intensity, 0.f, 0.f, 1.f);"
|
||||
"\n }}"),
|
||||
stageIdx);
|
||||
// FIXME HACK
|
||||
if (tex.loadFmt != GX::TF_C4 && tex.loadFmt != GX::TF_C8 && tex.loadFmt != GX::TF_C14X2) {
|
||||
// Perform intensity conversion
|
||||
out += fmt::format(FMT_STRING("\n sampled{0} = vec4<f32>(intensityF32(sampled{0}.rgb), 0.f, 0.f, 1.f);"),
|
||||
stageIdx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (tex.loadFmt) {
|
||||
|
@ -883,7 +883,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
|||
if (stage.colorOp.clamp) {
|
||||
op = fmt::format(FMT_STRING("clamp({}, vec3<f32>(0.0), vec3<f32>(1.0))"), op);
|
||||
}
|
||||
fragmentFn += fmt::format(FMT_STRING("\n {0} = vec4<f32>({1}, {0}.a);"), outReg, op);
|
||||
fragmentFn += fmt::format(FMT_STRING("\n // TEV stage {2}\n {0} = vec4<f32>({1}, {0}.a);"), outReg, op, idx);
|
||||
}
|
||||
{
|
||||
std::string outReg;
|
||||
|
@ -1033,7 +1033,6 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
|||
Log.report(logvisor::Fatal, FMT_STRING("unhandled tcg src {} for "), tcg.src);
|
||||
unreachable();
|
||||
}
|
||||
// TODO this all assumes MTX3x4 currently
|
||||
if (tcg.mtx == GX::IDENTITY) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n var tc{0}_tmp = tc{0}.xyz;"), i);
|
||||
} else {
|
||||
|
@ -1069,9 +1068,11 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
|||
uvIn = fmt::format(FMT_STRING("in.tex{0}_uv"), stage.texCoordId);
|
||||
// }
|
||||
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||
bool isPaletted =
|
||||
texConfig.copyFmt == GX::TF_C4 || texConfig.copyFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2;
|
||||
fragmentFnPre +=
|
||||
fmt::format(FMT_STRING("\n var sampled{0} = textureSamplePalette(tex{1}, tex{1}_samp, {2}, tlut{1});"),
|
||||
i, stage.texMapId, uvIn);
|
||||
fmt::format(FMT_STRING("\n var sampled{0} = textureSamplePalette{3}(tex{1}, tex{1}_samp, {2}, tlut{1});"),
|
||||
i, stage.texMapId, uvIn, isPaletted ? ""sv : "RGB"sv);
|
||||
} else {
|
||||
fragmentFnPre += fmt::format(
|
||||
FMT_STRING("\n var sampled{0} = textureSampleBias(tex{1}, tex{1}_samp, {2}, ubuf.tex{1}_lod);"), i,
|
||||
|
@ -1111,7 +1112,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
|||
"}";
|
||||
uniBufAttrs += "\n fog: Fog,";
|
||||
|
||||
fragmentFn += "\n var fogF = clamp((ubuf.fog.a / (ubuf.fog.b - in.pos.z)) - ubuf.fog.c, 0.0, 1.0);";
|
||||
fragmentFn += "\n // Fog\n var fogF = clamp((ubuf.fog.a / (ubuf.fog.b - in.pos.z)) - ubuf.fog.c, 0.0, 1.0);";
|
||||
switch (config.fogType) {
|
||||
case GX::FOG_PERSP_LIN:
|
||||
case GX::FOG_ORTHO_LIN:
|
||||
|
@ -1154,9 +1155,11 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
|||
|
||||
const auto& texConfig = config.textureConfig[i];
|
||||
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||
bool isPaletted =
|
||||
texConfig.copyFmt == GX::TF_C4 || texConfig.copyFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2;
|
||||
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
||||
"var tex{}: texture_2d<i32>;"),
|
||||
texBindIdx, i);
|
||||
"var tex{}: texture_2d<{}>;"),
|
||||
texBindIdx, i, isPaletted ? "i32"sv : "f32"sv);
|
||||
++texBindIdx;
|
||||
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
||||
"var tlut{}: texture_2d<f32>;"),
|
||||
|
@ -1175,6 +1178,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
|||
std::string comp0 = alpha_compare(config.alphaCompare.comp0, config.alphaCompare.ref0, comp0Valid);
|
||||
std::string comp1 = alpha_compare(config.alphaCompare.comp1, config.alphaCompare.ref1, comp1Valid);
|
||||
if (comp0Valid || comp1Valid) {
|
||||
fragmentFn += "\n // Alpha compare";
|
||||
switch (config.alphaCompare.op) {
|
||||
case GX::AOP_AND:
|
||||
fragmentFn += fmt::format(FMT_STRING("\n if (!({} && {})) {{ discard; }}"), comp0, comp1);
|
||||
|
@ -1212,17 +1216,48 @@ struct VertexOutput {{
|
|||
@builtin(position) pos: vec4<f32>,{vtxOutAttrs}
|
||||
}};
|
||||
|
||||
fn intensityF32(rgb: vec3<f32>) -> f32 {{
|
||||
// RGB to intensity conversion
|
||||
// https://github.com/dolphin-emu/dolphin/blob/4cd48e609c507e65b95bca5afb416b59eaf7f683/Source/Core/VideoCommon/TextureConverterShaderGen.cpp#L237-L241
|
||||
return dot(rgb, vec3(0.257, 0.504, 0.098)) + 16.0 / 255.0;
|
||||
}}
|
||||
fn intensityI32(rgb: vec3<f32>) -> i32 {{
|
||||
return i32(dot(rgb, vec3(0.257, 0.504, 0.098)) * 255.f);
|
||||
}}
|
||||
fn textureSamplePalette(tex: texture_2d<i32>, samp: sampler, uv: vec2<f32>, tlut: texture_2d<f32>) -> vec4<f32> {{
|
||||
var f = fract(uv * vec2<f32>(textureDimensions(tex)) + 0.5);
|
||||
// Gather index values
|
||||
var i = textureGather(0, tex, samp, uv);
|
||||
var sX = textureLoad(tlut, vec2<i32>(i.x, 0), 0);
|
||||
var sY = textureLoad(tlut, vec2<i32>(i.y, 0), 0);
|
||||
var sZ = textureLoad(tlut, vec2<i32>(i.z, 0), 0);
|
||||
var sW = textureLoad(tlut, vec2<i32>(i.w, 0), 0);
|
||||
// Bilinear filtering
|
||||
var tA = mix(sW, sZ, f.x);
|
||||
var tB = mix(sX, sY, f.x);
|
||||
return mix(tA, tB, f.y);
|
||||
// Load palette colors
|
||||
var c0 = textureLoad(tlut, vec2<i32>(i[0], 0), 0);
|
||||
var c1 = textureLoad(tlut, vec2<i32>(i[1], 0), 0);
|
||||
var c2 = textureLoad(tlut, vec2<i32>(i[2], 0), 0);
|
||||
var c3 = textureLoad(tlut, vec2<i32>(i[3], 0), 0);
|
||||
// Perform bilinear filtering
|
||||
var f = fract(uv * vec2<f32>(textureDimensions(tex)) + 0.5);
|
||||
var t0 = mix(c3, c2, f.x);
|
||||
var t1 = mix(c0, c1, f.x);
|
||||
return mix(t0, t1, f.y);
|
||||
}}
|
||||
fn textureSamplePaletteRGB(tex: texture_2d<f32>, samp: sampler, uv: vec2<f32>, tlut: texture_2d<f32>) -> vec4<f32> {{
|
||||
// Gather RGB channels
|
||||
var iR = textureGather(0, tex, samp, uv);
|
||||
var iG = textureGather(1, tex, samp, uv);
|
||||
var iB = textureGather(2, tex, samp, uv);
|
||||
// Perform intensity conversion
|
||||
var i0 = intensityI32(vec3<f32>(iR[0], iG[0], iB[0]));
|
||||
var i1 = intensityI32(vec3<f32>(iR[1], iG[1], iB[1]));
|
||||
var i2 = intensityI32(vec3<f32>(iR[2], iG[2], iB[2]));
|
||||
var i3 = intensityI32(vec3<f32>(iR[3], iG[3], iB[3]));
|
||||
// Load palette colors
|
||||
var c0 = textureLoad(tlut, vec2<i32>(i0, 0), 0);
|
||||
var c1 = textureLoad(tlut, vec2<i32>(i1, 0), 0);
|
||||
var c2 = textureLoad(tlut, vec2<i32>(i2, 0), 0);
|
||||
var c3 = textureLoad(tlut, vec2<i32>(i3, 0), 0);
|
||||
// Perform bilinear filtering
|
||||
var f = fract(uv * vec2<f32>(textureDimensions(tex)) + 0.5);
|
||||
var t0 = mix(c3, c2, f.x);
|
||||
var t1 = mix(c0, c1, f.x);
|
||||
return mix(t0, t1, f.y);
|
||||
}}
|
||||
|
||||
@stage(vertex)
|
||||
|
|
|
@ -71,18 +71,20 @@ TextureHandle new_static_texture_2d(uint32_t width, uint32_t height, uint32_t mi
|
|||
offset + dataSize, data.size());
|
||||
unreachable();
|
||||
}
|
||||
const auto dstView = wgpu::ImageCopyTexture{
|
||||
auto dstView = wgpu::ImageCopyTexture{
|
||||
.texture = ref.texture,
|
||||
.mipLevel = mip,
|
||||
};
|
||||
const auto range = push_texture_data(data.data() + offset, dataSize, bytesPerRow, heightBlocks);
|
||||
const auto dataLayout = wgpu::TextureDataLayout{
|
||||
.offset = range.offset,
|
||||
.bytesPerRow = bytesPerRow,
|
||||
.rowsPerImage = heightBlocks,
|
||||
};
|
||||
g_queue.WriteTexture(&dstView, data.data() + offset, dataSize, &dataLayout, &physicalSize);
|
||||
g_textureUploads.emplace_back(dataLayout, std::move(dstView), physicalSize);
|
||||
offset += dataSize;
|
||||
}
|
||||
if (offset < data.size()) {
|
||||
if (data.size() != UINT32_MAX && offset < data.size()) {
|
||||
Log.report(logvisor::Warning, FMT_STRING("new_static_texture_2d[{}]: texture used {} bytes, but given {} bytes"),
|
||||
label, offset, data.size());
|
||||
}
|
||||
|
@ -112,7 +114,8 @@ TextureHandle new_dynamic_texture_2d(uint32_t width, uint32_t height, uint32_t m
|
|||
};
|
||||
auto texture = g_device.CreateTexture(&textureDescriptor);
|
||||
auto textureView = texture.CreateView(&textureViewDescriptor);
|
||||
return std::make_shared<TextureRef>(std::move(texture), std::move(textureView), size, wgpuFormat, mips, format, false);
|
||||
return std::make_shared<TextureRef>(std::move(texture), std::move(textureView), size, wgpuFormat, mips, format,
|
||||
false);
|
||||
}
|
||||
|
||||
TextureHandle new_render_texture(uint32_t width, uint32_t height, GX::TextureFormat fmt, zstring_view label) noexcept {
|
||||
|
@ -167,18 +170,20 @@ void write_texture(const TextureRef& ref, ArrayRef<uint8_t> data) noexcept {
|
|||
data.size());
|
||||
unreachable();
|
||||
}
|
||||
const auto dstView = wgpu::ImageCopyTexture{
|
||||
auto dstView = wgpu::ImageCopyTexture{
|
||||
.texture = ref.texture,
|
||||
.mipLevel = mip,
|
||||
};
|
||||
const auto range = push_texture_data(data.data() + offset, dataSize, bytesPerRow, heightBlocks);
|
||||
const auto dataLayout = wgpu::TextureDataLayout{
|
||||
.offset = range.offset,
|
||||
.bytesPerRow = bytesPerRow,
|
||||
.rowsPerImage = heightBlocks,
|
||||
};
|
||||
g_queue.WriteTexture(&dstView, data.data() + offset, dataSize, &dataLayout, &physicalSize);
|
||||
g_textureUploads.emplace_back(dataLayout, std::move(dstView), physicalSize);
|
||||
offset += dataSize;
|
||||
}
|
||||
if (offset < data.size()) {
|
||||
if (data.size() != UINT32_MAX && offset < data.size()) {
|
||||
Log.report(logvisor::Warning, FMT_STRING("write_texture: texture used {} bytes, but given {} bytes"), offset,
|
||||
data.size());
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ TextureWithSampler create_render_texture(bool multisampled) {
|
|||
}
|
||||
const auto textureDescriptor = wgpu::TextureDescriptor{
|
||||
.label = "Render texture",
|
||||
.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst,
|
||||
.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
|
||||
wgpu::TextureUsage::CopyDst,
|
||||
.size = size,
|
||||
.format = format,
|
||||
.sampleCount = sampleCount,
|
||||
|
@ -230,27 +231,54 @@ static void error_callback(WGPUErrorType type, char const* message, void* userda
|
|||
magic_enum::enum_name(static_cast<wgpu::ErrorType>(type)), message);
|
||||
}
|
||||
|
||||
void initialize(SDL_Window* window) {
|
||||
Log.report(logvisor::Info, FMT_STRING("Creating Dawn instance"));
|
||||
g_Instance = std::make_unique<dawn::native::Instance>();
|
||||
#if !defined(NDEBUG)
|
||||
// D3D12's debug layer is very slow
|
||||
if (preferredBackendType != wgpu::BackendType::D3D12) {
|
||||
g_Instance->EnableBackendValidation(true);
|
||||
static void device_callback(WGPURequestDeviceStatus status, WGPUDevice device, char const* message, void* userdata) {
|
||||
if (status == WGPURequestDeviceStatus_Success) {
|
||||
g_device = wgpu::Device::Acquire(device);
|
||||
} else {
|
||||
Log.report(logvisor::Warning, FMT_STRING("Device request failed with message: {}"), message);
|
||||
}
|
||||
*static_cast<bool*>(userdata) = true;
|
||||
}
|
||||
|
||||
bool initialize(SDL_Window* window, wgpu::BackendType backendType) {
|
||||
if (!g_Instance) {
|
||||
Log.report(logvisor::Info, FMT_STRING("Creating Dawn instance"));
|
||||
g_Instance = std::make_unique<dawn::native::Instance>();
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
// D3D12's debug layer is very slow
|
||||
// g_Instance->EnableBackendValidation(backendType != wgpu::BackendType::D3D12);
|
||||
#endif
|
||||
utils::DiscoverAdapter(g_Instance.get(), window, preferredBackendType);
|
||||
if (!utils::DiscoverAdapter(g_Instance.get(), window, backendType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<dawn::native::Adapter> adapters = g_Instance->GetAdapters();
|
||||
const auto adapterIt = std::find_if(adapters.begin(), adapters.end(), [](const auto& adapter) -> bool {
|
||||
std::sort(adapters.begin(), adapters.end(), [&](const auto& a, const auto& b) {
|
||||
wgpu::AdapterProperties propertiesA;
|
||||
wgpu::AdapterProperties propertiesB;
|
||||
a.GetProperties(&propertiesA);
|
||||
b.GetProperties(&propertiesB);
|
||||
constexpr std::array PreferredTypeOrder{
|
||||
wgpu::AdapterType::DiscreteGPU,
|
||||
wgpu::AdapterType::IntegratedGPU,
|
||||
wgpu::AdapterType::CPU,
|
||||
};
|
||||
const auto typeItA = std::find(PreferredTypeOrder.begin(), PreferredTypeOrder.end(), propertiesA.adapterType);
|
||||
const auto typeItB = std::find(PreferredTypeOrder.begin(), PreferredTypeOrder.end(), propertiesB.adapterType);
|
||||
if (typeItA == PreferredTypeOrder.end() && typeItB != PreferredTypeOrder.end()) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(typeItA - typeItB);
|
||||
});
|
||||
const auto adapterIt = std::find_if(adapters.begin(), adapters.end(), [=](const auto& adapter) -> bool {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
return properties.backendType == preferredBackendType;
|
||||
return properties.backendType == backendType;
|
||||
});
|
||||
if (adapterIt == adapters.end()) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Failed to find usable graphics backend"));
|
||||
unreachable();
|
||||
return false;
|
||||
}
|
||||
g_Adapter = *adapterIt;
|
||||
}
|
||||
|
@ -276,9 +304,13 @@ void initialize(SDL_Window* window) {
|
|||
: supportedLimits.limits.minStorageBufferOffsetAlignment,
|
||||
},
|
||||
};
|
||||
const std::array<wgpu::FeatureName, 1> requiredFeatures{
|
||||
wgpu::FeatureName::TextureCompressionBC,
|
||||
};
|
||||
std::vector<wgpu::FeatureName> features;
|
||||
const auto supportedFeatures = g_Adapter.GetSupportedFeatures();
|
||||
for (const auto* const feature : supportedFeatures) {
|
||||
if (strcmp(feature, "texture-compression-bc") == 0) {
|
||||
features.push_back(wgpu::FeatureName::TextureCompressionBC);
|
||||
}
|
||||
}
|
||||
const std::array enableToggles {
|
||||
/* clang-format off */
|
||||
#if _WIN32
|
||||
|
@ -297,11 +329,18 @@ void initialize(SDL_Window* window) {
|
|||
togglesDescriptor.forceEnabledToggles = enableToggles.data();
|
||||
const auto deviceDescriptor = wgpu::DeviceDescriptor{
|
||||
.nextInChain = &togglesDescriptor,
|
||||
.requiredFeaturesCount = requiredFeatures.size(),
|
||||
.requiredFeatures = requiredFeatures.data(),
|
||||
.requiredFeaturesCount = static_cast<uint32_t>(features.size()),
|
||||
.requiredFeatures = features.data(),
|
||||
.requiredLimits = &requiredLimits,
|
||||
};
|
||||
g_device = wgpu::Device::Acquire(g_Adapter.CreateDevice(&deviceDescriptor));
|
||||
bool deviceCallbackReceived = false;
|
||||
g_Adapter.RequestDevice(&deviceDescriptor, &device_callback, &deviceCallbackReceived);
|
||||
// while (!deviceCallbackReceived) {
|
||||
// TODO wgpuInstanceProcessEvents
|
||||
// }
|
||||
if (!g_device) {
|
||||
return false;
|
||||
}
|
||||
g_device.SetUncapturedErrorCallback(&error_callback, nullptr);
|
||||
}
|
||||
g_queue = g_device.GetQueue();
|
||||
|
@ -309,8 +348,7 @@ void initialize(SDL_Window* window) {
|
|||
g_BackendBinding =
|
||||
std::unique_ptr<utils::BackendBinding>(utils::CreateBinding(g_backendType, window, g_device.Get()));
|
||||
if (!g_BackendBinding) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Unsupported backend {}"), backendName);
|
||||
unreachable();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto swapChainFormat = static_cast<wgpu::TextureFormat>(g_BackendBinding->GetPreferredSwapChainTextureFormat());
|
||||
|
@ -341,9 +379,13 @@ void initialize(SDL_Window* window) {
|
|||
resize_swapchain(size.fb_width, size.fb_height);
|
||||
g_windowSize = size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
g_CopyBindGroupLayout = {};
|
||||
g_CopyPipeline = {};
|
||||
g_CopyBindGroup = {};
|
||||
g_frameBuffer = {};
|
||||
g_frameBufferResolved = {};
|
||||
g_depthBuffer = {};
|
||||
|
|
|
@ -31,15 +31,24 @@ struct TextureWithSampler {
|
|||
wgpu::Sampler sampler;
|
||||
};
|
||||
|
||||
constexpr std::array PreferredBackendOrder{
|
||||
#ifdef DAWN_ENABLE_BACKEND_D3D12
|
||||
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::D3D12;
|
||||
#elif DAWN_ENABLE_BACKEND_VULKAN
|
||||
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::Vulkan;
|
||||
#elif DAWN_ENABLE_BACKEND_METAL
|
||||
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::Metal;
|
||||
#else
|
||||
static const wgpu::BackendType preferredBackendType = wgpu::BackendType::OpenGL;
|
||||
wgpu::BackendType::D3D12,
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_METAL
|
||||
wgpu::BackendType::Metal,
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||
wgpu::BackendType::Vulkan,
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_DESKTOP_GL
|
||||
wgpu::BackendType::OpenGL,
|
||||
#endif
|
||||
#ifdef DAWN_ENABLE_BACKEND_OPENGLES
|
||||
wgpu::BackendType::OpenGLES,
|
||||
#endif
|
||||
};
|
||||
|
||||
extern wgpu::Device g_device;
|
||||
extern wgpu::Queue g_queue;
|
||||
extern wgpu::SwapChain g_swapChain;
|
||||
|
@ -51,7 +60,7 @@ extern TextureWithSampler g_depthBuffer;
|
|||
extern wgpu::RenderPipeline g_CopyPipeline;
|
||||
extern wgpu::BindGroup g_CopyBindGroup;
|
||||
|
||||
void initialize(SDL_Window* window);
|
||||
bool initialize(SDL_Window* window, wgpu::BackendType backendType);
|
||||
void shutdown();
|
||||
void resize_swapchain(uint32_t width, uint32_t height);
|
||||
TextureWithSampler create_render_texture(bool multisampled);
|
||||
|
|
|
@ -98,6 +98,7 @@ if (NOT MSVC)
|
|||
target_compile_options(SDL2-static PRIVATE -Wno-implicit-fallthrough -Wno-shadow)
|
||||
endif ()
|
||||
|
||||
set(DAWN_ENABLE_VULKAN ON CACHE BOOL "Enable compilation of the Vulkan backend" FORCE)
|
||||
add_subdirectory(../extern/dawn dawn EXCLUDE_FROM_ALL)
|
||||
if (DAWN_ENABLE_VULKAN)
|
||||
target_compile_definitions(dawn_native PRIVATE
|
||||
|
|
Loading…
Reference in New Issue