2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 23:11:20 +00:00
metaforce/Runtime/World/CWorldShadow.cpp
Lioncash 221cc5c6b8 RuntimeCommonB: Normalize cpp file includes
Like the prior changes normalizing the inclusions within headers, this
tackles the cpp files of the RuntimeCommonB target, making these source
files consistent with their headers.
2019-12-22 18:12:04 -05:00

116 lines
4.5 KiB
C++

#include "Runtime/World/CWorldShadow.hpp"
#include "Runtime/CStateManager.hpp"
#include "Runtime/Graphics/CBooRenderer.hpp"
#include "Runtime/World/CWorld.hpp"
namespace urde {
CWorldShadow::CWorldShadow(u32 w, u32 h, bool rgba8) : m_shader(w, h) {}
void CWorldShadow::EnableModelProjectedShadow(const zeus::CTransform& pos, s32 lightIdx, float f1) {
zeus::CTransform texTransform = zeus::lookAt(zeus::skZero3f, x74_lightPos - x68_objPos);
zeus::CTransform posXf = pos;
posXf.origin = zeus::skZero3f;
texTransform = posXf.inverse() * texTransform;
texTransform = (texTransform * zeus::CTransform::Scale(float(M_SQRT2) * x64_objHalfExtent * f1)).inverse();
texTransform = zeus::CTransform::Translate(0.5f, 0.f, 0.5f) * texTransform;
CBooModel::EnableShadowMaps(m_shader.GetTexture().get(), texTransform);
#if CWORLDSHADOW_FEEDBACK
if (!m_feedback)
m_feedback.emplace(EFilterType::Blend, m_shader.GetTexture().get());
zeus::CRectangle rect(0.4f, 0.4f, 0.2f, 0.2f);
m_feedback->draw(zeus::skWhite, 1.f, rect);
#endif
}
void CWorldShadow::DisableModelProjectedShadow() { CBooModel::DisableShadowMaps(); }
void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, s32 lightIdx,
const zeus::CAABox& aabb, bool motionBlur, bool lighten) {
if (x80_aid != aid || x84_lightIdx != lightIdx) {
x88_blurReset = true;
x80_aid = aid;
x84_lightIdx = lightIdx;
}
if (aid != kInvalidAreaId) {
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(aid);
if (area->IsPostConstructed()) {
const CWorldLight& light = area->GetPostConstructed()->x60_lightsA[lightIdx];
zeus::CVector3f centerPoint = aabb.center();
if (const CPVSAreaSet* pvs = area->GetAreaVisSet()) {
CPVSVisSet lightSet = pvs->Get1stLightSet(lightIdx);
g_Renderer->EnablePVS(lightSet, aid);
} else {
CPVSVisSet visSet;
visSet.Reset(EPVSVisSetState::OutOfBounds);
g_Renderer->EnablePVS(visSet, aid);
}
zeus::CVector3f lightToPoint = centerPoint - light.GetPosition();
x64_objHalfExtent = (aabb.max - centerPoint).magnitude();
float distance = lightToPoint.magnitude();
float fov = zeus::radToDeg(std::atan2(x64_objHalfExtent, distance)) * 2.f;
if (fov >= 0.00001f) {
lightToPoint.normalize();
x4_view = zeus::lookAt(light.GetPosition(), centerPoint, zeus::skDown);
x68_objPos = centerPoint;
x74_lightPos = light.GetPosition();
CGraphics::SetViewPointMatrix(x4_view);
zeus::CFrustum frustum;
frustum.updatePlanes(x4_view, zeus::SProjPersp(zeus::degToRad(fov), 1.f, 0.1f, distance + x64_objHalfExtent));
g_Renderer->SetClippingPlanes(frustum);
g_Renderer->SetPerspective(fov, m_shader.GetWidth(), m_shader.GetHeight(), 0.1f, 1000.f);
SViewport backupVp = g_Viewport;
zeus::CVector2f backupDepthRange = CGraphics::g_CachedDepthRange;
m_shader.bindRenderTarget();
g_Renderer->SetViewport(0, 0, m_shader.GetWidth(), m_shader.GetHeight());
CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR);
x34_model = zeus::lookAt(centerPoint - zeus::CVector3f(0.f, 0.f, 0.1f), light.GetPosition());
CGraphics::SetModelMatrix(x34_model);
float extent = float(M_SQRT2) * x64_objHalfExtent;
/* Depth test and write */
/* Color white 100% alpha */
m_shader.drawBase(extent);
CGraphics::SetModelMatrix(zeus::CTransform());
CBooModel::SetDrawingOccluders(true);
g_Renderer->PrepareDynamicLights({});
g_Renderer->UpdateAreaUniforms(aid, EWorldShadowMode::WorldOnActorShadow);
g_Renderer->DrawUnsortedGeometry(aid, 0, 0, true);
CBooModel::SetDrawingOccluders(false);
if (lighten) {
CGraphics::SetModelMatrix(x34_model);
/* No depth test or write */
/* Color white 25% alpha */
m_shader.lightenShadow();
}
if (motionBlur && !x88_blurReset) {
/* No depth test or write */
/* Color white 85% alpha */
/* Draw in shadow texture */
m_shader.blendPreviousShadow();
}
x88_blurReset = false;
m_shader.resolveTexture();
CBooRenderer::BindMainDrawTarget();
g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
CGraphics::SetDepthRange(backupDepthRange[0], backupDepthRange[1]);
}
}
}
}
void CWorldShadow::ResetBlur() { x88_blurReset = true; }
} // namespace urde