diff --git a/binaries/data/mods/mod/shaders/arb/canvas2d.fp b/binaries/data/mods/mod/shaders/arb/canvas2d.fp
new file mode 100644
index 0000000000..2de2d68706
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/arb/canvas2d.fp
@@ -0,0 +1,15 @@
+!!ARBfp1.0
+
+TEMP colorTex;
+TEX colorTex, fragment.texcoord[0], texture[0], 2D;
+
+PARAM colorAdd = program.local[1];
+PARAM colorMul = program.local[2];
+
+TEMP color;
+MUL color, colorTex, colorMul;
+ADD color, color, colorAdd;
+
+MOV result.color, color;
+
+END
diff --git a/binaries/data/mods/mod/shaders/arb/canvas2d.vp b/binaries/data/mods/mod/shaders/arb/canvas2d.vp
new file mode 100644
index 0000000000..56d364990f
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/arb/canvas2d.vp
@@ -0,0 +1,16 @@
+!!ARBvp1.0
+
+PARAM transform[4] = { program.local[0..3] };
+
+TEMP position;
+
+DP4 position.x, transform[0], vertex.position;
+DP4 position.y, transform[1], vertex.position;
+MOV position.z, 0.0;
+MOV position.w, 1.0;
+
+MOV result.position, position;
+
+MOV result.texcoord[0], vertex.texcoord[0];
+
+END
diff --git a/binaries/data/mods/mod/shaders/arb/canvas2d.xml b/binaries/data/mods/mod/shaders/arb/canvas2d.xml
new file mode 100644
index 0000000000..c32d39265f
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/arb/canvas2d.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/mod/shaders/effects/canvas2d.xml b/binaries/data/mods/mod/shaders/effects/canvas2d.xml
new file mode 100644
index 0000000000..5cd236fa47
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/effects/canvas2d.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/mod/shaders/glsl/canvas2d.fs b/binaries/data/mods/mod/shaders/glsl/canvas2d.fs
new file mode 100644
index 0000000000..b39ff8af0c
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/glsl/canvas2d.fs
@@ -0,0 +1,12 @@
+#version 110
+
+uniform vec4 colorAdd;
+uniform vec4 colorMul;
+uniform sampler2D tex;
+
+varying vec2 v_uv;
+
+void main()
+{
+ gl_FragColor = clamp(texture2D(tex, v_uv) * colorMul + colorAdd, 0.0, 1.0);
+}
diff --git a/binaries/data/mods/mod/shaders/glsl/canvas2d.vs b/binaries/data/mods/mod/shaders/glsl/canvas2d.vs
new file mode 100644
index 0000000000..9da970c42f
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/glsl/canvas2d.vs
@@ -0,0 +1,14 @@
+#version 110
+
+uniform mat4 transform;
+
+attribute vec2 a_vertex;
+attribute vec2 a_uv0;
+
+varying vec2 v_uv;
+
+void main()
+{
+ v_uv = a_uv0;
+ gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
+}
diff --git a/binaries/data/mods/mod/shaders/glsl/canvas2d.xml b/binaries/data/mods/mod/shaders/glsl/canvas2d.xml
new file mode 100644
index 0000000000..65ea4cd4fc
--- /dev/null
+++ b/binaries/data/mods/mod/shaders/glsl/canvas2d.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/graphics/Canvas2D.cpp b/source/graphics/Canvas2D.cpp
index c67f448e3c..d7f1149a81 100644
--- a/source/graphics/Canvas2D.cpp
+++ b/source/graphics/Canvas2D.cpp
@@ -21,11 +21,15 @@
#include "graphics/Color.h"
#include "graphics/ShaderManager.h"
+#include "graphics/TextureManager.h"
#include "gui/GUIMatrix.h"
+#include "maths/Rect.h"
#include "maths/Vector2D.h"
#include "ps/CStrInternStatic.h"
#include "renderer/Renderer.h"
+#include
+
void CCanvas2D::DrawLine(const std::vector& points, const float width, const CColor& color)
{
std::vector vertices;
@@ -45,8 +49,8 @@ void CCanvas2D::DrawLine(const std::vector& points, const float width
CShaderProgramPtr shader = tech->GetShader();
shader->Uniform(str_transform, transform);
- shader->Uniform(str_color, color );
- shader->VertexPointer(3, GL_FLOAT, 0, &vertices[0]);
+ shader->Uniform(str_color, color);
+ shader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
shader->AssertPointersBound();
#if !CONFIG2_GLES
@@ -62,3 +66,35 @@ void CCanvas2D::DrawLine(const std::vector& points, const float width
tech->EndPass();
}
+
+void CCanvas2D::DrawRect(const CRect& rect, const CColor& color)
+{
+ const std::array uvs = {
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
+ };
+ const std::array vertices = {
+ rect.left, rect.bottom,
+ rect.right, rect.bottom,
+ rect.right, rect.top,
+ rect.left, rect.top
+ };
+
+ CShaderDefines defines;
+ CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(
+ str_canvas2d, g_Renderer.GetSystemShaderDefines(), defines);
+ tech->BeginPass();
+ CShaderProgramPtr shader = tech->GetShader();
+
+ shader->BindTexture(str_tex, g_Renderer.GetTextureManager().GetWhiteTexture());
+ shader->Uniform(str_transform, GetDefaultGuiMatrix());
+ shader->Uniform(str_colorAdd, color);
+ shader->Uniform(str_colorMul, CColor(0.0f, 0.0f, 0.0f, 0.0f));
+ shader->VertexPointer(2, GL_FLOAT, 0, vertices.data());
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, uvs.data());
+ shader->AssertPointersBound();
+
+ if (!g_Renderer.DoSkipSubmit())
+ glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size() / 2);
+
+ tech->EndPass();
+}
diff --git a/source/graphics/Canvas2D.h b/source/graphics/Canvas2D.h
index 40a5fc74de..0d5d09cd8f 100644
--- a/source/graphics/Canvas2D.h
+++ b/source/graphics/Canvas2D.h
@@ -22,6 +22,8 @@
#include
+class CRect;
+
struct CColor;
// Encapsulates 2D drawing functionality to hide and optimize
@@ -30,6 +32,8 @@ class CCanvas2D
{
public:
void DrawLine(const std::vector& points, const float width, const CColor& color);
+
+ void DrawRect(const CRect& rect, const CColor& color);
};
#endif // INCLUDED_CANVAS2D
diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp
index 9e25995ae3..f6e23e15c4 100644
--- a/source/graphics/TextureManager.cpp
+++ b/source/graphics/TextureManager.cpp
@@ -19,6 +19,7 @@
#include "TextureManager.h"
+#include "graphics/Color.h"
#include "graphics/TextureConverter.h"
#include "lib/allocators/shared_ptr.h"
#include "lib/file/vfs/vfs_tree.h"
@@ -38,6 +39,53 @@
#include
#include
+class SingleColorTexture
+{
+public:
+ SingleColorTexture(const CColor& color, PIVFS vfs, const VfsPath& pathPlaceholder, const bool disableGL, CTextureManagerImpl* textureManager)
+ {
+ const SColor4ub color32 = color.AsSColor4ub();
+ // Construct 1x1 32-bit texture
+ std::shared_ptr data(new u8[3], ArrayDeleter());
+ data.get()[0] = color32.R;
+ data.get()[1] = color32.G;
+ data.get()[2] = color32.B;
+ data.get()[3] = color32.A;
+
+ Tex t;
+ ignore_result(t.wrap(1, 1, 32, TEX_ALPHA, data, 0));
+
+ m_Handle = ogl_tex_wrap(&t, vfs, pathPlaceholder);
+ ignore_result(ogl_tex_set_filter(m_Handle, GL_LINEAR));
+ if (!disableGL)
+ ignore_result(ogl_tex_upload(m_Handle));
+
+ CTextureProperties props(pathPlaceholder);
+ m_Texture = CTexturePtr(new CTexture(m_Handle, props, textureManager));
+ m_Texture->m_State = CTexture::LOADED;
+ m_Texture->m_Self = m_Texture;
+ }
+
+ ~SingleColorTexture()
+ {
+ ignore_result(ogl_tex_free(m_Handle));
+ }
+
+ CTexturePtr GetTexture()
+ {
+ return m_Texture;
+ }
+
+ Handle GetHandle()
+ {
+ return m_Handle;
+ }
+
+private:
+ Handle m_Handle;
+ CTexturePtr m_Texture;
+};
+
struct TPhash
{
std::size_t operator()(CTextureProperties const& a) const
@@ -80,8 +128,11 @@ class CTextureManagerImpl
friend class CTexture;
public:
CTextureManagerImpl(PIVFS vfs, bool highQuality, bool disableGL) :
- m_VFS(vfs), m_CacheLoader(vfs, L".dds"), m_DisableGL(disableGL), m_TextureConverter(vfs, highQuality),
- m_DefaultHandle(0), m_ErrorHandle(0)
+ m_VFS(vfs), m_CacheLoader(vfs, L".dds"), m_DisableGL(disableGL),
+ m_TextureConverter(vfs, highQuality), m_DefaultHandle(0),
+ m_ErrorTexture(CColor(1.0f, 0.0f, 1.0f, 1.0f), vfs, L"(error texture)", disableGL, this),
+ m_WhiteTexture(CColor(1.0f, 1.0f, 1.0f, 1.0f), vfs, L"(white texture)", disableGL, this),
+ m_TransparentTexture(CColor(0.0f, 0.0f, 0.0f, 0.0f), vfs, L"(transparent texture)", disableGL, this)
{
// Initialise some textures that will always be available,
// without needing to load any files
@@ -103,29 +154,6 @@ public:
ignore_result(ogl_tex_upload(m_DefaultHandle));
}
- // Error texture (magenta)
- if (!m_DisableGL)
- {
- // Construct 1x1 24-bit texture
- std::shared_ptr data(new u8[3], ArrayDeleter());
- data.get()[0] = 255;
- data.get()[1] = 0;
- data.get()[2] = 255;
- Tex t;
- ignore_result(t.wrap(1, 1, 24, 0, data, 0));
-
- m_ErrorHandle = ogl_tex_wrap(&t, m_VFS, L"(error texture)");
- ignore_result(ogl_tex_set_filter(m_ErrorHandle, GL_LINEAR));
- if (!m_DisableGL)
- ignore_result(ogl_tex_upload(m_ErrorHandle));
-
- // Construct a CTexture to return to callers who want an error texture
- CTextureProperties props(L"(error texture)");
- m_ErrorTexture = CTexturePtr(new CTexture(m_ErrorHandle, props, this));
- m_ErrorTexture->m_State = CTexture::LOADED;
- m_ErrorTexture->m_Self = m_ErrorTexture;
- }
-
// Allow hotloading of textures
RegisterFileReloadFunc(ReloadChangedFileCB, this);
}
@@ -135,12 +163,21 @@ public:
UnregisterFileReloadFunc(ReloadChangedFileCB, this);
ignore_result(ogl_tex_free(m_DefaultHandle));
- ignore_result(ogl_tex_free(m_ErrorHandle));
}
CTexturePtr GetErrorTexture()
{
- return m_ErrorTexture;
+ return m_ErrorTexture.GetTexture();
+ }
+
+ CTexturePtr GetWhiteTexture()
+ {
+ return m_WhiteTexture.GetTexture();
+ }
+
+ CTexturePtr GetTransparentTexture()
+ {
+ return m_TransparentTexture.GetTexture();
}
/**
@@ -182,7 +219,7 @@ public:
LOGERROR("Texture failed to load; \"%s\"", texture->m_Properties.m_Path.string8());
// Replace with error texture to make it obvious
- texture->SetHandle(m_ErrorHandle);
+ texture->SetHandle(m_ErrorTexture.GetHandle());
return;
}
@@ -224,7 +261,7 @@ public:
ogl_tex_free(h);
// Replace with error texture to make it obvious
- texture->SetHandle(m_ErrorHandle);
+ texture->SetHandle(m_ErrorTexture.GetHandle());
return;
}
@@ -279,7 +316,7 @@ public:
// No source file or archive cache was found, so we can't load the
// real texture at all - return the error texture instead
LOGERROR("CCacheLoader failed to find archived or source file for: \"%s\"", texture->m_Properties.m_Path.string8());
- texture->SetHandle(m_ErrorHandle);
+ texture->SetHandle(m_ErrorTexture.GetHandle());
return true;
}
}
@@ -352,7 +389,7 @@ public:
else
{
LOGERROR("Texture failed to convert: \"%s\"", texture->m_Properties.m_Path.string8());
- texture->SetHandle(m_ErrorHandle);
+ texture->SetHandle(m_ErrorTexture.GetHandle());
}
texture->m_State = CTexture::LOADED;
return true;
@@ -503,8 +540,9 @@ private:
CTextureConverter m_TextureConverter;
Handle m_DefaultHandle;
- Handle m_ErrorHandle;
- CTexturePtr m_ErrorTexture;
+ SingleColorTexture m_ErrorTexture;
+ SingleColorTexture m_WhiteTexture;
+ SingleColorTexture m_TransparentTexture;
// Cache of all loaded textures
using TextureCache =
@@ -662,6 +700,16 @@ CTexturePtr CTextureManager::GetErrorTexture()
return m->GetErrorTexture();
}
+CTexturePtr CTextureManager::GetWhiteTexture()
+{
+ return m->GetWhiteTexture();
+}
+
+CTexturePtr CTextureManager::GetTransparentTexture()
+{
+ return m->GetTransparentTexture();
+}
+
bool CTextureManager::MakeProgress()
{
return m->MakeProgress();
diff --git a/source/graphics/TextureManager.h b/source/graphics/TextureManager.h
index 0c7809df90..fb6adad372 100644
--- a/source/graphics/TextureManager.h
+++ b/source/graphics/TextureManager.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* 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
@@ -94,6 +94,16 @@ public:
*/
CTexturePtr GetErrorTexture();
+ /**
+ * Returns a single color RGBA texture with CColor(1.0f, 1.0f, 1.0f, 1.0f).
+ */
+ CTexturePtr GetWhiteTexture();
+
+ /**
+ * Returns a single color RGBA texture with CColor(0.0f, 0.0f, 0.0f, 0.0f).
+ */
+ CTexturePtr GetTransparentTexture();
+
/**
* Work on asynchronous texture loading operations, if any.
* Returns true if it did any work.
@@ -209,6 +219,7 @@ private:
class CTexture
{
friend class CTextureManagerImpl;
+ friend class SingleColorTexture;
friend struct TextureCacheCmp;
friend struct TPequal_to;
friend struct TPhash;
diff --git a/source/gui/ObjectTypes/CGUIDummyObject.h b/source/gui/ObjectTypes/CGUIDummyObject.h
index 24f353c196..9ee74d353e 100644
--- a/source/gui/ObjectTypes/CGUIDummyObject.h
+++ b/source/gui/ObjectTypes/CGUIDummyObject.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019 Wildfire Games.
+/* 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
diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp
index a12ed58ba9..ea50ab22e4 100644
--- a/source/ps/CConsole.cpp
+++ b/source/ps/CConsole.cpp
@@ -24,6 +24,7 @@
#include "CConsole.h"
+#include "graphics/Canvas2D.h"
#include "graphics/FontMetrics.h"
#include "graphics/ShaderManager.h"
#include "graphics/TextRenderer.h"
@@ -49,6 +50,8 @@
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/JSON.h"
+#include
+
namespace
{
@@ -177,7 +180,6 @@ void CConsole::Update(const float deltaRealTime)
}
}
-//Render Manager.
void CConsole::Render()
{
if (! (m_bVisible || m_bToggle) ) return;
@@ -187,25 +189,16 @@ void CConsole::Render()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid);
- solidTech->BeginPass();
- CShaderProgramPtr solidShader = solidTech->GetShader();
-
- CMatrix3D transform = GetDefaultGuiMatrix();
-
- // animation: slide in from top of screen
- const float DeltaY = (1.0f - m_fVisibleFrac) * m_fHeight;
- transform.PostTranslate(m_fX, m_fY - DeltaY, 0.0f); // move to window position
- solidShader->Uniform(str_transform, transform);
-
- DrawWindow(solidShader);
-
- solidTech->EndPass();
+ DrawWindow();
CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text);
textTech->BeginPass();
CTextRenderer textRenderer(textTech->GetShader());
textRenderer.Font(CStrIntern(CONSOLE_FONT));
+ // animation: slide in from top of screen
+ CMatrix3D transform = GetDefaultGuiMatrix();
+ const float DeltaY = (1.0f - m_fVisibleFrac) * m_fHeight;
+ transform.PostTranslate(m_fX, m_fY - DeltaY, 0.0f); // move to window position
textRenderer.SetTransform(transform);
DrawHistory(textRenderer);
@@ -218,43 +211,32 @@ void CConsole::Render()
glDisable(GL_BLEND);
}
-
-void CConsole::DrawWindow(CShaderProgramPtr& shader)
+void CConsole::DrawWindow()
{
- float boxVerts[] = {
- m_fWidth, 0.0f,
- 1.0f, 0.0f,
- 1.0f, m_fHeight-1.0f,
- m_fWidth, m_fHeight-1.0f
+ std::vector points = {
+ CVector2D{m_fWidth, 0.0f},
+ CVector2D{1.0f, 0.0f},
+ CVector2D{1.0f, m_fHeight - 1.0f},
+ CVector2D{m_fWidth, m_fHeight - 1.0f},
+ CVector2D{m_fWidth, 0.0f}
};
+ for (CVector2D& point : points)
+ point += CVector2D{m_fX, m_fY - (1.0f - m_fVisibleFrac) * m_fHeight};
- shader->VertexPointer(2, GL_FLOAT, 0, boxVerts);
-
- // Draw Background
- // Set the color to a translucent blue
- shader->Uniform(str_color, 0.0f, 0.0f, 0.5f, 0.6f);
- shader->AssertPointersBound();
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- // Draw Border
- // Set the color to a translucent yellow
- shader->Uniform(str_color, 0.5f, 0.5f, 0.0f, 0.6f);
- shader->AssertPointersBound();
- glDrawArrays(GL_LINE_LOOP, 0, 4);
+ CCanvas2D canvas;
+ canvas.DrawRect(CRect(points[1], points[3]), CColor(0.0f, 0.0f, 0.5f, 0.6f));
+ canvas.DrawLine(points, 1.0f, CColor(0.5f, 0.5f, 0.0f, 0.6f));
if (m_fHeight > m_iFontHeight + 4)
{
- float lineVerts[] = {
- 0.0f, m_fHeight - (float)m_iFontHeight - 4.0f,
- m_fWidth, m_fHeight - (float)m_iFontHeight - 4.0f
+ points = {
+ CVector2D{0.0f, m_fHeight - static_cast(m_iFontHeight) - 4.0f},
+ CVector2D{m_fWidth, m_fHeight - static_cast(m_iFontHeight) - 4.0f}
};
- shader->VertexPointer(2, GL_FLOAT, 0, lineVerts);
- shader->AssertPointersBound();
- glDrawArrays(GL_LINES, 0, 2);
+ canvas.DrawLine(points, 1.0f, CColor(0.5f, 0.5f, 0.0f, 0.6f));
}
}
-
void CConsole::DrawHistory(CTextRenderer& textRenderer)
{
int i = 1;
diff --git a/source/ps/CConsole.h b/source/ps/CConsole.h
index 4e758129a1..7d779967d9 100644
--- a/source/ps/CConsole.h
+++ b/source/ps/CConsole.h
@@ -111,7 +111,7 @@ private:
bool m_bCursorVisState; // if the cursor should be drawn or not
double m_cursorBlinkRate; // cursor blink rate in seconds, if greater than 0.0
- void DrawWindow(CShaderProgramPtr& shader);
+ void DrawWindow();
void DrawHistory(CTextRenderer& textRenderer);
void DrawBuffer(CTextRenderer& textRenderer);
void DrawCursor(CTextRenderer& textRenderer);
diff --git a/source/ps/CStrInternStatic.h b/source/ps/CStrInternStatic.h
index d0b0cc34ff..9b711b7f31 100644
--- a/source/ps/CStrInternStatic.h
+++ b/source/ps/CStrInternStatic.h
@@ -90,6 +90,7 @@ X(blurTex4)
X(blurTex8)
X(brightness)
X(cameraPos)
+X(canvas2d)
X(color)
X(colorAdd)
X(colorMul)