diff --git a/source/graphics/Canvas2D.cpp b/source/graphics/Canvas2D.cpp
new file mode 100644
index 0000000000..c67f448e3c
--- /dev/null
+++ b/source/graphics/Canvas2D.cpp
@@ -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 .
+ */
+
+#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& points, const float width, const CColor& color)
+{
+ std::vector 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();
+}
diff --git a/source/graphics/Canvas2D.h b/source/graphics/Canvas2D.h
new file mode 100644
index 0000000000..40a5fc74de
--- /dev/null
+++ b/source/graphics/Canvas2D.h
@@ -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 .
+ */
+
+#ifndef INCLUDED_CANVAS2D
+#define INCLUDED_CANVAS2D
+
+#include "maths/Vector2D.h"
+
+#include
+
+struct CColor;
+
+// Encapsulates 2D drawing functionality to hide and optimize
+// low level API calls.
+class CCanvas2D
+{
+public:
+ void DrawLine(const std::vector& points, const float width, const CColor& color);
+};
+
+#endif // INCLUDED_CANVAS2D
diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp
index 6a55d21a99..a9efc2b91c 100644
--- a/source/gui/CGUI.cpp
+++ b/source/gui/CGUI.cpp
@@ -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))
diff --git a/source/gui/ObjectBases/IGUIObject.h b/source/gui/ObjectBases/IGUIObject.h
index 4fcad61c0b..6c47dfc4d3 100644
--- a/source/gui/ObjectBases/IGUIObject.h
+++ b/source/gui/ObjectBases/IGUIObject.h
@@ -37,6 +37,7 @@
#include