1
1
forked from 0ad/0ad

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)
{
glEnable(GL_SCISSOR_TEST);
glScissor(1, 1, FINAL_TEXTURE_SIZE - 2, FINAL_TEXTURE_SIZE - 2);
Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
scissorRect.x = scissorRect.y = 1;
scissorRect.width = scissorRect.height = FINAL_TEXTURE_SIZE - 2;
deviceCommandContext->SetScissors(1, &scissorRect);
#if !CONFIG2_GLES
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
@ -519,7 +521,7 @@ void CMiniMapTexture::RenderFinalTexture(
#if !CONFIG2_GLES
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
glDisable(GL_SCISSOR_TEST);
deviceCommandContext->SetScissors(0, nullptr);
}
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.
*
* 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
* 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.
*/
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.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -27,6 +27,7 @@
#include "gui/SettingTypes/CGUIString.h"
#include "ps/CStrInternStatic.h"
#include "ps/VideoMode.h"
#include "renderer/backend/gl/DeviceCommandContext.h"
#include "renderer/Renderer.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
{
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
g_Renderer.GetDeviceCommandContext();
bool isClipped = clipping != CRect();
if (isClipped)
{
@ -440,12 +444,13 @@ void CGUIText::Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor
clipping.right = std::floor(clipping.right);
float scale = g_VideoMode.GetScale();
glEnable(GL_SCISSOR_TEST);
glScissor(
std::ceil(clipping.left * scale),
std::ceil(g_yres - clipping.bottom * scale),
std::floor(clipping.GetWidth() * scale),
std::floor(clipping.GetHeight() * scale));
Renderer::Backend::GL::CDeviceCommandContext::ScissorRect 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);
}
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);
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.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -32,6 +32,7 @@
#include "ps/Globals.h"
#include "ps/Hotkey.h"
#include "ps/VideoMode.h"
#include "renderer/backend/gl/DeviceCommandContext.h"
#include "renderer/Renderer.h"
#include <sstream>
@ -1190,6 +1191,9 @@ void CInput::UpdateCachedSize()
void CInput::Draw(CCanvas2D& canvas)
{
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext =
g_Renderer.GetDeviceCommandContext();
if (m_CursorBlinkRate > 0.0)
{
// check if the cursor visibility state needs to be changed
@ -1240,12 +1244,13 @@ void CInput::Draw(CCanvas2D& canvas)
if (cliparea != CRect())
{
float scale = g_VideoMode.GetScale();
glEnable(GL_SCISSOR_TEST);
glScissor(
cliparea.left * scale,
g_yres - cliparea.bottom * scale,
cliparea.GetWidth() * scale,
cliparea.GetHeight() * scale);
Renderer::Backend::GL::CDeviceCommandContext::ScissorRect 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);
}
// These are useful later.
@ -1515,7 +1520,7 @@ void CInput::Draw(CCanvas2D& canvas)
canvas.DrawText(textRenderer);
if (cliparea != CRect())
glDisable(GL_SCISSOR_TEST);
deviceCommandContext->SetScissors(0, nullptr);
if (m_Caption->empty() && !m_PlaceholderText->GetRawString().empty())
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.y2 = (GLint)ceil((reflectionScissor[1].Y*0.5f+0.5f)*vpHeight);
glEnable(GL_SCISSOR_TEST);
glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
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
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_ReflectionFbo);
@ -670,7 +674,7 @@ void CSceneRenderer::RenderReflections(
ogl_WarnIfError();
}
glDisable(GL_SCISSOR_TEST);
deviceCommandContext->SetScissors(0, nullptr);
// Reset old camera
m_ViewCamera = normalCamera;
@ -715,8 +719,12 @@ void CSceneRenderer::RenderRefractions(
screenScissor.x2 = (GLint)ceil((refractionScissor[1].X*0.5f+0.5f)*vpWidth);
screenScissor.y2 = (GLint)ceil((refractionScissor[1].Y*0.5f+0.5f)*vpHeight);
glEnable(GL_SCISSOR_TEST);
glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
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
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_RefractionFbo);
@ -735,7 +743,7 @@ void CSceneRenderer::RenderRefractions(
RenderTransparentModels(deviceCommandContext, context, CULL_REFRACTIONS, TRANSPARENT_OPAQUE);
ogl_WarnIfError();
glDisable(GL_SCISSOR_TEST);
deviceCommandContext->SetScissors(0, nullptr);
// Reset old camera
m_ViewCamera = normalCamera;

View File

@ -632,8 +632,6 @@ void ShadowMap::BeginRender()
}
m->SavedViewCamera = g_Renderer.GetSceneRenderer().GetViewCamera();
glEnable(GL_SCISSOR_TEST);
}
void ShadowMap::PrepareCamera(const int cascade)
@ -649,15 +647,18 @@ void ShadowMap::PrepareCamera(const int cascade)
g_Renderer.GetSceneRenderer().SetViewCamera(camera);
const SViewPort& cascadeViewPort = m->Cascades[cascade].ViewPort;
glScissor(
cascadeViewPort.m_X, cascadeViewPort.m_Y,
cascadeViewPort.m_Width, cascadeViewPort.m_Height);
Renderer::Backend::GL::CDeviceCommandContext::ScissorRect scissorRect;
scissorRect.x = cascadeViewPort.m_X;
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
void ShadowMap::EndRender()
{
glDisable(GL_SCISSOR_TEST);
g_Renderer.GetDeviceCommandContext()->SetScissors(0, nullptr);
g_Renderer.GetSceneRenderer().SetViewCamera(m->SavedViewCamera);

View File

@ -47,6 +47,22 @@ bool operator!=(const StencilOpState& lhs, const StencilOpState& 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
// static
@ -149,6 +165,7 @@ void CDeviceCommandContext::Flush()
void CDeviceCommandContext::ResetStates()
{
SetGraphicsPipelineStateImpl(MakeDefaultGraphicsPipelineStateDesc(), true);
SetScissors(0, nullptr);
}
void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
@ -337,6 +354,28 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
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 Backend

View File

@ -21,6 +21,7 @@
#include "renderer/backend/Format.h"
#include "renderer/backend/PipelineState.h"
#include <array>
#include <memory>
#include <optional>
@ -53,6 +54,14 @@ public:
const uint32_t width, const uint32_t height,
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();
private:
@ -64,6 +73,9 @@ private:
const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force);
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