cogl/matrix: Multiply using graphene matrices
At this point, we are still only changing CoglMatrix APIs internally, and it should still produce the same output as before. To achieve this, using graphens matrix implementation, we need to exploit some knowledge about conventions used in Cogl and graphene respectively. In Cogl, transformation matrices are equivalent to those of affine transformation matrices. The convention used by graphene, however, is to operate on matrices that are transposed compared to their affine counterparts. So for example, let's say we want to multiply the affine matrices A and B, to get C. A × B = C The first step is to convert A and B to graphene matrices. We do this by importing the floating point array, importing it directly using graphene. Cogl exports its matrix to a column major floating point array. When we import this in graphene, being row major, we end up with the same matrix, only transposed. Cogl Graphene A <===> Aᵀ B <===> Bᵀ We then multiply these imported matrices in reverse Bᵀ × Aᵀ which in turn, due to ABᵀ = BᵀAᵀ, gives us Bᵀ × Aᵀ = (A × B)ᵀ Our original goal was to find C, thus we know that A × B = C That means we can shuffle things around a bit. A × B = C Bᵀ × Aᵀ = (A × B)ᵀ Bᵀ × Aᵀ = Cᵀ With the same conversion as done when going from Cogl to graphene, only the other way around, we still end up effectively transposing the matrix during the conversion. Graphene Cogl Cᵀ <===> C Thus when converting Cᵀ to Cogl, we in fact end up with C. (Explanation authored by Jonas Ådahl) https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
This commit is contained in:
parent
2b9ce99ff2
commit
02a30f2a22
@ -326,32 +326,22 @@ matrix_multiply_array_with_flags (CoglMatrix *result,
|
|||||||
matrix_multiply4x4 ((float *)result, (float *)result, array);
|
matrix_multiply4x4 ((float *)result, (float *)result, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Joins both flags and marks the type and inverse as dirty. Calls
|
|
||||||
* matrix_multiply3x4() if both matrices are 3D, or matrix_multiply4x4()
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_cogl_matrix_multiply (CoglMatrix *result,
|
|
||||||
const CoglMatrix *a,
|
|
||||||
const CoglMatrix *b)
|
|
||||||
{
|
|
||||||
result->flags = (a->flags |
|
|
||||||
b->flags |
|
|
||||||
MAT_DIRTY_TYPE |
|
|
||||||
MAT_DIRTY_INVERSE);
|
|
||||||
|
|
||||||
if (TEST_MAT_FLAGS(result, MAT_FLAGS_3D))
|
|
||||||
matrix_multiply3x4 ((float *)result, (float *)a, (float *)b);
|
|
||||||
else
|
|
||||||
matrix_multiply4x4 ((float *)result, (float *)a, (float *)b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_matrix_multiply (CoglMatrix *result,
|
cogl_matrix_multiply (CoglMatrix *result,
|
||||||
const CoglMatrix *a,
|
const CoglMatrix *a,
|
||||||
const CoglMatrix *b)
|
const CoglMatrix *b)
|
||||||
{
|
{
|
||||||
_cogl_matrix_multiply (result, a, b);
|
graphene_matrix_t res;
|
||||||
|
graphene_matrix_t ma;
|
||||||
|
graphene_matrix_t mb;
|
||||||
|
|
||||||
|
cogl_matrix_to_graphene_matrix (a, &ma);
|
||||||
|
cogl_matrix_to_graphene_matrix (b, &mb);
|
||||||
|
graphene_matrix_multiply (&mb, &ma, &res);
|
||||||
|
graphene_matrix_to_cogl_matrix (&res, result);
|
||||||
|
|
||||||
|
result->flags = a->flags | b->flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE;
|
||||||
|
|
||||||
_COGL_MATRIX_DEBUG_PRINT (result);
|
_COGL_MATRIX_DEBUG_PRINT (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user