diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp
index ea7f157da9..5be0cb61b4 100644
--- a/source/graphics/ModelDef.cpp
+++ b/source/graphics/ModelDef.cpp
@@ -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
@@ -15,17 +15,14 @@
* along with 0 A.D. If not, see .
*/
-/*
- * Defines a raw 3d model.
- */
-
#include "precompiled.h"
#include "ModelDef.h"
+
#include "graphics/SkeletonAnimDef.h"
#include "lib/sysdep/arch/x86_x64/simd.h"
-#include "ps/FileIo.h"
#include "maths/Vector4D.h"
+#include "ps/FileIo.h"
#if COMPILER_HAS_SSE
# include
@@ -203,10 +200,11 @@ static void SkinPointsAndNormalsSSE(
const CMatrix3D& mtx = newPoseMatrices[blendIndices[j]];
// Loads matrix to xmm registers.
- col0 = _mm_load_ps(mtx._data);
- col1 = _mm_load_ps(mtx._data + 4);
- col2 = _mm_load_ps(mtx._data + 8);
- col3 = _mm_load_ps(mtx._data + 12);
+ const float* data = mtx.AsFloatArray();
+ col0 = _mm_load_ps(data);
+ col1 = _mm_load_ps(data + 4);
+ col2 = _mm_load_ps(data + 8);
+ col3 = _mm_load_ps(data + 12);
// Loads and computes vertex coordinates.
vec0 = _mm_load1_ps(&vtx.m_Coords.X); // v0 = [x, x, x, x]
diff --git a/source/graphics/TerrainTextureEntry.cpp b/source/graphics/TerrainTextureEntry.cpp
index 24a5521130..83fec62102 100644
--- a/source/graphics/TerrainTextureEntry.cpp
+++ b/source/graphics/TerrainTextureEntry.cpp
@@ -185,8 +185,3 @@ void CTerrainTextureEntry::BuildBaseColor()
m_BaseColorValid = true;
}
}
-
-const float* CTerrainTextureEntry::GetTextureMatrix() const
-{
- return &m_TextureMatrix._11;
-}
diff --git a/source/graphics/TerrainTextureEntry.h b/source/graphics/TerrainTextureEntry.h
index b6722dfba7..4ae1647b76 100644
--- a/source/graphics/TerrainTextureEntry.h
+++ b/source/graphics/TerrainTextureEntry.h
@@ -50,7 +50,7 @@ public:
// Returns a matrix of the form [c 0 -s 0; -s 0 -c 0; 0 0 0 0; 0 0 0 1]
// mapping world-space (x,y,z,1) coordinates onto (u,v,0,1) texcoords
- const float* GetTextureMatrix() const;
+ const CMatrix3D& GetTextureMatrix() const { return m_TextureMatrix; }
// Used in Atlas to retrieve a texture for previews. Can't use textures
// directly because they're required on CPU side. Another solution is to
diff --git a/source/graphics/TerritoryTexture.cpp b/source/graphics/TerritoryTexture.cpp
index 836dcd800a..b84db8cd6c 100644
--- a/source/graphics/TerritoryTexture.cpp
+++ b/source/graphics/TerritoryTexture.cpp
@@ -63,10 +63,10 @@ Renderer::Backend::GL::CTexture* CTerritoryTexture::GetTexture()
return m_Texture.get();
}
-const float* CTerritoryTexture::GetTextureMatrix()
+const CMatrix3D& CTerritoryTexture::GetTextureMatrix()
{
ENSURE(!UpdateDirty());
- return &m_TextureMatrix._11;
+ return m_TextureMatrix;
}
const CMatrix3D& CTerritoryTexture::GetMinimapTextureMatrix()
diff --git a/source/graphics/TerritoryTexture.h b/source/graphics/TerritoryTexture.h
index eddf4c71db..a61ab48cef 100644
--- a/source/graphics/TerritoryTexture.h
+++ b/source/graphics/TerritoryTexture.h
@@ -47,7 +47,7 @@ public:
* coordinates, in the form expected by a matrix uniform.
* This must only be called after UpdateIfNeeded.
*/
- const float* GetTextureMatrix();
+ const CMatrix3D& GetTextureMatrix();
/**
* Returns a matrix to map (0,0)-(1,1) texture coordinates onto texture
diff --git a/source/maths/Matrix3D.h b/source/maths/Matrix3D.h
index 92b77fd8a3..0cbea2b9a8 100644
--- a/source/maths/Matrix3D.h
+++ b/source/maths/Matrix3D.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
@@ -28,7 +28,6 @@
class CQuaternion;
-/////////////////////////////////////////////////////////////////////////
// CMatrix3D: a 4x4 matrix class for common operations in 3D
class CMatrix3D
{
@@ -37,8 +36,10 @@ public:
// or via a flat or 2d array
// NOTE: _xy means row x, column y in the mathematical notation of this matrix, so don't be
// fooled by the way they're listed below
- union {
- struct {
+ union
+ {
+ struct
+ {
float _11, _21, _31, _41;
float _12, _22, _32, _42;
float _13, _23, _33, _43;
@@ -320,6 +321,20 @@ public:
// rotate a vector by the transpose of this matrix
void RotateTransposed(const CVector3D& vector,CVector3D& result) const;
CVector3D RotateTransposed(const CVector3D& vector) const;
+
+ // Returns 16 element array of floats, e.g. for mat4 uniforms.
+ const float* AsFloatArray() const
+ {
+ // Additional check to prevent a weird compiler has a different
+ // alignement for an array and a class members.
+ static_assert(
+ sizeof(CMatrix3D) == sizeof(float) * 16u &&
+ offsetof(CMatrix3D, _data) == 0 &&
+ offsetof(CMatrix3D, _11) == 0 &&
+ offsetof(CMatrix3D, _44) == sizeof(float) * 15u,
+ "CMatrix3D should be properly layouted to use AsFloatArray");
+ return _data;
+ }
};
#endif // INCLUDED_MATRIX3D
diff --git a/source/renderer/backend/gl/ShaderProgram.cpp b/source/renderer/backend/gl/ShaderProgram.cpp
index 33fb33ce59..1ad59bda55 100644
--- a/source/renderer/backend/gl/ShaderProgram.cpp
+++ b/source/renderer/backend/gl/ShaderProgram.cpp
@@ -781,7 +781,7 @@ public:
if (id.first != -1)
{
if (id.second == GL_FLOAT_MAT4)
- glUniformMatrix4fv(id.first, 1, GL_FALSE, &v._11);
+ glUniformMatrix4fv(id.first, 1, GL_FALSE, v.AsFloatArray());
else
LOGERROR("CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)");
}