Index: binaries/data/mods/public/shaders/arb/los_interp.xml
===================================================================
--- binaries/data/mods/public/shaders/arb/los_interp.xml
+++ binaries/data/mods/public/shaders/arb/los_interp.xml
@@ -5,7 +5,7 @@
-
+
Index: binaries/data/mods/public/shaders/arb/terrain_base.xml
===================================================================
--- binaries/data/mods/public/shaders/arb/terrain_base.xml
+++ binaries/data/mods/public/shaders/arb/terrain_base.xml
@@ -3,11 +3,11 @@
-
+
-
+
Index: binaries/data/mods/public/shaders/arb/terrain_blend.xml
===================================================================
--- binaries/data/mods/public/shaders/arb/terrain_blend.xml
+++ binaries/data/mods/public/shaders/arb/terrain_blend.xml
@@ -5,11 +5,11 @@
-
+
-
+
Index: binaries/data/mods/public/shaders/arb/terrain_common.vp
===================================================================
--- binaries/data/mods/public/shaders/arb/terrain_common.vp
+++ binaries/data/mods/public/shaders/arb/terrain_common.vp
@@ -12,6 +12,11 @@
TEMP lighting;
+TEMP terrainTextureTransform;
+MOV terrainTextureTransform, textureTransform;
+MOV terrainTextureTransform.z, -textureTransform.y;
+MOV terrainTextureTransform.w, 0;
+
//// Compute position and normal:
ATTRIB position = vertex.position;
@@ -40,8 +45,8 @@
// Compute texcoords from position and terrain-texture-dependent transform.
// textureTransform is stored as [c, -s, s, 0],
// and we want texcoord = (x*c + z*-s, x*-s + z*-c, 0, 1)
- DP3 result.texcoord[0].x, textureTransform.xyww, position.xzww;
- DP3 result.texcoord[0].y, -textureTransform.zxww, position.xzww;
+ DP3 result.texcoord[0].x, terrainTextureTransform.xyww, position.xzww;
+ DP3 result.texcoord[0].y, -terrainTextureTransform.zxww, position.xzww;
MOV result.texcoord[0].z, 0;
MOV result.texcoord[0].w, 1;
#endif
Index: binaries/data/mods/public/shaders/arb/terrain_decal.xml
===================================================================
--- binaries/data/mods/public/shaders/arb/terrain_decal.xml
+++ binaries/data/mods/public/shaders/arb/terrain_decal.xml
@@ -5,11 +5,11 @@
-
+
-
+
Index: binaries/data/mods/public/shaders/arb/water_simple.xml
===================================================================
--- binaries/data/mods/public/shaders/arb/water_simple.xml
+++ binaries/data/mods/public/shaders/arb/water_simple.xml
@@ -4,7 +4,7 @@
-
+
Index: binaries/data/mods/public/shaders/glsl/los_interp.fs
===================================================================
--- binaries/data/mods/public/shaders/glsl/los_interp.fs
+++ binaries/data/mods/public/shaders/glsl/los_interp.fs
@@ -4,7 +4,7 @@
uniform sampler2D losTex1, losTex2;
-uniform vec3 delta;
+uniform float delta;
void main(void)
@@ -12,6 +12,6 @@
float los2 = texture2D(losTex1, v_tex).a;
float los1 = texture2D(losTex2, v_tex).a;
- gl_FragColor.a = mix(los1, los2, clamp(delta.r, 0.0, 1.0));
+ gl_FragColor.a = mix(los1, los2, clamp(delta, 0.0, 1.0));
}
Index: binaries/data/mods/public/shaders/glsl/model_common.vs
===================================================================
--- binaries/data/mods/public/shaders/glsl/model_common.vs
+++ binaries/data/mods/public/shaders/glsl/model_common.vs
@@ -15,7 +15,7 @@
uniform mat4 instancingTransform;
#if USE_WIND
- uniform vec4 sim_time;
+ uniform float sim_time;
uniform vec4 windData;
#endif
@@ -112,9 +112,9 @@
vec4 cosVec;
// these determine the speed of the wind's "cosine" waves.
cosVec.w = 0.0;
- cosVec.x = sim_time.x * modelPos[0] + position.x;
- cosVec.y = sim_time.x * modelPos[2] / 3.0 + instancingTransform[3][0];
- cosVec.z = sim_time.x * abswind / 4.0 + position.z;
+ cosVec.x = sim_time * modelPos[0] + position.x;
+ cosVec.y = sim_time * modelPos[2] / 3.0 + instancingTransform[3][0];
+ cosVec.z = sim_time * abswind / 4.0 + position.z;
// calculate "cosines" in parallel, using a smoothed triangle wave
cosVec = fakeCos(cosVec);
Index: source/graphics/Canvas2D.cpp
===================================================================
--- source/graphics/Canvas2D.cpp
+++ source/graphics/Canvas2D.cpp
@@ -37,14 +37,24 @@
// Array of 2D elements unrolled into 1D array.
using PlaneArray2D = std::array;
+struct SBindingSlots
+{
+ int32_t transform;
+ int32_t colorAdd;
+ int32_t colorMul;
+ int32_t grayscaleFactor;
+ int32_t tex;
+};
+
inline void DrawTextureImpl(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- Renderer::Backend::GL::CShaderProgram* shader, const CTexturePtr& texture,
- const PlaneArray2D& vertices, PlaneArray2D uvs,
- const CColor& multiply, const CColor& add, const float grayscaleFactor)
+ const CTexturePtr& texture, const PlaneArray2D& vertices, PlaneArray2D uvs,
+ const CColor& multiply, const CColor& add, const float grayscaleFactor,
+ const SBindingSlots& bindingSlots)
{
texture->UploadBackendTextureIfNeeded(deviceCommandContext);
- shader->BindTexture(str_tex, texture->GetBackendTexture());
+ deviceCommandContext->SetTexture(
+ bindingSlots.tex, texture->GetBackendTexture());
for (size_t idx = 0; idx < uvs.size(); idx += 2)
{
if (texture->GetWidth() > 0.0f)
@@ -53,9 +63,9 @@
uvs[idx + 1] /= texture->GetHeight();
}
- shader->Uniform(str_colorAdd, add);
- shader->Uniform(str_colorMul, multiply);
- shader->Uniform(str_grayscaleFactor, grayscaleFactor);
+ deviceCommandContext->SetUniform(bindingSlots.colorAdd, add.AsFloatArray());
+ deviceCommandContext->SetUniform(bindingSlots.colorMul, multiply.AsFloatArray());
+ deviceCommandContext->SetUniform(bindingSlots.grayscaleFactor, grayscaleFactor);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
@@ -87,12 +97,22 @@
CShaderDefines defines;
Tech = g_Renderer.GetShaderManager().LoadEffect(str_canvas2d, defines);
+ // The canvas technique must be loaded because we can't render UI without it.
ENSURE(Tech);
DeviceCommandContext->SetGraphicsPipelineState(
Tech->GetGraphicsPipelineStateDesc());
DeviceCommandContext->BeginPass();
- Renderer::Backend::GL::CShaderProgram* shader = Tech->GetShader();
- shader->Uniform(str_transform, GetDefaultGuiMatrix());
+ Renderer::Backend::IShaderProgram* shader = Tech->GetShader();
+
+ BindingSlots.transform = shader->GetBindingSlot(str_transform);
+ 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 = GetDefaultGuiMatrix();
+ DeviceCommandContext->SetUniform(
+ BindingSlots.transform, transform.AsFloatArray());
}
void UnbindTech()
@@ -106,6 +126,10 @@
Renderer::Backend::GL::CDeviceCommandContext* DeviceCommandContext;
CShaderTechniquePtr Tech;
+
+ // We assume that the shader can't be destroyed while it's bound. So these
+ // bindings remain valid while the shader is alive.
+ SBindingSlots BindingSlots;
};
CCanvas2D::CCanvas2D(
@@ -251,11 +275,16 @@
m->BindTechIfNeeded();
- Renderer::Backend::GL::CShaderProgram* shader = m->Tech->GetShader();
- shader->BindTexture(str_tex, g_Renderer.GetTextureManager().GetAlphaGradientTexture()->GetBackendTexture());
- shader->Uniform(str_colorAdd, CColor(0.0f, 0.0f, 0.0f, 0.0f));
- shader->Uniform(str_colorMul, color);
- shader->Uniform(str_grayscaleFactor, 0.0f);
+ m->DeviceCommandContext->SetTexture(
+ m->BindingSlots.tex,
+ g_Renderer.GetTextureManager().GetAlphaGradientTexture()->GetBackendTexture());
+ const CColor colorAdd(0.0f, 0.0f, 0.0f, 0.0f);
+ m->DeviceCommandContext->SetUniform(
+ m->BindingSlots.colorAdd, colorAdd.AsFloatArray());
+ m->DeviceCommandContext->SetUniform(
+ m->BindingSlots.colorMul, color.AsFloatArray());
+ m->DeviceCommandContext->SetUniform(
+ m->BindingSlots.grayscaleFactor, 0.0f);
m->DeviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
@@ -290,9 +319,10 @@
m->BindTechIfNeeded();
DrawTextureImpl(
- m->DeviceCommandContext, m->Tech->GetShader(),
+ m->DeviceCommandContext,
g_Renderer.GetTextureManager().GetTransparentTexture(),
- vertices, uvs, CColor(0.0f, 0.0f, 0.0f, 0.0f), color, 0.0f);
+ vertices, uvs, CColor(0.0f, 0.0f, 0.0f, 0.0f), color, 0.0f,
+ m->BindingSlots);
}
void CCanvas2D::DrawTexture(CTexturePtr texture, const CRect& destination)
@@ -326,18 +356,19 @@
};
m->BindTechIfNeeded();
- DrawTextureImpl(m->DeviceCommandContext, m->Tech->GetShader(),
- texture, vertices, uvs, multiply, add, grayscaleFactor);
+ DrawTextureImpl(
+ m->DeviceCommandContext, texture, vertices, uvs,
+ multiply, add, grayscaleFactor, m->BindingSlots);
}
void CCanvas2D::DrawText(CTextRenderer& textRenderer)
{
m->BindTechIfNeeded();
- Renderer::Backend::GL::CShaderProgram* shader = m->Tech->GetShader();
- shader->Uniform(str_grayscaleFactor, 0.0f);
+ m->DeviceCommandContext->SetUniform(
+ m->BindingSlots.grayscaleFactor, 0.0f);
- textRenderer.Render(m->DeviceCommandContext, shader, GetDefaultGuiMatrix());
+ textRenderer.Render(m->DeviceCommandContext, m->Tech->GetShader(), GetDefaultGuiMatrix());
}
void CCanvas2D::Flush()
Index: source/graphics/Color.h
===================================================================
--- source/graphics/Color.h
+++ source/graphics/Color.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
@@ -21,6 +21,7 @@
#include "graphics/SColor.h"
#include "maths/Vector3D.h"
#include "maths/Vector4D.h"
+#include "ps/containers/Span.h"
#include "ps/CStrForward.h"
// Simple defines for 3 and 4 component floating point colors - just map to
@@ -66,7 +67,7 @@
}
// For passing to uniform as vec3/vec4.
- const float* AsFloatArray() const
+ PS::span AsFloatArray() const
{
// Additional check to prevent a weird compiler has a different
// alignement for an array and a class members.
@@ -77,7 +78,7 @@
offsetof(CColor, b) == sizeof(float) * 2u &&
offsetof(CColor, a) == sizeof(float) * 3u,
"CColor should be properly layouted to use AsFloatArray");
- return &r;
+ return PS::span(&r, 4);
}
// For passing to CRenderer:
Index: source/graphics/LOSTexture.cpp
===================================================================
--- source/graphics/LOSTexture.cpp
+++ source/graphics/LOSTexture.cpp
@@ -80,7 +80,7 @@
bool CLOSTexture::CreateShader()
{
m_SmoothTech = g_Renderer.GetShaderManager().LoadEffect(str_los_interp);
- Renderer::Backend::GL::CShaderProgram* shader = m_SmoothTech->GetShader();
+ Renderer::Backend::IShaderProgram* shader = m_SmoothTech->GetShader();
m_ShaderInitialized = m_SmoothTech && shader;
@@ -145,12 +145,16 @@
m_SmoothTech->GetGraphicsPipelineStateDesc());
deviceCommandContext->BeginPass();
- Renderer::Backend::GL::CShaderProgram* shader = m_SmoothTech->GetShader();
+ Renderer::Backend::IShaderProgram* shader = m_SmoothTech->GetShader();
- shader->BindTexture(str_losTex1, m_Texture.get());
- shader->BindTexture(str_losTex2, m_SmoothTextures[m_WhichTexture].get());
-
- shader->Uniform(str_delta, (float)g_Renderer.GetTimeManager().GetFrameDelta() * 4.0f, 0.0f, 0.0f, 0.0f);
+ deviceCommandContext->SetTexture(
+ shader->GetBindingSlot(str_losTex1), m_Texture.get());
+ deviceCommandContext->SetTexture(
+ shader->GetBindingSlot(str_losTex2), m_SmoothTextures[m_WhichTexture].get());
+
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_delta),
+ static_cast(g_Renderer.GetTimeManager().GetFrameDelta()) * 4.0f);
const SViewPort oldVp = g_Renderer.GetViewport();
const SViewPort vp =
Index: source/graphics/MiniMapTexture.cpp
===================================================================
--- source/graphics/MiniMapTexture.cpp
+++ source/graphics/MiniMapTexture.cpp
@@ -366,7 +366,7 @@
const float invTileMapSize = 1.0f / static_cast(TERRAIN_TILE_SIZE * m_MapSize);
const float texCoordMax = m_TerrainTexture ? static_cast(m_MapSize - 1) / m_TerrainTexture->GetWidth() : 1.0f;
- Renderer::Backend::GL::CShaderProgram* shader;
+ Renderer::Backend::IShaderProgram* shader = nullptr;
CShaderTechniquePtr tech;
CShaderDefines baseDefines;
@@ -380,7 +380,10 @@
shader = tech->GetShader();
if (m_TerrainTexture)
- shader->BindTexture(str_baseTex, m_TerrainTexture.get());
+ {
+ deviceCommandContext->SetTexture(
+ shader->GetBindingSlot(str_baseTex), m_TerrainTexture.get());
+ }
CMatrix3D baseTransform;
baseTransform.SetIdentity();
@@ -390,8 +393,10 @@
CMatrix3D terrainTransform;
terrainTransform.SetIdentity();
terrainTransform.Scale(texCoordMax, texCoordMax, 1.0f);
- shader->Uniform(str_transform, baseTransform);
- shader->Uniform(str_textureTransform, terrainTransform);
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray());
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_textureTransform), terrainTransform.AsFloatArray());
if (m_TerrainTexture)
DrawTexture(deviceCommandContext);
@@ -414,9 +419,13 @@
// Draw territory boundaries
CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture();
- shader->BindTexture(str_baseTex, territoryTexture.GetTexture());
- shader->Uniform(str_transform, baseTransform);
- shader->Uniform(str_textureTransform, territoryTexture.GetMinimapTextureMatrix());
+ deviceCommandContext->SetTexture(
+ shader->GetBindingSlot(str_baseTex), territoryTexture.GetTexture());
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray());
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_textureTransform),
+ territoryTexture.GetMinimapTextureMatrix().AsFloatArray());
DrawTexture(deviceCommandContext);
deviceCommandContext->EndPass();
@@ -427,9 +436,13 @@
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
deviceCommandContext->BeginPass();
- shader->BindTexture(str_baseTex, losTexture.GetTexture());
- shader->Uniform(str_transform, baseTransform);
- shader->Uniform(str_textureTransform, losTexture.GetMinimapTextureMatrix());
+ deviceCommandContext->SetTexture(
+ shader->GetBindingSlot(str_baseTex), losTexture.GetTexture());
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray());
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_textureTransform),
+ losTexture.GetMinimapTextureMatrix().AsFloatArray());
DrawTexture(deviceCommandContext);
@@ -442,7 +455,8 @@
tech->GetGraphicsPipelineStateDesc());
deviceCommandContext->BeginPass();
shader = tech->GetShader();
- shader->Uniform(str_transform, baseTransform);
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray());
CMatrix3D unitMatrix;
unitMatrix.SetIdentity();
@@ -451,7 +465,8 @@
unitMatrix.Scale(unitScale * 2.0f, unitScale * 2.0f, 1.0f);
// Offset the coordinates to [-1, 1].
unitMatrix.Translate(CVector3D(-1.0f, -1.0f, 0.0f));
- shader->Uniform(str_transform, unitMatrix);
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), unitMatrix.AsFloatArray());
if (doUpdate)
{
Index: source/graphics/ModelDef.cpp
===================================================================
--- source/graphics/ModelDef.cpp
+++ source/graphics/ModelDef.cpp
@@ -200,7 +200,7 @@
const CMatrix3D& mtx = newPoseMatrices[blendIndices[j]];
// Loads matrix to xmm registers.
- const float* data = mtx.AsFloatArray();
+ const float* data = mtx.AsFloatArray().data();
col0 = _mm_load_ps(data);
col1 = _mm_load_ps(data + 4);
col2 = _mm_load_ps(data + 8);
Index: source/graphics/ParticleEmitter.h
===================================================================
--- source/graphics/ParticleEmitter.h
+++ source/graphics/ParticleEmitter.h
@@ -22,7 +22,7 @@
#include "graphics/ParticleEmitterType.h"
#include "maths/Quaternion.h"
#include "renderer/backend/gl/DeviceCommandContext.h"
-#include "renderer/backend/gl/ShaderProgram.h"
+#include "renderer/backend/IShaderProgram.h"
#include "renderer/VertexArray.h"
#include