Index: binaries/data/mods/mod/shaders/arb/canvas2d.vp
===================================================================
--- binaries/data/mods/mod/shaders/arb/canvas2d.vp
+++ binaries/data/mods/mod/shaders/arb/canvas2d.vp
@@ -1,11 +1,14 @@
!!ARBvp1.0
-PARAM transform[4] = { program.local[0..3] };
+PARAM transform = program.local[0];
+PARAM translation = program.local[1];
TEMP position;
-DP4 position.x, transform[0], vertex.position;
-DP4 position.y, transform[1], vertex.position;
+MUL position, transform, vertex.position.xyxy;
+ADD position.x, position.x, position.y;
+ADD position.y, position.z, position.w;
+ADD position, position, translation;
MOV position.z, 0.0;
MOV position.w, 1.0;
Index: binaries/data/mods/mod/shaders/arb/canvas2d.xml
===================================================================
--- binaries/data/mods/mod/shaders/arb/canvas2d.xml
+++ binaries/data/mods/mod/shaders/arb/canvas2d.xml
@@ -4,7 +4,8 @@
-
+
+
Index: binaries/data/mods/mod/shaders/glsl/canvas2d.vs
===================================================================
--- binaries/data/mods/mod/shaders/glsl/canvas2d.vs
+++ binaries/data/mods/mod/shaders/glsl/canvas2d.vs
@@ -1,6 +1,7 @@
#version 110
-uniform mat4 transform;
+uniform vec4 transform;
+uniform vec2 translation;
attribute vec2 a_vertex;
attribute vec2 a_uv0;
@@ -10,5 +11,5 @@
void main()
{
v_uv = a_uv0;
- gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
+ gl_Position = vec4(mat2(transform.xy, transform.zw) * a_vertex + translation, 0.0, 1.0);
}
Index: source/graphics/Canvas2D.cpp
===================================================================
--- source/graphics/Canvas2D.cpp
+++ source/graphics/Canvas2D.cpp
@@ -39,6 +39,7 @@
struct SBindingSlots
{
int32_t transform;
+ int32_t translation;
int32_t colorAdd;
int32_t colorMul;
int32_t grayscaleFactor;
@@ -111,14 +112,19 @@
Renderer::Backend::IShaderProgram* shader = Tech->GetShader();
BindingSlots.transform = shader->GetBindingSlot(str_transform);
+ BindingSlots.translation = shader->GetBindingSlot(str_translation);
BindingSlots.colorAdd = shader->GetBindingSlot(str_colorAdd);
BindingSlots.colorMul = shader->GetBindingSlot(str_colorMul);
BindingSlots.grayscaleFactor = shader->GetBindingSlot(str_grayscaleFactor);
BindingSlots.tex = shader->GetBindingSlot(str_tex);
const CMatrix3D transform = GetTransform();
+ Translation = CVector2D(transform._14, transform._24);
DeviceCommandContext->SetUniform(
- BindingSlots.transform, transform.AsFloatArray());
+ BindingSlots.transform,
+ transform._11, transform._21, transform._12, transform._22);
+ DeviceCommandContext->SetUniform(
+ BindingSlots.translation, Translation.AsFloatArray());
}
void UnbindTech()
@@ -153,6 +159,7 @@
uint32_t WidthInPixels = 1;
uint32_t HeightInPixels = 1;
float Scale = 1.0f;
+ CVector2D Translation;
Renderer::Backend::IDeviceCommandContext* DeviceCommandContext = nullptr;
CShaderTechniquePtr Tech;
@@ -440,7 +447,7 @@
m->DeviceCommandContext->SetUniform(
m->BindingSlots.grayscaleFactor, 0.0f);
- textRenderer.Render(m->DeviceCommandContext, m->Tech->GetShader(), m->GetTransform());
+ textRenderer.Render(m->DeviceCommandContext, m->Tech->GetShader(), m->Translation);
}
void CCanvas2D::Flush()
Index: source/graphics/TextRenderer.h
===================================================================
--- source/graphics/TextRenderer.h
+++ source/graphics/TextRenderer.h
@@ -105,7 +105,7 @@
*/
void Render(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
- Renderer::Backend::IShaderProgram* shader, const CMatrix3D& transform);
+ Renderer::Backend::IShaderProgram* shader, const CVector2D& translation);
private:
friend struct SBatchCompare;
Index: source/graphics/TextRenderer.cpp
===================================================================
--- source/graphics/TextRenderer.cpp
+++ source/graphics/TextRenderer.cpp
@@ -203,7 +203,7 @@
void CTextRenderer::Render(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
- Renderer::Backend::IShaderProgram* shader, const CMatrix3D& transform)
+ Renderer::Backend::IShaderProgram* shader, const CVector2D& translation)
{
std::vector indexes;
std::vector vertexes;
@@ -225,11 +225,11 @@
}
const int32_t texBindingSlot = shader->GetBindingSlot(str_tex);
- const int32_t transformBindingSlot = shader->GetBindingSlot(str_transform);
+ const int32_t translationBindingSlot = shader->GetBindingSlot(str_translation);
const int32_t colorAddBindingSlot = shader->GetBindingSlot(str_colorAdd);
const int32_t colorMulBindingSlot = shader->GetBindingSlot(str_colorMul);
- bool transformChanged = false;
+ bool translationChanged = false;
CTexture* lastTexture = nullptr;
for (std::list::iterator it = m_Batches.begin(); it != m_Batches.end(); ++it)
@@ -247,11 +247,9 @@
if (batch.translate.X != 0.0f || batch.translate.Y != 0.0f)
{
- CMatrix3D localTransform;
- localTransform.SetTranslation(batch.translate.X, batch.translate.Y, 0.0f);
- localTransform = transform * localTransform;
- deviceCommandContext->SetUniform(transformBindingSlot, localTransform.AsFloatArray());
- transformChanged = true;
+ const CVector2D localTranslation = translation + batch.translate;
+ deviceCommandContext->SetUniform(translationBindingSlot, localTranslation.AsFloatArray());
+ translationChanged = true;
}
// ALPHA-only textures will have .rgb sampled as 0, so we need to
@@ -346,6 +344,6 @@
m_Batches.clear();
- if (transformChanged)
- deviceCommandContext->SetUniform(transformBindingSlot, transform.AsFloatArray());
+ if (translationChanged)
+ deviceCommandContext->SetUniform(translationBindingSlot, translation.AsFloatArray());
}
Index: source/maths/Vector2D.h
===================================================================
--- source/maths/Vector2D.h
+++ source/maths/Vector2D.h
@@ -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
@@ -18,6 +18,8 @@
#ifndef INCLUDED_VECTOR2D
#define INCLUDED_VECTOR2D
+#include "ps/containers/Span.h"
+
#include
class CSize2D;
@@ -160,6 +162,19 @@
void operator+=(const CSize2D& size);
void operator-=(const CSize2D& size);
+
+ // Returns 2 element array of floats, e.g. for vec2 uniforms.
+ PS::span AsFloatArray() const
+ {
+ // Additional check to prevent a weird compiler has a different
+ // alignement for an array and a class members.
+ static_assert(
+ sizeof(CVector2D) == sizeof(float) * 2u &&
+ offsetof(CVector2D, X) == 0 &&
+ offsetof(CVector2D, Y) == sizeof(float),
+ "Vector2D should be properly layouted to use AsFloatArray");
+ return PS::span(&X, 3);
+ }
public:
float X, Y;