Refactored widescreen filter to set renderer viewport as well

This commit is contained in:
Jack Andersen 2016-09-02 13:37:02 -10:00
parent 4fdf84d6b8
commit ce3014b313
11 changed files with 113 additions and 54 deletions

View File

@ -28,6 +28,7 @@ zeus::CTransform CGraphics::g_GXViewPointMatrix;
zeus::CTransform CGraphics::g_CameraMatrix;
zeus::CVector2i CGraphics::g_ViewportResolution;
zeus::CVector2i CGraphics::g_ViewportResolutionHalf;
SClipScreenRect CGraphics::g_CroppedViewport;
int CGraphics::g_ViewportSamples = 1;
bool CGraphics::g_IsGXModelMatrixIdentity = true;
@ -398,6 +399,9 @@ zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const zeus::CVector3
void CGraphics::SetViewportResolution(const zeus::CVector2i& res)
{
g_ViewportResolution = res;
g_CroppedViewport = SClipScreenRect();
g_CroppedViewport.xc_width = res.x;
g_CroppedViewport.x10_height = res.y;
g_ViewportResolutionHalf = {res.x / 2, res.y / 2};
}

View File

@ -141,16 +141,31 @@ enum class ERglFogMode
struct SClipScreenRect
{
bool x0_valid;
int x4_left;
int x8_top;
int xc_width;
int x10_height;
int x14_dstWidth;
float x18_uvXMin;
float x1c_uvXMax;
float x20_uvYMin;
float x24_uvYMax;
bool x0_valid = false;
int x4_left = 0;
int x8_top = 0;
int xc_width = 0;
int x10_height = 0;
int x14_dstWidth = 0;
float x18_uvXMin = 0.f;
float x1c_uvXMax = 0.f;
float x20_uvYMin = 0.f;
float x24_uvYMax = 0.f;
SClipScreenRect() = default;
SClipScreenRect(bool valid, int left, int top, int width, int height, int dstWidth,
float uvXMin, float uvXMax, float uvYMin, float uvYMax)
: x0_valid(valid), x4_left(left), x8_top(top), xc_width(width), x10_height(height), x14_dstWidth(dstWidth),
x18_uvXMin(uvXMin), x1c_uvXMax(uvXMax), x20_uvYMin(uvYMin), x24_uvYMax(uvYMax) {}
SClipScreenRect(const boo::SWindowRect& rect)
{
x4_left = rect.location[0];
x8_top = rect.location[1];
xc_width = rect.size[0];
x10_height = rect.size[1];
x14_dstWidth = rect.size[0];
}
};
enum class ETexelFormat
@ -211,6 +226,7 @@ public:
static zeus::CTransform g_CameraMatrix;
static zeus::CVector2i g_ViewportResolution;
static zeus::CVector2i g_ViewportResolutionHalf;
static SClipScreenRect g_CroppedViewport;
static int g_ViewportSamples;
static bool g_IsGXModelMatrixIdentity;

View File

@ -8,18 +8,7 @@ CCameraBlurFilter::CCameraBlurFilter()
{
m_token = CGraphics::g_BooFactory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
struct Vert
{
zeus::CVector2f m_pos;
zeus::CVector2f m_uv;
} verts[4] =
{
{{-1.0, -1.0}, {0.0, 0.0}},
{{-1.0, 1.0}, {0.0, 1.0}},
{{ 1.0, -1.0}, {1.0, 0.0}},
{{ 1.0, 1.0}, {1.0, 1.0}},
};
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, 32, 4);
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4);
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
m_dataBind = TShader<CCameraBlurFilter>::BuildShaderDataBinding(ctx, *this);
return true;
@ -35,7 +24,21 @@ void CCameraBlurFilter::draw(float amount)
clipRect.xc_width = CGraphics::g_ViewportResolution.x;
clipRect.x10_height = CGraphics::g_ViewportResolution.y;
CGraphics::ResolveSpareTexture(clipRect);
float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y);
float aspect = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_CroppedViewport.x10_height);
float xFac = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_ViewportResolution.x);
float yFac = CGraphics::g_CroppedViewport.x10_height / float(CGraphics::g_ViewportResolution.y);
float xBias = CGraphics::g_CroppedViewport.x4_left / float(CGraphics::g_ViewportResolution.x);
float yBias = CGraphics::g_CroppedViewport.x8_top / float(CGraphics::g_ViewportResolution.y);
Vert verts[4] =
{
{{-1.0, -1.0}, {xBias, yBias}},
{{-1.0, 1.0}, {xBias, yBias + yFac}},
{{ 1.0, -1.0}, {xBias + xFac, yBias}},
{{ 1.0, 1.0}, {xBias + xFac, yBias + yFac}},
};
m_vbo->load(verts, sizeof(verts));
for (int i=0 ; i<6 ; ++i)
{
@ -49,8 +52,8 @@ void CCameraBlurFilter::draw(float amount)
float amtY = std::sin(tmp);
amtY *= amount / 448.f;
m_uniform.m_uv[i][0] = amtX;
m_uniform.m_uv[i][1] = amtY;
m_uniform.m_uv[i][0] = amtX * xFac;
m_uniform.m_uv[i][1] = amtY * yFac;
}
m_uniform.m_opacity = std::min(amount / 2.f, 1.f);
m_uniBuf->load(&m_uniform, sizeof(m_uniform));

View File

@ -15,13 +15,19 @@ class CCameraBlurFilter
friend struct CCameraBlurFilterMetalDataBindingFactory;
friend struct CCameraBlurFilterD3DDataBindingFactory;
struct Vert
{
zeus::CVector2f m_pos;
zeus::CVector2f m_uv;
};
struct Uniform
{
zeus::CVector4f m_uv[6];
float m_opacity = 1.f;
};
boo::GraphicsDataToken m_token;
boo::IGraphicsBufferS* m_vbo;
boo::IGraphicsBufferD* m_vbo;
boo::IGraphicsBufferD* m_uniBuf;
boo::IShaderDataBinding* m_dataBind = nullptr;
Uniform m_uniform;

View File

@ -51,6 +51,37 @@ void CWideScreenFilter::draw(const zeus::CColor& color, float t)
m_top.draw(color, rect);
}
}
float CWideScreenFilter::SetViewportToMatch(float t)
{
float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y);
if (aspect < 1.7777f)
{
float targetHeight = CGraphics::g_ViewportResolution.x / 1.7777f;
float delta = (CGraphics::g_ViewportResolution.y - targetHeight) * t / 2.f;
boo::SWindowRect rect = {};
rect.size[0] = CGraphics::g_ViewportResolution.x;
rect.size[1] = CGraphics::g_ViewportResolution.y - delta * 2.f;
rect.location[1] = delta;
CGraphics::g_CroppedViewport = rect;
CGraphics::g_BooMainCommandQueue->setViewport(rect);
return 1.7777f;
}
else
{
SetViewportToFull();
return aspect;
}
}
void CWideScreenFilter::SetViewportToFull()
{
boo::SWindowRect rect = {};
rect.size[0] = CGraphics::g_ViewportResolution.x;
rect.size[1] = CGraphics::g_ViewportResolution.y;
CGraphics::g_CroppedViewport = rect;
CGraphics::g_BooMainCommandQueue->setViewport(rect);
}
const zeus::CRectangle CColoredQuadFilter::DefaultRect = {0.f, 0.f, 1.f, 1.f};

View File

@ -45,6 +45,8 @@ public:
CWideScreenFilter(CCameraFilterPass::EFilterType type)
: m_top(type), m_bottom(type) {}
void draw(const zeus::CColor& color, float t);
static float SetViewportToMatch(float t);
static void SetViewportToFull();
};
}

View File

@ -63,20 +63,21 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt)
m_uniform.m_indXf[2][1] = 0.f;
/* Warp effect is fixed at 192x192 rectangle in original (1/2.5 viewport height) */
float aspect = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_CroppedViewport.x10_height);
m_uniform.m_matrix[1][1] = 1.f / 2.5f;
m_uniform.m_matrix[0][0] = m_uniform.m_matrix[1][1] / CGraphics::g_ProjAspect;
m_uniform.m_matrix[0][0] = m_uniform.m_matrix[1][1] / aspect;
SClipScreenRect clipRect = {};
clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0]) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.x;
if (clipRect.x4_left >= CGraphics::g_ViewportResolution.x)
clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0]) / 2.f + 0.5f) * CGraphics::g_CroppedViewport.xc_width;
if (clipRect.x4_left >= CGraphics::g_CroppedViewport.xc_width)
return;
clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1]) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.y;
if (clipRect.x8_top >= CGraphics::g_ViewportResolution.y)
clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1]) / 2.f + 0.5f) * CGraphics::g_CroppedViewport.x10_height;
if (clipRect.x8_top >= CGraphics::g_CroppedViewport.x10_height)
return;
clipRect.xc_width = CGraphics::g_ViewportResolution.x * m_uniform.m_matrix[0][0];
clipRect.xc_width = CGraphics::g_CroppedViewport.xc_width * m_uniform.m_matrix[0][0];
if (clipRect.x4_left + clipRect.xc_width <= 0)
return;
clipRect.x10_height = CGraphics::g_ViewportResolution.y * m_uniform.m_matrix[1][1];
clipRect.x10_height = CGraphics::g_CroppedViewport.x10_height * m_uniform.m_matrix[1][1];
if (clipRect.x8_top + clipRect.x10_height <= 0)
return;
@ -99,21 +100,21 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt)
}
float tmp = clipRect.x4_left + clipRect.xc_width;
if (tmp >= CGraphics::g_ViewportResolution.x)
if (tmp >= CGraphics::g_CroppedViewport.xc_width)
{
clipRect.xc_width = CGraphics::g_ViewportResolution.x - clipRect.x4_left;
clipRect.xc_width = CGraphics::g_CroppedViewport.xc_width - clipRect.x4_left;
m_uniform.m_indXf[0][0] = clipRect.xc_width / oldW;
}
tmp = clipRect.x8_top + clipRect.x10_height;
if (tmp >= CGraphics::g_ViewportResolution.y)
if (tmp >= CGraphics::g_CroppedViewport.x10_height)
{
clipRect.x10_height = CGraphics::g_ViewportResolution.y - clipRect.x8_top;
clipRect.x10_height = CGraphics::g_CroppedViewport.x10_height - clipRect.x8_top;
m_uniform.m_indXf[1][1] = clipRect.x10_height / oldH;
}
/* Transform UV coordinates of rectangle within viewport and sampled scene texels (clamped to viewport bounds) */
zeus::CVector2f vp{float(CGraphics::g_ViewportResolution.x), float(CGraphics::g_ViewportResolution.y)};
zeus::CVector2f vp{float(CGraphics::g_CroppedViewport.xc_width), float(CGraphics::g_CroppedViewport.x10_height)};
m_uniform.m_matrix[0][0] = clipRect.xc_width / vp.x;
m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y;
m_uniform.m_matrix[3][0] = pt.x + (1.f / vp.x);
@ -133,10 +134,13 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt)
clipRect.x8_top -= 1;
clipRect.x10_height += 1;
}
if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_ViewportResolution.x)
if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_CroppedViewport.xc_width)
clipRect.xc_width += 1;
if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_ViewportResolution.y)
if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_CroppedViewport.x10_height)
clipRect.x10_height += 1;
clipRect.x4_left += CGraphics::g_CroppedViewport.x4_left;
clipRect.x8_top += CGraphics::g_CroppedViewport.x8_top;
CGraphics::ResolveSpareTexture(clipRect);
m_uniform.m_strength.x = m_uniform.m_matrix[0][0] * m_strength * 0.5f *

View File

@ -54,10 +54,7 @@ void CThermalColdFilter::setShift(unsigned shift)
void CThermalColdFilter::draw()
{
SClipScreenRect clipRect = {};
clipRect.xc_width = CGraphics::g_ViewportResolution.x;
clipRect.x10_height = CGraphics::g_ViewportResolution.y;
CGraphics::ResolveSpareTexture(clipRect);
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
m_uniform.m_shiftTexMtx[0][0] = 80.f * (CGraphics::g_ProjAspect / 1.33f);
m_uniform.m_shiftTexMtx[1][1] = 120.f;

View File

@ -28,10 +28,7 @@ CThermalHotFilter::CThermalHotFilter()
void CThermalHotFilter::draw()
{
SClipScreenRect clipRect = {};
clipRect.xc_width = CGraphics::g_ViewportResolution.x;
clipRect.x10_height = CGraphics::g_ViewportResolution.y;
CGraphics::ResolveSpareTexture(clipRect);
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
//m_uniBuf->load(&m_uniform, sizeof(m_uniform));

View File

@ -31,10 +31,7 @@ CXRayBlurFilter::CXRayBlurFilter(TLockedToken<CTexture>& tex)
void CXRayBlurFilter::draw(float amount)
{
SClipScreenRect clipRect = {};
clipRect.xc_width = CGraphics::g_ViewportResolution.x;
clipRect.x10_height = CGraphics::g_ViewportResolution.y;
CGraphics::ResolveSpareTexture(clipRect);
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
float blurL = amount * 0.0014f * 0.25f;
float blurQ = amount * 0.0000525f * 0.25f;

View File

@ -220,9 +220,10 @@ void CWorldTransManager::DrawSecondPass()
void CWorldTransManager::DrawEnabled()
{
float wsAspect = CWideScreenFilter::SetViewportToMatch(1.f);
g_Renderer->SetPerspective(CCameraManager::DefaultFirstPersonFOV(),
CGraphics::g_ViewportResolution.x /
float(CGraphics::g_ViewportResolution.y),
wsAspect,
CCameraManager::DefaultNearPlane(),
CCameraManager::DefaultFarPlane());
g_Renderer->x318_26_ = true;
@ -243,6 +244,7 @@ void CWorldTransManager::DrawEnabled()
m_dissolve.draw(zeus::CColor{1.f, 1.f, 1.f, t}, 1.f);
}
CWideScreenFilter::SetViewportToFull();
m_widescreen.draw(zeus::CColor::skBlack, 1.f);
float ftbT = 0.f;