Adds Canvas2D to encapsulate low level GL calls for 2D rendering.

Implements DrawLine for charts.

Differential Revision: https://code.wildfiregames.com/D4024
This was SVN commit r25588.
This commit is contained in:
vladislavbelov
2021-05-28 16:35:57 +00:00
parent 6f9a162dfa
commit 2f3837e0b5
30 changed files with 158 additions and 71 deletions
+64
View File
@@ -0,0 +1,64 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precompiled.h"
#include "Canvas2D.h"
#include "graphics/Color.h"
#include "graphics/ShaderManager.h"
#include "gui/GUIMatrix.h"
#include "maths/Vector2D.h"
#include "ps/CStrInternStatic.h"
#include "renderer/Renderer.h"
void CCanvas2D::DrawLine(const std::vector<CVector2D>& points, const float width, const CColor& color)
{
std::vector<float> vertices;
vertices.reserve(points.size() * 3);
for (const CVector2D& point : points)
{
vertices.emplace_back(point.X);
vertices.emplace_back(point.Y);
vertices.emplace_back(0.0f);
}
// Setup the render state
CMatrix3D transform = GetDefaultGuiMatrix();
CShaderDefines lineDefines;
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid, g_Renderer.GetSystemShaderDefines(), lineDefines);
tech->BeginPass();
CShaderProgramPtr shader = tech->GetShader();
shader->Uniform(str_transform, transform);
shader->Uniform(str_color, color );
shader->VertexPointer(3, GL_FLOAT, 0, &vertices[0]);
shader->AssertPointersBound();
#if !CONFIG2_GLES
glEnable(GL_LINE_SMOOTH);
#endif
glLineWidth(width);
if (!g_Renderer.DoSkipSubmit())
glDrawArrays(GL_LINE_STRIP, 0, vertices.size() / 3);
glLineWidth(1.0f);
#if !CONFIG2_GLES
glDisable(GL_LINE_SMOOTH);
#endif
tech->EndPass();
}
+35
View File
@@ -0,0 +1,35 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_CANVAS2D
#define INCLUDED_CANVAS2D
#include "maths/Vector2D.h"
#include <vector>
struct CColor;
// Encapsulates 2D drawing functionality to hide and optimize
// low level API calls.
class CCanvas2D
{
public:
void DrawLine(const std::vector<CVector2D>& points, const float width, const CColor& color);
};
#endif // INCLUDED_CANVAS2D
+4 -1
View File
@@ -19,6 +19,7 @@
#include "CGUI.h"
#include "graphics/Canvas2D.h"
#include "gui/IGUIScrollBar.h"
#include "gui/ObjectBases/IGUIObject.h"
#include "gui/ObjectTypes/CGUIDummyObject.h"
@@ -343,8 +344,10 @@ void CGUI::Draw()
return visibleObject1.bufferedZ < visibleObject2.bufferedZ;
return visibleObject1.index < visibleObject2.index;
});
CCanvas2D canvas;
for (const VisibleObject& visibleObject : visibleObjects)
visibleObject.object->Draw();
visibleObject.object->Draw(canvas);
}
void CGUI::DrawSprite(const CGUISpriteInstance& Sprite, const CRect& Rect, const CRect& UNUSED(Clipping))
+2 -1
View File
@@ -37,6 +37,7 @@
#include <map>
#include <vector>
class CCanvas2D;
class CGUI;
class CGUISize;
class IGUIObject;
@@ -264,7 +265,7 @@ protected:
/**
* Draws the object.
*/
virtual void Draw() = 0;
virtual void Draw(CCanvas2D& canvas) = 0;
/**
* Some objects need to be able to pre-emptively process SDL_Event_.
+1 -1
View File
@@ -80,7 +80,7 @@ void CButton::HandleMessage(SGUIMessage& Message)
IGUITextOwner::HandleMessage(Message);
}
void CButton::Draw()
void CButton::Draw(CCanvas2D& UNUSED(canvas))
{
m_pGUI.DrawSprite(
GetButtonSprite(m_Sprite, m_SpriteOver, m_SpritePressed, m_SpriteDisabled),
+1 -1
View File
@@ -56,7 +56,7 @@ public:
/**
* Draws the Button
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
/**
* @see IGUIObject#IsMouseOver()
+28 -44
View File
@@ -19,6 +19,7 @@
#include "CChart.h"
#include "graphics/Canvas2D.h"
#include "graphics/ShaderManager.h"
#include "gui/GUIMatrix.h"
#include "gui/SettingTypes/CGUIList.h"
@@ -65,24 +66,6 @@ void CChart::HandleMessage(SGUIMessage& Message)
UpdateSeries();
}
void CChart::DrawLine(const CShaderProgramPtr& shader, const CGUIColor& color, const std::vector<float>& vertices) const
{
shader->Uniform(str_color, color);
shader->VertexPointer(3, GL_FLOAT, 0, &vertices[0]);
shader->AssertPointersBound();
#if !CONFIG2_GLES
glEnable(GL_LINE_SMOOTH);
#endif
glLineWidth(1.1f);
if (!g_Renderer.DoSkipSubmit())
glDrawArrays(GL_LINE_STRIP, 0, vertices.size() / 3);
glLineWidth(1.0f);
#if !CONFIG2_GLES
glDisable(GL_LINE_SMOOTH);
#endif
}
void CChart::DrawTriangleStrip(const CShaderProgramPtr& shader, const CGUIColor& color, const std::vector<float>& vertices) const
{
shader->Uniform(str_color, color);
@@ -109,7 +92,7 @@ void CChart::DrawAxes(const CShaderProgramPtr& shader) const
DrawTriangleStrip(shader, m_AxisColor, vertices);
}
void CChart::Draw()
void CChart::Draw(CCanvas2D& canvas)
{
PROFILE3("render chart");
@@ -120,6 +103,32 @@ void CChart::Draw()
const float width = rect.GetWidth();
const float height = rect.GetHeight();
CVector2D scale(width / (m_RightTop.X - m_LeftBottom.X), height / (m_RightTop.Y - m_LeftBottom.Y));
std::vector<CVector2D> linePoints;
for (const CChartData& data : m_Series)
{
if (data.m_Points.empty())
continue;
linePoints.clear();
for (const CVector2D& point : data.m_Points)
{
if (fabs(point.X) != std::numeric_limits<float>::infinity() && fabs(point.Y) != std::numeric_limits<float>::infinity())
{
linePoints.emplace_back(
rect.left + (point.X - m_LeftBottom.X) * scale.X,
rect.bottom - (point.Y - m_LeftBottom.Y) * scale.Y);
}
else
{
canvas.DrawLine(linePoints, 1.1f, data.m_Color);
linePoints.clear();
}
}
if (!linePoints.empty())
canvas.DrawLine(linePoints, 1.1f, data.m_Color);
}
// Setup the render state
CMatrix3D transform = GetDefaultGuiMatrix();
CShaderDefines lineDefines;
@@ -128,31 +137,6 @@ void CChart::Draw()
CShaderProgramPtr shader = tech->GetShader();
shader->Uniform(str_transform, transform);
CVector2D scale(width / (m_RightTop.X - m_LeftBottom.X), height / (m_RightTop.Y - m_LeftBottom.Y));
for (const CChartData& data : m_Series)
{
if (data.m_Points.empty())
continue;
std::vector<float> vertices;
for (const CVector2D& point : data.m_Points)
{
if (fabs(point.X) != std::numeric_limits<float>::infinity() && fabs(point.Y) != std::numeric_limits<float>::infinity())
{
vertices.push_back(rect.left + (point.X - m_LeftBottom.X) * scale.X);
vertices.push_back(rect.bottom - (point.Y - m_LeftBottom.Y) * scale.Y);
vertices.push_back(0.0f);
}
else
{
DrawLine(shader, data.m_Color, vertices);
vertices.clear();
}
}
if (!vertices.empty())
DrawLine(shader, data.m_Color, vertices);
}
if (m_AxisWidth > 0)
DrawAxes(shader);
+1 -1
View File
@@ -65,7 +65,7 @@ protected:
/**
* Draws the Chart
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
virtual CRect GetChartRect() const;
+1 -1
View File
@@ -64,7 +64,7 @@ void CCheckBox::HandleMessage(SGUIMessage& Message)
}
}
void CCheckBox::Draw()
void CCheckBox::Draw(CCanvas2D& UNUSED(canvas))
{
m_pGUI.DrawSprite(
m_Checked ?
+1 -1
View File
@@ -43,7 +43,7 @@ public:
/**
* Draws the control
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
protected:
// Settings
+1 -1
View File
@@ -420,7 +420,7 @@ bool CDropDown::IsMouseOver() const
return m_CachedActualSize.PointInside(m_pGUI.GetMousePos());
}
void CDropDown::Draw()
void CDropDown::Draw(CCanvas2D& UNUSED(canvas))
{
const CGUISpriteInstance& sprite = m_Enabled ? m_Sprite : m_SpriteDisabled;
const CGUISpriteInstance& spriteOverlay = m_Enabled ? m_SpriteOverlay : m_SpriteOverlayDisabled;
+1 -1
View File
@@ -65,7 +65,7 @@ public:
/**
* Draws the Button
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
// This is one of the few classes we actually need to redefine this function
// this is because the size of the control changes whether it is open
+1 -1
View File
@@ -35,7 +35,7 @@ class CGUIDummyObject : public IGUIObject
public:
CGUIDummyObject(CGUI& pGUI) : IGUIObject(pGUI) {}
virtual void Draw() {}
virtual void Draw(CCanvas2D& UNUSED(canvas)) {}
/**
* Empty can never be hovered. It is only a category.
+1 -1
View File
@@ -43,7 +43,7 @@ public:
virtual ~CHotkeyPicker();
// Do nothing.
virtual void Draw() {};
virtual void Draw(CCanvas2D& UNUSED(canvas)) {};
// Checks if the timer has passed and we need to fire a "combination" event.
virtual void Tick();
+1 -1
View File
@@ -31,7 +31,7 @@ CImage::~CImage()
{
}
void CImage::Draw()
void CImage::Draw(CCanvas2D& UNUSED(canvas))
{
m_pGUI.DrawSprite(m_Sprite, m_CachedActualSize);
}
+1 -1
View File
@@ -43,7 +43,7 @@ protected:
/**
* Draws the Image
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
};
+1 -1
View File
@@ -1187,7 +1187,7 @@ void CInput::UpdateCachedSize()
m_GeneratedPlaceholderTextValid = false;
}
void CInput::Draw()
void CInput::Draw(CCanvas2D& UNUSED(canvas))
{
if (m_CursorBlinkRate > 0.0)
{
+1 -1
View File
@@ -95,7 +95,7 @@ protected:
/**
* Draws the Text
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
/**
* Calculate m_CharacterPosition
+1 -1
View File
@@ -299,7 +299,7 @@ InReaction CList::ManuallyHandleKeys(const SDL_Event_* ev)
return result;
}
void CList::Draw()
void CList::Draw(CCanvas2D& UNUSED(canvas))
{
DrawList(m_Selected, m_Sprite, m_SpriteOverlay, m_SpriteSelectArea, m_SpriteSelectAreaOverlay, m_TextColor);
}
+1 -1
View File
@@ -84,7 +84,7 @@ protected:
/**
* Draws the List box
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
virtual void CreateJSObject();
+1 -1
View File
@@ -422,7 +422,7 @@ void CMiniMap::DrawTexture(CShaderProgramPtr shader, float coordMax, float angle
// most of the time, updating the framebuffer twice a frame.
// Here it updates as ping-pong either texture or vertex array each sec to lower gpu stalling
// (those operations cause a gpu sync, which slows down the way gpu works)
void CMiniMap::Draw()
void CMiniMap::Draw(CCanvas2D& UNUSED(canvas))
{
PROFILE3("render minimap");
+1 -1
View File
@@ -39,7 +39,7 @@ public:
static float GetShallowPassageHeight();
protected:
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
/**
* @see IGUIObject#HandleMessage()
+1 -1
View File
@@ -53,7 +53,7 @@ void CProgressBar::HandleMessage(SGUIMessage& Message)
}
}
void CProgressBar::Draw()
void CProgressBar::Draw(CCanvas2D& UNUSED(canvas))
{
m_pGUI.DrawSprite(m_SpriteBackground, m_CachedActualSize);
+1 -1
View File
@@ -36,7 +36,7 @@ protected:
/**
* Draws the progress bar
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
/**
* @see IGUIObject#HandleMessage()
+1 -1
View File
@@ -102,7 +102,7 @@ void CSlider::HandleMessage(SGUIMessage& Message)
}
}
void CSlider::Draw()
void CSlider::Draw(CCanvas2D& UNUSED(canvas))
{
CRect slider_line(m_CachedActualSize);
slider_line.left += m_ButtonSide / 2.0f;
+1 -1
View File
@@ -44,7 +44,7 @@ protected:
*/
virtual void HandleMessage(SGUIMessage& Message);
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
/**
* Change settings and send the script event
+1 -1
View File
@@ -183,7 +183,7 @@ void CText::HandleMessage(SGUIMessage& Message)
IGUITextOwner::HandleMessage(Message);
}
void CText::Draw()
void CText::Draw(CCanvas2D& UNUSED(canvas))
{
m_pGUI.DrawSprite(m_Sprite, m_CachedActualSize);
+1 -1
View File
@@ -65,7 +65,7 @@ protected:
/**
* Draws the Text
*/
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
virtual void CreateJSObject();
+1 -1
View File
@@ -131,7 +131,7 @@ void CTooltip::HandleMessage(SGUIMessage& Message)
IGUITextOwner::HandleMessage(Message);
}
void CTooltip::Draw()
void CTooltip::Draw(CCanvas2D& UNUSED(canvas))
{
// Normally IGUITextOwner will handle this updating but since SetupText can modify the position
// we need to call it now *before* we do the rest of the drawing
+1 -1
View File
@@ -53,7 +53,7 @@ protected:
*/
virtual void HandleMessage(SGUIMessage& Message);
virtual void Draw();
virtual void Draw(CCanvas2D& canvas);
virtual float GetBufferedZ() const;