Moves scissor test management to DeviceCommandContext.

This was SVN commit r26288.
This commit is contained in:
Vladislav Belov 2022-02-01 17:58:21 +00:00
parent aeaf495da3
commit ac77d1c3e0
8 changed files with 105 additions and 33 deletions

View File

@ -497,8 +497,10 @@ void CMiniMapTexture::RenderFinalTexture(
if (m_EntitiesDrawn > 0) if (m_EntitiesDrawn > 0)
{ {
glEnable(GL_SCISSOR_TEST); Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
glScissor(1, 1, FINAL_TEXTURE_SIZE - 2, FINAL_TEXTURE_SIZE - 2); scissorRect.x = scissorRect.y = 1;
scissorRect.width = scissorRect.height = FINAL_TEXTURE_SIZE - 2;
deviceCommandContext->SetScissors(1, &scissorRect);
#if !CONFIG2_GLES #if !CONFIG2_GLES
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif #endif
@ -519,7 +521,7 @@ void CMiniMapTexture::RenderFinalTexture(
#if !CONFIG2_GLES #if !CONFIG2_GLES
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif #endif
glDisable(GL_SCISSOR_TEST); deviceCommandContext->SetScissors(0, nullptr);
} }
tech->EndPass(); tech->EndPass();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games. /* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -45,7 +45,7 @@ public:
/** /**
* Set clipping rectangle, in pre-transform coordinates (i.e. text is clipped against * Set clipping rectangle, in pre-transform coordinates (i.e. text is clipped against
* this rect based purely on the x,y values passed into Put()). Text fully outside the * this rect based purely on the x,y values passed into Put()). Text fully outside the
* clipping rectangle may not be rendered. Should be used in conjunction with glScissor * clipping rectangle may not be rendered. Should be used in conjunction with SetScissors
* for precise clipping - this is just an optimisation. * for precise clipping - this is just an optimisation.
*/ */
void SetClippingRect(const CRect& rect); void SetClippingRect(const CRect& rect);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games. /* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -27,6 +27,7 @@
#include "gui/SettingTypes/CGUIString.h" #include "gui/SettingTypes/CGUIString.h"
#include "ps/CStrInternStatic.h" #include "ps/CStrInternStatic.h"
#include "ps/VideoMode.h" #include "ps/VideoMode.h"
#include "renderer/backend/gl/DeviceCommandContext.h"
#include "renderer/Renderer.h" #include "renderer/Renderer.h"
#include <math.h> #include <math.h>
@ -430,6 +431,9 @@ bool CGUIText::AssembleCalls(
void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor, const CVector2D& pos, CRect clipping) const void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor, const CVector2D& pos, CRect clipping) const
{ {
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
g_Renderer.GetDeviceCommandContext();
bool isClipped = clipping != CRect(); bool isClipped = clipping != CRect();
if (isClipped) if (isClipped)
{ {
@ -440,12 +444,13 @@ void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor
clipping.right = std::floor(clipping.right); clipping.right = std::floor(clipping.right);
float scale = g_VideoMode.GetScale(); float scale = g_VideoMode.GetScale();
glEnable(GL_SCISSOR_TEST); Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
glScissor( scissorRect.x = std::ceil(clipping.left * scale);
std::ceil(clipping.left * scale), scissorRect.y = std::ceil(g_yres - clipping.bottom * scale);
std::ceil(g_yres - clipping.bottom * scale), scissorRect.width = std::floor(clipping.GetWidth() * scale);
std::floor(clipping.GetWidth() * scale), scissorRect.height = std::floor(clipping.GetHeight() * scale);
std::floor(clipping.GetHeight() * scale)); // TODO: move scissors to CCanvas2D.
deviceCommandContext->SetScissors(1, &scissorRect);
} }
CTextRenderer textRenderer; CTextRenderer textRenderer;
@ -469,5 +474,5 @@ void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor
pGUI.DrawSprite(sc.m_Sprite, canvas, sc.m_Area + pos); pGUI.DrawSprite(sc.m_Sprite, canvas, sc.m_Area + pos);
if (isClipped) if (isClipped)
glDisable(GL_SCISSOR_TEST); deviceCommandContext->SetScissors(0, nullptr);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games. /* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -32,6 +32,7 @@
#include "ps/Globals.h" #include "ps/Globals.h"
#include "ps/Hotkey.h" #include "ps/Hotkey.h"
#include "ps/VideoMode.h" #include "ps/VideoMode.h"
#include "renderer/backend/gl/DeviceCommandContext.h"
#include "renderer/Renderer.h" #include "renderer/Renderer.h"
#include <sstream> #include <sstream>
@ -1190,6 +1191,9 @@ void CInput::UpdateCachedSize()
void CInput::Draw(CCanvas2D& canvas) void CInput::Draw(CCanvas2D& canvas)
{ {
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
g_Renderer.GetDeviceCommandContext();
if (m_CursorBlinkRate > 0.0) if (m_CursorBlinkRate > 0.0)
{ {
// check if the cursor visibility state needs to be changed // check if the cursor visibility state needs to be changed
@ -1240,12 +1244,13 @@ void CInput::Draw(CCanvas2D& canvas)
if (cliparea != CRect()) if (cliparea != CRect())
{ {
float scale = g_VideoMode.GetScale(); float scale = g_VideoMode.GetScale();
glEnable(GL_SCISSOR_TEST); Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
glScissor( scissorRect.x = cliparea.left * scale;
cliparea.left * scale, scissorRect.y = g_yres - cliparea.bottom * scale;
g_yres - cliparea.bottom * scale, scissorRect.width = cliparea.GetWidth() * scale;
cliparea.GetWidth() * scale, scissorRect.height = cliparea.GetHeight() * scale;
cliparea.GetHeight() * scale); // TODO: move scissors to CCanvas2D.
deviceCommandContext->SetScissors(1, &scissorRect);
} }
// These are useful later. // These are useful later.
@ -1515,7 +1520,7 @@ void CInput::Draw(CCanvas2D& canvas)
canvas.DrawText(textRenderer); canvas.DrawText(textRenderer);
if (cliparea != CRect()) if (cliparea != CRect())
glDisable(GL_SCISSOR_TEST); deviceCommandContext->SetScissors(0, nullptr);
if (m_Caption->empty() && !m_PlaceholderText->GetRawString().empty()) if (m_Caption->empty() && !m_PlaceholderText->GetRawString().empty())
DrawPlaceholderText(canvas, cliparea); DrawPlaceholderText(canvas, cliparea);

View File

@ -632,8 +632,12 @@ void CSceneRenderer::RenderReflections(
screenScissor.x2 = (GLint)ceil((reflectionScissor[1].X*0.5f+0.5f)*vpWidth); screenScissor.x2 = (GLint)ceil((reflectionScissor[1].X*0.5f+0.5f)*vpWidth);
screenScissor.y2 = (GLint)ceil((reflectionScissor[1].Y*0.5f+0.5f)*vpHeight); screenScissor.y2 = (GLint)ceil((reflectionScissor[1].Y*0.5f+0.5f)*vpHeight);
glEnable(GL_SCISSOR_TEST); Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); scissorRect.x = screenScissor.x1;
scissorRect.y = screenScissor.y1;
scissorRect.width = screenScissor.x2 - screenScissor.x1;
scissorRect.height = screenScissor.y2 - screenScissor.y1;
deviceCommandContext->SetScissors(1, &scissorRect);
// try binding the framebuffer // try binding the framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_ReflectionFbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_ReflectionFbo);
@ -670,7 +674,7 @@ void CSceneRenderer::RenderReflections(
ogl_WarnIfError(); ogl_WarnIfError();
} }
glDisable(GL_SCISSOR_TEST); deviceCommandContext->SetScissors(0, nullptr);
// Reset old camera // Reset old camera
m_ViewCamera = normalCamera; m_ViewCamera = normalCamera;
@ -715,8 +719,12 @@ void CSceneRenderer::RenderRefractions(
screenScissor.x2 = (GLint)ceil((refractionScissor[1].X*0.5f+0.5f)*vpWidth); screenScissor.x2 = (GLint)ceil((refractionScissor[1].X*0.5f+0.5f)*vpWidth);
screenScissor.y2 = (GLint)ceil((refractionScissor[1].Y*0.5f+0.5f)*vpHeight); screenScissor.y2 = (GLint)ceil((refractionScissor[1].Y*0.5f+0.5f)*vpHeight);
glEnable(GL_SCISSOR_TEST); Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); scissorRect.x = screenScissor.x1;
scissorRect.y = screenScissor.y1;
scissorRect.width = screenScissor.x2 - screenScissor.x1;
scissorRect.height = screenScissor.y2 - screenScissor.y1;
deviceCommandContext->SetScissors(1, &scissorRect);
// try binding the framebuffer // try binding the framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_RefractionFbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_RefractionFbo);
@ -735,7 +743,7 @@ void CSceneRenderer::RenderRefractions(
RenderTransparentModels(deviceCommandContext, context, CULL_REFRACTIONS, TRANSPARENT_OPAQUE); RenderTransparentModels(deviceCommandContext, context, CULL_REFRACTIONS, TRANSPARENT_OPAQUE);
ogl_WarnIfError(); ogl_WarnIfError();
glDisable(GL_SCISSOR_TEST); deviceCommandContext->SetScissors(0, nullptr);
// Reset old camera // Reset old camera
m_ViewCamera = normalCamera; m_ViewCamera = normalCamera;

View File

@ -632,8 +632,6 @@ void ShadowMap::BeginRender()
} }
m->SavedViewCamera = g_Renderer.GetSceneRenderer().GetViewCamera(); m->SavedViewCamera = g_Renderer.GetSceneRenderer().GetViewCamera();
glEnable(GL_SCISSOR_TEST);
} }
void ShadowMap::PrepareCamera(const int cascade) void ShadowMap::PrepareCamera(const int cascade)
@ -649,15 +647,18 @@ void ShadowMap::PrepareCamera(const int cascade)
g_Renderer.GetSceneRenderer().SetViewCamera(camera); g_Renderer.GetSceneRenderer().SetViewCamera(camera);
const SViewPort& cascadeViewPort = m->Cascades[cascade].ViewPort; const SViewPort& cascadeViewPort = m->Cascades[cascade].ViewPort;
glScissor( Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
cascadeViewPort.m_X, cascadeViewPort.m_Y, scissorRect.x = cascadeViewPort.m_X;
cascadeViewPort.m_Width, cascadeViewPort.m_Height); scissorRect.y = cascadeViewPort.m_Y;
scissorRect.width = cascadeViewPort.m_Width;
scissorRect.height = cascadeViewPort.m_Height;
g_Renderer.GetDeviceCommandContext()->SetScissors(1, &scissorRect);
} }
// Finish rendering into shadow map texture // Finish rendering into shadow map texture
void ShadowMap::EndRender() void ShadowMap::EndRender()
{ {
glDisable(GL_SCISSOR_TEST); g_Renderer.GetDeviceCommandContext()->SetScissors(0, nullptr);
g_Renderer.GetSceneRenderer().SetViewCamera(m->SavedViewCamera); g_Renderer.GetSceneRenderer().SetViewCamera(m->SavedViewCamera);

View File

@ -47,6 +47,22 @@ bool operator!=(const StencilOpState& lhs, const StencilOpState& rhs)
return !operator==(lhs, rhs); return !operator==(lhs, rhs);
} }
bool operator==(
const CDeviceCommandContext::ScissorRect& lhs,
const CDeviceCommandContext::ScissorRect& rhs)
{
return
lhs.x == rhs.x && lhs.y == rhs.y &&
lhs.width == rhs.width && lhs.height == rhs.height;
}
bool operator!=(
const CDeviceCommandContext::ScissorRect& lhs,
const CDeviceCommandContext::ScissorRect& rhs)
{
return !operator==(lhs, rhs);
}
} // anonymous namespace } // anonymous namespace
// static // static
@ -149,6 +165,7 @@ void CDeviceCommandContext::Flush()
void CDeviceCommandContext::ResetStates() void CDeviceCommandContext::ResetStates()
{ {
SetGraphicsPipelineStateImpl(MakeDefaultGraphicsPipelineStateDesc(), true); SetGraphicsPipelineStateImpl(MakeDefaultGraphicsPipelineStateDesc(), true);
SetScissors(0, nullptr);
} }
void CDeviceCommandContext::SetGraphicsPipelineStateImpl( void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
@ -337,6 +354,28 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
m_GraphicsPipelineStateDesc = pipelineStateDesc; m_GraphicsPipelineStateDesc = pipelineStateDesc;
} }
void CDeviceCommandContext::SetScissors(const uint32_t scissorCount, const ScissorRect* scissors)
{
ENSURE(scissorCount <= 1);
if (scissorCount == 0)
{
if (m_ScissorCount != scissorCount)
glDisable(GL_SCISSOR_TEST);
}
else
{
if (m_ScissorCount != scissorCount)
glEnable(GL_SCISSOR_TEST);
if (m_ScissorCount != scissorCount || m_Scissors[0] != scissors[0])
{
ENSURE(scissors);
m_Scissors[0] = scissors[0];
glScissor(m_Scissors[0].x, m_Scissors[0].y, m_Scissors[0].width, m_Scissors[0].height);
}
}
m_ScissorCount = scissorCount;
}
} // namespace GL } // namespace GL
} // namespace Backend } // namespace Backend

View File

@ -21,6 +21,7 @@
#include "renderer/backend/Format.h" #include "renderer/backend/Format.h"
#include "renderer/backend/PipelineState.h" #include "renderer/backend/PipelineState.h"
#include <array>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -53,6 +54,14 @@ public:
const uint32_t width, const uint32_t height, const uint32_t width, const uint32_t height,
const uint32_t level = 0, const uint32_t layer = 0); const uint32_t level = 0, const uint32_t layer = 0);
// TODO: maybe we should add a more common type, like CRectI.
struct ScissorRect
{
int32_t x, y;
int32_t width, height;
};
void SetScissors(const uint32_t scissorCount, const ScissorRect* scissors);
void Flush(); void Flush();
private: private:
@ -64,6 +73,9 @@ private:
const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force); const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force);
GraphicsPipelineStateDesc m_GraphicsPipelineStateDesc{}; GraphicsPipelineStateDesc m_GraphicsPipelineStateDesc{};
uint32_t m_ScissorCount = 0;
// GL2.1 doesn't support more than 1 scissor.
std::array<ScissorRect, 1> m_Scissors;
}; };
} // namespace GL } // namespace GL