mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-21 01:04:06 +00:00
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:
@@ -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();
|
||||
}
|
||||
@@ -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
@@ -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))
|
||||
|
||||
@@ -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_.
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
/**
|
||||
* Draws the Button
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
/**
|
||||
* @see IGUIObject#IsMouseOver()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ protected:
|
||||
/**
|
||||
* Draws the Chart
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
virtual CRect GetChartRect() const;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ void CCheckBox::HandleMessage(SGUIMessage& Message)
|
||||
}
|
||||
}
|
||||
|
||||
void CCheckBox::Draw()
|
||||
void CCheckBox::Draw(CCanvas2D& UNUSED(canvas))
|
||||
{
|
||||
m_pGUI.DrawSprite(
|
||||
m_Checked ?
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
/**
|
||||
* Draws the control
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
protected:
|
||||
// Settings
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -31,7 +31,7 @@ CImage::~CImage()
|
||||
{
|
||||
}
|
||||
|
||||
void CImage::Draw()
|
||||
void CImage::Draw(CCanvas2D& UNUSED(canvas))
|
||||
{
|
||||
m_pGUI.DrawSprite(m_Sprite, m_CachedActualSize);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ protected:
|
||||
/**
|
||||
* Draws the Image
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
};
|
||||
|
||||
@@ -1187,7 +1187,7 @@ void CInput::UpdateCachedSize()
|
||||
m_GeneratedPlaceholderTextValid = false;
|
||||
}
|
||||
|
||||
void CInput::Draw()
|
||||
void CInput::Draw(CCanvas2D& UNUSED(canvas))
|
||||
{
|
||||
if (m_CursorBlinkRate > 0.0)
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ protected:
|
||||
/**
|
||||
* Draws the Text
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
/**
|
||||
* Calculate m_CharacterPosition
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ protected:
|
||||
/**
|
||||
* Draws the List box
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
virtual void CreateJSObject();
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
static float GetShallowPassageHeight();
|
||||
|
||||
protected:
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
/**
|
||||
* @see IGUIObject#HandleMessage()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ protected:
|
||||
/**
|
||||
* Draws the progress bar
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
/**
|
||||
* @see IGUIObject#HandleMessage()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ protected:
|
||||
/**
|
||||
* Draws the Text
|
||||
*/
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
virtual void CreateJSObject();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -53,7 +53,7 @@ protected:
|
||||
*/
|
||||
virtual void HandleMessage(SGUIMessage& Message);
|
||||
|
||||
virtual void Draw();
|
||||
virtual void Draw(CCanvas2D& canvas);
|
||||
|
||||
virtual float GetBufferedZ() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user