Removes scissor backend setup from GUI.
Differential Revision: https://code.wildfiregames.com/D5051 This was SVN commit r27798.
This commit is contained in:
parent
23f1949e2a
commit
5ba7ec3bfa
@ -25,6 +25,7 @@
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "maths/Rect.h"
|
||||
#include "maths/Vector2D.h"
|
||||
#include "ps/containers/StaticVector.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "renderer/Renderer.h"
|
||||
|
||||
@ -159,6 +160,22 @@ public:
|
||||
return transform;
|
||||
}
|
||||
|
||||
void ApplyScissors()
|
||||
{
|
||||
if (!Scissors.empty())
|
||||
{
|
||||
CRect rect = Scissors.back();
|
||||
Renderer::Backend::IDeviceCommandContext::Rect scissorRect;
|
||||
scissorRect.x = std::ceil(rect.left * Scale);
|
||||
scissorRect.y = std::ceil(static_cast<float>(HeightInPixels) - rect.bottom * Scale);
|
||||
scissorRect.width = std::floor(rect.GetWidth() * Scale);
|
||||
scissorRect.height = std::floor(rect.GetHeight() * Scale);
|
||||
DeviceCommandContext->SetScissors(1, &scissorRect);
|
||||
}
|
||||
else
|
||||
DeviceCommandContext->SetScissors(0, nullptr);
|
||||
}
|
||||
|
||||
uint32_t WidthInPixels = 1;
|
||||
uint32_t HeightInPixels = 1;
|
||||
float Scale = 1.0f;
|
||||
@ -173,6 +190,8 @@ public:
|
||||
// We assume that the shader can't be destroyed while it's bound. So these
|
||||
// bindings remain valid while the shader is alive.
|
||||
SBindingSlots BindingSlots;
|
||||
|
||||
PS::StaticVector<CRect, 4> Scissors;
|
||||
};
|
||||
|
||||
CCanvas2D::CCanvas2D(
|
||||
@ -186,6 +205,7 @@ CCanvas2D::CCanvas2D(
|
||||
CCanvas2D::~CCanvas2D()
|
||||
{
|
||||
Flush();
|
||||
ENSURE(m->Scissors.empty());
|
||||
}
|
||||
|
||||
void CCanvas2D::DrawLine(const std::vector<CVector2D>& points, const float width, const CColor& color)
|
||||
@ -448,6 +468,20 @@ void CCanvas2D::DrawText(CTextRenderer& textRenderer)
|
||||
m->DeviceCommandContext, m->Tech->GetShader(), m->TransformScale, m->Translation);
|
||||
}
|
||||
|
||||
void CCanvas2D::PushScissor(const CRect& scissor)
|
||||
{
|
||||
ENSURE(!m->Scissors.full());
|
||||
m->Scissors.emplace_back(scissor);
|
||||
m->ApplyScissors();
|
||||
}
|
||||
|
||||
void CCanvas2D::PopScissor()
|
||||
{
|
||||
ENSURE(!m->Scissors.empty());
|
||||
m->Scissors.pop_back();
|
||||
m->ApplyScissors();
|
||||
}
|
||||
|
||||
void CCanvas2D::Flush()
|
||||
{
|
||||
m->UnbindTech();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
/* Copyright (C) 2023 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -90,7 +90,37 @@ public:
|
||||
void DrawText(CTextRenderer& textRenderer);
|
||||
|
||||
/**
|
||||
* Unbinds all binded resources and clears caches. Frequent calls might
|
||||
* Adds the scissor rect to a scissor stack. The only top scissor is
|
||||
* applied. It's recommended to use as few nested scissors as possible.
|
||||
*/
|
||||
void PushScissor(const CRect& scissor);
|
||||
|
||||
/**
|
||||
* Removes the top scissor rect from a scissor stack. The stack must not be
|
||||
* empty.
|
||||
*/
|
||||
void PopScissor();
|
||||
|
||||
class ScopedScissor
|
||||
{
|
||||
public:
|
||||
ScopedScissor(CCanvas2D& canvas, const CRect& scissor)
|
||||
: m_Canvas(canvas)
|
||||
{
|
||||
m_Canvas.PushScissor(scissor);
|
||||
}
|
||||
|
||||
~ScopedScissor()
|
||||
{
|
||||
m_Canvas.PopScissor();
|
||||
}
|
||||
|
||||
private:
|
||||
CCanvas2D& m_Canvas;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbinds all bound resources and clears caches. Frequent calls might
|
||||
* affect performance. Useful to call a custom rendering code.
|
||||
*/
|
||||
void Flush();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
/* Copyright (C) 2023 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -26,11 +26,9 @@
|
||||
#include "gui/ObjectBases/IGUIObject.h"
|
||||
#include "gui/SettingTypes/CGUIString.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/VideoMode.h"
|
||||
#include "renderer/backend/IDeviceCommandContext.h"
|
||||
#include "renderer/Renderer.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
|
||||
extern int g_xres, g_yres;
|
||||
|
||||
@ -450,29 +448,13 @@ bool CGUIText::AssembleCalls(
|
||||
|
||||
void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor, const CVector2D& pos, CRect clipping) const
|
||||
{
|
||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
|
||||
const bool isClipped = clipping != CRect();
|
||||
std::optional<CCanvas2D::ScopedScissor> scopedScissor;
|
||||
if (isClipped)
|
||||
{
|
||||
// Make clipping rect as small as possible to prevent rounding errors
|
||||
clipping.top = std::ceil(clipping.top);
|
||||
clipping.bottom = std::floor(clipping.bottom);
|
||||
clipping.left = std::ceil(clipping.left);
|
||||
clipping.right = std::floor(clipping.right);
|
||||
|
||||
if (clipping.GetWidth() <= 0.0f || clipping.GetHeight() <= 0.0f)
|
||||
return;
|
||||
|
||||
const float scale = g_VideoMode.GetScale();
|
||||
Renderer::Backend::IDeviceCommandContext::Rect scissorRect;
|
||||
scissorRect.x = std::ceil(clipping.left * scale);
|
||||
scissorRect.y = std::ceil(g_yres - clipping.bottom * scale);
|
||||
scissorRect.width = std::floor(clipping.GetWidth() * scale);
|
||||
scissorRect.height = std::floor(clipping.GetHeight() * scale);
|
||||
// TODO: move scissors to CCanvas2D.
|
||||
deviceCommandContext->SetScissors(1, &scissorRect);
|
||||
scopedScissor.emplace(canvas, clipping);
|
||||
}
|
||||
|
||||
CTextRenderer textRenderer;
|
||||
@ -494,7 +476,4 @@ void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor
|
||||
|
||||
for (const SSpriteCall& sc : m_SpriteCalls)
|
||||
pGUI.DrawSprite(sc.m_Sprite, canvas, sc.m_Area + pos);
|
||||
|
||||
if (isClipped)
|
||||
deviceCommandContext->SetScissors(0, nullptr);
|
||||
}
|
||||
|
@ -31,9 +31,6 @@
|
||||
#include "ps/GameSetup/Config.h"
|
||||
#include "ps/Globals.h"
|
||||
#include "ps/Hotkey.h"
|
||||
#include "ps/VideoMode.h"
|
||||
#include "renderer/backend/IDeviceCommandContext.h"
|
||||
#include "renderer/Renderer.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -1488,9 +1485,6 @@ void CInput::DrawContent(CCanvas2D& canvas)
|
||||
|
||||
void CInput::Draw(CCanvas2D& canvas)
|
||||
{
|
||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||
g_Renderer.GetDeviceCommandContext();
|
||||
|
||||
// We'll have to setup clipping manually, since we're doing the rendering manually.
|
||||
CRect cliparea(m_CachedActualSize);
|
||||
|
||||
@ -1513,20 +1507,11 @@ void CInput::Draw(CCanvas2D& canvas)
|
||||
{
|
||||
if (cliparea.GetWidth() <= 0.0f || cliparea.GetHeight() <= 0.0f)
|
||||
return;
|
||||
const float scale = g_VideoMode.GetScale();
|
||||
Renderer::Backend::IDeviceCommandContext::Rect scissorRect;
|
||||
scissorRect.x = cliparea.left * scale;
|
||||
scissorRect.y = g_yres - cliparea.bottom * scale;
|
||||
scissorRect.width = cliparea.GetWidth() * scale;
|
||||
scissorRect.height = cliparea.GetHeight() * scale;
|
||||
// TODO: move scissors to CCanvas2D.
|
||||
deviceCommandContext->SetScissors(1, &scissorRect);
|
||||
CCanvas2D::ScopedScissor scopedScissor(canvas, cliparea);
|
||||
DrawContent(canvas);
|
||||
}
|
||||
|
||||
DrawContent(canvas);
|
||||
|
||||
if (isClipped)
|
||||
deviceCommandContext->SetScissors(0, nullptr);
|
||||
else
|
||||
DrawContent(canvas);
|
||||
|
||||
if (m_Caption->empty() && !m_PlaceholderText->GetRawString().empty())
|
||||
DrawPlaceholderText(canvas, cliparea);
|
||||
|
Loading…
Reference in New Issue
Block a user