metaforce/Runtime/Camera/CCameraFilter.cpp

259 lines
7.5 KiB
C++
Raw Normal View History

2016-08-17 13:05:23 -07:00
#include "Graphics/CGraphics.hpp"
2016-08-16 18:58:53 -07:00
#include "CCameraFilter.hpp"
#include "GameGlobalObjects.hpp"
#include "Graphics/CBooRenderer.hpp"
2016-08-19 21:22:13 -07:00
#include "CSimplePool.hpp"
2017-05-31 22:34:24 -07:00
#include "Graphics/Shaders/CColoredQuadFilter.hpp"
#include "Graphics/Shaders/CTexturedQuadFilter.hpp"
#include "Graphics/Shaders/CScanLinesFilter.hpp"
#include "Graphics/Shaders/CRandomStaticFilter.hpp"
2016-08-16 18:58:53 -07:00
namespace urde
{
2017-05-31 22:34:24 -07:00
template <class S>
void CCameraFilterPass<S>::Update(float dt)
2017-03-23 22:30:16 -07:00
{
2017-05-31 22:34:24 -07:00
if (x10_remTime <= 0.f)
return;
EFilterType origType = x0_curType;
x10_remTime = std::max(0.f, x10_remTime - dt);
x18_curColor = zeus::CColor::lerp(x1c_nextColor, x14_prevColor, x10_remTime / xc_duration);
if (x10_remTime == 0.f)
{
x0_curType = x4_nextType;
if (x0_curType == EFilterType::Passthru)
{
x24_texObj = TLockedToken<CTexture>();
2017-11-14 20:12:13 -08:00
x20_nextTxtr = {};
2017-05-31 22:34:24 -07:00
}
}
2017-03-23 22:30:16 -07:00
2017-05-31 22:34:24 -07:00
if (x0_curType == EFilterType::Passthru)
m_shader = std::experimental::nullopt;
else if (x0_curType != origType)
m_shader.emplace(x0_curType, x24_texObj);
2017-03-23 22:30:16 -07:00
}
2017-05-31 22:34:24 -07:00
template <class S>
void CCameraFilterPass<S>::SetFilter(EFilterType type, EFilterShape shape,
2017-08-12 22:26:14 -07:00
float time, const zeus::CColor& color, CAssetId txtr)
2016-08-16 18:58:53 -07:00
{
2017-05-31 22:34:24 -07:00
if (time == 0.f)
2016-08-16 18:58:53 -07:00
{
2017-05-31 22:34:24 -07:00
xc_duration = 0.f;
x10_remTime = 0.f;
2017-11-14 20:12:13 -08:00
if (txtr.IsValid())
2017-05-31 22:34:24 -07:00
x24_texObj = g_SimplePool->GetObj({FOURCC('TXTR'), txtr});
if (type == EFilterType::Passthru)
m_shader = std::experimental::nullopt;
2017-11-14 20:12:13 -08:00
else if (x0_curType != type || (x20_nextTxtr != txtr && txtr.IsValid()))
2017-05-31 22:34:24 -07:00
m_shader.emplace(type, x24_texObj);
x4_nextType = type;
x0_curType = type;
x8_shape = shape;
x1c_nextColor = color;
x18_curColor = color;
x14_prevColor = color;
x20_nextTxtr = txtr;
2016-08-16 18:58:53 -07:00
}
2017-05-31 22:34:24 -07:00
else
{
EFilterType origType = x0_curType;
2017-08-12 22:26:14 -07:00
CAssetId origTxtr = x20_nextTxtr;
2017-05-31 22:34:24 -07:00
x1c_nextColor = color;
x14_prevColor = x18_curColor;
x8_shape = shape;
x20_nextTxtr = txtr;
2017-11-14 20:12:13 -08:00
if (txtr.IsValid())
2017-05-31 22:34:24 -07:00
x24_texObj = g_SimplePool->GetObj({FOURCC('TXTR'), txtr});
x10_remTime = time;
xc_duration = time;
x0_curType = x4_nextType;
x4_nextType = type;
if (type == EFilterType::Passthru)
{
if (x0_curType == EFilterType::Multiply)
x1c_nextColor = zeus::CColor::skWhite;
else if (x0_curType == EFilterType::Add || x0_curType == EFilterType::Blend)
2018-12-07 17:49:15 -08:00
x1c_nextColor.a() = 0.f;
2017-05-31 22:34:24 -07:00
}
else
{
if (x0_curType == EFilterType::Passthru)
{
if (type == EFilterType::Multiply)
{
x18_curColor = zeus::CColor::skWhite;
}
else if (type == EFilterType::Add || type == EFilterType::Blend)
{
x18_curColor = x1c_nextColor;
2018-12-07 17:49:15 -08:00
x18_curColor.a() = 0.f;
2017-05-31 22:34:24 -07:00
x14_prevColor = x18_curColor;
}
}
x0_curType = x4_nextType;
}
if (x0_curType == EFilterType::Passthru)
m_shader = std::experimental::nullopt;
2017-11-14 20:12:13 -08:00
else if (x0_curType != origType || (x20_nextTxtr != origTxtr && x20_nextTxtr.IsValid()))
2017-05-31 22:34:24 -07:00
m_shader.emplace(x0_curType, x24_texObj);
}
}
template <class S>
void CCameraFilterPass<S>::DisableFilter(float time)
{
SetFilter(EFilterType::Passthru, x8_shape, time, zeus::CColor::skWhite, -1);
}
template <class S>
void CCameraFilterPass<S>::Draw() const
{
if (m_shader)
const_cast<S&>(*m_shader).DrawFilter(x8_shape, x18_curColor,
GetT(x4_nextType == EFilterType::Passthru));
2016-08-16 18:58:53 -07:00
}
2017-05-31 22:34:24 -07:00
float CCameraFilterPassBase::GetT(bool invert) const
2016-08-16 18:58:53 -07:00
{
2017-05-31 22:34:24 -07:00
float tmp;
if (xc_duration == 0.f)
tmp = 1.f;
else
tmp = 1.f - x10_remTime / xc_duration;
if (invert)
return 1.f - tmp;
return tmp;
}
void CCameraFilterPassPoly::SetFilter(EFilterType type, EFilterShape shape,
2017-08-12 22:26:14 -07:00
float time, const zeus::CColor& color, CAssetId txtr)
2017-05-31 22:34:24 -07:00
{
if (!m_filter || m_shape != shape)
{
m_shape = shape;
switch (shape)
{
case EFilterShape::Fullscreen:
case EFilterShape::FullscreenHalvesLeftRight:
case EFilterShape::FullscreenHalvesTopBottom:
case EFilterShape::FullscreenQuarters:
2017-11-14 20:12:13 -08:00
if (txtr.IsValid())
2017-05-31 22:34:24 -07:00
m_filter = std::make_unique<CCameraFilterPass<CTexturedQuadFilterAlpha>>();
else
m_filter = std::make_unique<CCameraFilterPass<CColoredQuadFilter>>();
break;
case EFilterShape::CinemaBars:
m_filter = std::make_unique<CCameraFilterPass<CWideScreenFilter>>();
break;
case EFilterShape::ScanLinesEven:
m_filter = std::make_unique<CCameraFilterPass<CScanLinesFilterEven>>();
break;
2017-05-31 22:34:24 -07:00
case EFilterShape::ScanLinesOdd:
m_filter = std::make_unique<CCameraFilterPass<CScanLinesFilterOdd>>();
2017-05-31 22:34:24 -07:00
break;
case EFilterShape::RandomStatic:
m_filter = std::make_unique<CCameraFilterPass<CRandomStaticFilter>>();
break;
case EFilterShape::CookieCutterDepthRandomStatic:
m_filter = std::make_unique<CCameraFilterPass<CCookieCutterDepthRandomStaticFilter>>();
break;
default: break;
}
}
if (m_filter)
m_filter->SetFilter(type, shape, time, color, txtr);
2016-08-16 18:58:53 -07:00
}
2018-01-05 22:50:42 -08:00
void CCameraBlurPass::Draw(bool clearDepth)
2016-08-19 21:22:13 -07:00
{
if (x10_curType == EBlurType::NoBlur)
return;
if (x10_curType == EBlurType::Xray)
{
2017-11-16 00:05:10 -08:00
if (!m_xrayShader)
m_xrayShader.emplace(x0_paletteTex);
m_xrayShader->draw(x1c_curValue);
2016-08-19 21:22:13 -07:00
}
2016-08-20 11:18:44 -07:00
else
{
2017-11-16 00:05:10 -08:00
if (!m_shader)
m_shader.emplace();
2018-01-05 22:50:42 -08:00
m_shader->draw(x1c_curValue, clearDepth);
if (clearDepth)
CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR);
2016-08-20 11:18:44 -07:00
}
2016-08-19 21:22:13 -07:00
}
void CCameraBlurPass::Update(float dt)
{
if (x28_remainingTime > 0.f)
{
x28_remainingTime = std::max(x28_remainingTime - dt, 0.f);
x1c_curValue = x18_endValue + (x20_startValue - x18_endValue) * x28_remainingTime / x24_totalTime;
if (x28_remainingTime != 0.f)
return;
x10_curType = x14_endType;
}
}
void CCameraBlurPass::SetBlur(EBlurType type, float amount, float duration)
{
if (duration == 0.f)
{
x24_totalTime = 0.f;
x28_remainingTime = 0.f;
x18_endValue = amount;
x1c_curValue = amount;
x20_startValue = amount;
if (x10_curType == EBlurType::NoBlur)
{
if (type == EBlurType::Xray)
x0_paletteTex = g_SimplePool->GetObj("TXTR_XRayPalette");
}
x14_endType = type;
x10_curType = type;
//x2c_usePersistent = b1;
}
else
{
//x2c_usePersistent = b1;
x24_totalTime = duration;
x28_remainingTime = duration;
x18_endValue = x1c_curValue;
x20_startValue = amount;
if (type != x14_endType)
{
if (x10_curType == EBlurType::NoBlur)
{
if (type == EBlurType::Xray)
x0_paletteTex = g_SimplePool->GetObj("TXTR_XRayPalette");
x10_curType = type;
}
x14_endType = type;
}
}
}
void CCameraBlurPass::DisableBlur(float duration)
{
SetBlur(EBlurType::NoBlur, 0.f, duration);
}
2016-08-16 18:58:53 -07:00
}