mirror of
https://github.com/brl/mutter.git
synced 2024-11-30 03:50:47 -05:00
Merge branch 'units-rework'
* units-rework: [texture] Do not mix fixed point and units values [tests] Fix the actor detection [units] Do not use fixed point and units interchangeably
This commit is contained in:
commit
fd2d78918b
@ -772,6 +772,24 @@ clutter_actor_real_allocate (ClutterActor *self,
|
||||
g_object_thaw_notify (G_OBJECT (self));
|
||||
}
|
||||
|
||||
/* like ClutterVertex, but using CoglFixed and with a w component */
|
||||
typedef struct {
|
||||
CoglFixed x;
|
||||
CoglFixed y;
|
||||
CoglFixed z;
|
||||
CoglFixed w;
|
||||
} fixed_vertex_t;
|
||||
|
||||
/* copies a fixed vertex into a ClutterVertex */
|
||||
static inline void
|
||||
fixed_vertex_to_units (const fixed_vertex_t *f,
|
||||
ClutterVertex *u)
|
||||
{
|
||||
u->x = CLUTTER_UNITS_FROM_FIXED (f->x);
|
||||
u->y = CLUTTER_UNITS_FROM_FIXED (f->y);
|
||||
u->z = CLUTTER_UNITS_FROM_FIXED (f->z);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility functions for manipulating transformation matrix
|
||||
*
|
||||
@ -779,35 +797,39 @@ clutter_actor_real_allocate (ClutterActor *self,
|
||||
*/
|
||||
#define M(m,row,col) (m)[(col) * 4 + (row)]
|
||||
|
||||
/* Transform point (x,y,z) by matrix */
|
||||
static void
|
||||
mtx_transform (ClutterFixed m[16],
|
||||
ClutterFixed *x, ClutterFixed *y, ClutterFixed *z,
|
||||
ClutterFixed *w)
|
||||
/* Transforms a vertex using the passed matrix; vertex is
|
||||
* an in-out parameter
|
||||
*/
|
||||
static inline void
|
||||
mtx_transform (const ClutterFixed m[],
|
||||
fixed_vertex_t *vertex)
|
||||
{
|
||||
ClutterFixed _x, _y, _z, _w;
|
||||
_x = *x;
|
||||
_y = *y;
|
||||
_z = *z;
|
||||
_w = *w;
|
||||
|
||||
/* We care lot about precision here, so have to use QMUL */
|
||||
*x = COGL_FIXED_MUL (M (m, 0, 0), _x)
|
||||
_x = vertex->x;
|
||||
_y = vertex->y;
|
||||
_z = vertex->z;
|
||||
_w = vertex->w;
|
||||
|
||||
/* We care lot about precision here, so have to use MUL instead
|
||||
* of FAST_MUL
|
||||
*/
|
||||
vertex->x = COGL_FIXED_MUL (M (m, 0, 0), _x)
|
||||
+ COGL_FIXED_MUL (M (m, 0, 1), _y)
|
||||
+ COGL_FIXED_MUL (M (m, 0, 2), _z)
|
||||
+ COGL_FIXED_MUL (M (m, 0, 3), _w);
|
||||
|
||||
*y = COGL_FIXED_MUL (M (m, 1, 0), _x)
|
||||
vertex->y = COGL_FIXED_MUL (M (m, 1, 0), _x)
|
||||
+ COGL_FIXED_MUL (M (m, 1, 1), _y)
|
||||
+ COGL_FIXED_MUL (M (m, 1, 2), _z)
|
||||
+ COGL_FIXED_MUL (M (m, 1, 3), _w);
|
||||
|
||||
*z = COGL_FIXED_MUL (M (m, 2, 0), _x)
|
||||
vertex->z = COGL_FIXED_MUL (M (m, 2, 0), _x)
|
||||
+ COGL_FIXED_MUL (M (m, 2, 1), _y)
|
||||
+ COGL_FIXED_MUL (M (m, 2, 2), _z)
|
||||
+ COGL_FIXED_MUL (M (m, 2, 3), _w);
|
||||
|
||||
*w = COGL_FIXED_MUL (M (m, 3, 0), _x)
|
||||
vertex->w = COGL_FIXED_MUL (M (m, 3, 0), _x)
|
||||
+ COGL_FIXED_MUL (M (m, 3, 1), _y)
|
||||
+ COGL_FIXED_MUL (M (m, 3, 2), _z)
|
||||
+ COGL_FIXED_MUL (M (m, 3, 3), _w);
|
||||
@ -819,9 +841,70 @@ mtx_transform (ClutterFixed m[16],
|
||||
|
||||
#undef M
|
||||
|
||||
/* Help macros to scale from OpenGL <-1,1> coordinates system to our
|
||||
* X-window based <0,window-size> coordinates
|
||||
*/
|
||||
#define MTX_GL_SCALE_X(x,w,v1,v2) (COGL_FIXED_MUL (((COGL_FIXED_DIV ((x), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
|
||||
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - COGL_FIXED_MUL (((COGL_FIXED_DIV ((y), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
|
||||
#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
|
||||
|
||||
/* transforms a 4-tuple of coordinates using @matrix and
|
||||
* places the result into a fixed @vertex
|
||||
*/
|
||||
static inline void
|
||||
fixed_vertex_transform (const ClutterFixed matrix[],
|
||||
ClutterFixed x,
|
||||
ClutterFixed y,
|
||||
ClutterFixed z,
|
||||
ClutterFixed w,
|
||||
fixed_vertex_t *vertex)
|
||||
{
|
||||
fixed_vertex_t tmp = { 0, };
|
||||
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.z = z;
|
||||
tmp.w = w;
|
||||
|
||||
mtx_transform (matrix, &tmp);
|
||||
|
||||
*vertex = tmp;
|
||||
}
|
||||
|
||||
/* scales a fixed @vertex using @matrix and @viewport, and
|
||||
* transforms the result into ClutterUnits, filling @vertex_p
|
||||
*/
|
||||
static inline void
|
||||
fixed_vertex_scale (const ClutterFixed matrix[],
|
||||
const fixed_vertex_t *vertex,
|
||||
const ClutterFixed viewport[],
|
||||
ClutterVertex *vertex_p)
|
||||
{
|
||||
ClutterFixed v_x, v_y, v_width, v_height;
|
||||
fixed_vertex_t tmp = { 0, };
|
||||
|
||||
tmp = *vertex;
|
||||
|
||||
mtx_transform (matrix, &tmp);
|
||||
|
||||
v_x = viewport[0];
|
||||
v_y = viewport[1];
|
||||
v_width = viewport[2];
|
||||
v_height = viewport[3];
|
||||
|
||||
tmp.x = MTX_GL_SCALE_X (tmp.x, tmp.w, v_width, v_x);
|
||||
tmp.y = MTX_GL_SCALE_Y (tmp.y, tmp.w, v_height, v_y);
|
||||
tmp.z = MTX_GL_SCALE_Z (tmp.z, tmp.w, v_width, v_x);
|
||||
tmp.w = 0;
|
||||
|
||||
fixed_vertex_to_units (&tmp, vertex_p);
|
||||
}
|
||||
|
||||
/* Applies the transforms associated with this actor and its ancestors,
|
||||
* retrieves the resulting OpenGL modelview matrix, and uses the matrix
|
||||
* to transform the supplied point
|
||||
*
|
||||
* The point coordinates are in-out parameters
|
||||
*/
|
||||
static void
|
||||
clutter_actor_transform_point_relative (ClutterActor *actor,
|
||||
@ -832,14 +915,33 @@ clutter_actor_transform_point_relative (ClutterActor *actor,
|
||||
ClutterUnit *w)
|
||||
{
|
||||
ClutterFixed mtx[16];
|
||||
fixed_vertex_t vertex = { 0, };
|
||||
|
||||
vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0;
|
||||
vertex.y = (y != NULL) ? CLUTTER_UNITS_TO_FIXED (*y) : 0;
|
||||
vertex.z = (z != NULL) ? CLUTTER_UNITS_TO_FIXED (*z) : 0;
|
||||
vertex.w = (w != NULL) ? CLUTTER_UNITS_TO_FIXED (*w) : 0;
|
||||
|
||||
cogl_push_matrix();
|
||||
|
||||
_clutter_actor_apply_modelview_transform_recursive (actor, ancestor);
|
||||
|
||||
cogl_get_modelview_matrix (mtx);
|
||||
mtx_transform (mtx, x, y, z, w);
|
||||
mtx_transform (mtx, &vertex);
|
||||
|
||||
cogl_pop_matrix();
|
||||
|
||||
if (x)
|
||||
*x = CLUTTER_UNITS_FROM_FIXED (vertex.x);
|
||||
|
||||
if (y)
|
||||
*y = CLUTTER_UNITS_FROM_FIXED (vertex.y);
|
||||
|
||||
if (z)
|
||||
*z = CLUTTER_UNITS_FROM_FIXED (vertex.z);
|
||||
|
||||
if (w)
|
||||
*w = CLUTTER_UNITS_FROM_FIXED (vertex.w);
|
||||
}
|
||||
|
||||
/* Applies the transforms associated with this actor and its ancestors,
|
||||
@ -854,22 +956,34 @@ clutter_actor_transform_point (ClutterActor *actor,
|
||||
ClutterUnit *w)
|
||||
{
|
||||
ClutterFixed mtx[16];
|
||||
fixed_vertex_t vertex = { 0, };
|
||||
|
||||
vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0;
|
||||
vertex.y = (y != NULL) ? CLUTTER_UNITS_TO_FIXED (*y) : 0;
|
||||
vertex.z = (z != NULL) ? CLUTTER_UNITS_TO_FIXED (*z) : 0;
|
||||
vertex.w = (w != NULL) ? CLUTTER_UNITS_TO_FIXED (*w) : 0;
|
||||
|
||||
cogl_push_matrix();
|
||||
|
||||
_clutter_actor_apply_modelview_transform_recursive (actor, NULL);
|
||||
|
||||
cogl_get_modelview_matrix (mtx);
|
||||
mtx_transform (mtx, x, y, z, w);
|
||||
mtx_transform (mtx, &vertex);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
/* Help macros to scale from OpenGL <-1,1> coordinates system to our
|
||||
* X-window based <0,window-size> coordinates
|
||||
*/
|
||||
#define MTX_GL_SCALE_X(x,w,v1,v2) (COGL_FIXED_MUL (((COGL_FIXED_DIV ((x), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
|
||||
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - COGL_FIXED_MUL (((COGL_FIXED_DIV ((y), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
|
||||
#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
|
||||
if (x)
|
||||
*x = CLUTTER_UNITS_FROM_FIXED (vertex.x);
|
||||
|
||||
if (y)
|
||||
*y = CLUTTER_UNITS_FROM_FIXED (vertex.y);
|
||||
|
||||
if (z)
|
||||
*z = CLUTTER_UNITS_FROM_FIXED (vertex.z);
|
||||
|
||||
if (w)
|
||||
*w = CLUTTER_UNITS_FROM_FIXED (vertex.w);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_apply_relative_transform_to_point:
|
||||
@ -896,21 +1010,22 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
|
||||
const ClutterVertex *point,
|
||||
ClutterVertex *vertex)
|
||||
{
|
||||
ClutterVertex tmp = { 0, };
|
||||
ClutterFixed v[4];
|
||||
ClutterFixed w = COGL_FIXED_1;
|
||||
ClutterFixed x, y, z, w;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
|
||||
g_return_if_fail (point != NULL);
|
||||
g_return_if_fail (vertex != NULL);
|
||||
|
||||
tmp = *point;
|
||||
x = CLUTTER_UNITS_TO_FIXED (vertex->x);
|
||||
y = CLUTTER_UNITS_TO_FIXED (vertex->y);
|
||||
z = CLUTTER_UNITS_TO_FIXED (vertex->z);
|
||||
w = COGL_FIXED_1;
|
||||
|
||||
/* First we tranform the point using the OpenGL modelview matrix */
|
||||
clutter_actor_transform_point_relative (self, ancestor,
|
||||
&tmp.x, &tmp.y, &tmp.z,
|
||||
&w);
|
||||
&x, &y, &z, &w);
|
||||
|
||||
cogl_get_viewport (v);
|
||||
|
||||
@ -918,9 +1033,12 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
|
||||
* The w[3] parameter should always be 1.0 here, so we ignore it; otherwise
|
||||
* we would have to divide the original verts with it.
|
||||
*/
|
||||
vertex->x = COGL_FIXED_MUL ((tmp.x + COGL_FIXED_0_5), v[2]);
|
||||
vertex->y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - tmp.y), v[3]);
|
||||
vertex->z = COGL_FIXED_MUL ((tmp.z + COGL_FIXED_0_5), v[2]);
|
||||
vertex->x =
|
||||
CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((x + COGL_FIXED_0_5), v[2]));
|
||||
vertex->y =
|
||||
CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((COGL_FIXED_0_5 - y), v[3]));
|
||||
vertex->z =
|
||||
CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((z + COGL_FIXED_0_5), v[2]));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -940,30 +1058,35 @@ clutter_actor_apply_transform_to_point (ClutterActor *self,
|
||||
const ClutterVertex *point,
|
||||
ClutterVertex *vertex)
|
||||
{
|
||||
ClutterVertex tmp = { 0, };
|
||||
ClutterFixed mtx_p[16];
|
||||
ClutterFixed v[4];
|
||||
ClutterFixed w = COGL_FIXED_1;
|
||||
fixed_vertex_t tmp = { 0, };
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
g_return_if_fail (point != NULL);
|
||||
g_return_if_fail (vertex != NULL);
|
||||
|
||||
tmp = *point;
|
||||
tmp.x = CLUTTER_UNITS_TO_FIXED (vertex->x);
|
||||
tmp.y = CLUTTER_UNITS_TO_FIXED (vertex->y);
|
||||
tmp.z = CLUTTER_UNITS_TO_FIXED (vertex->z);
|
||||
tmp.w = COGL_FIXED_1;
|
||||
|
||||
/* First we tranform the point using the OpenGL modelview matrix */
|
||||
clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &w);
|
||||
clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &tmp.w);
|
||||
|
||||
cogl_get_projection_matrix (mtx_p);
|
||||
cogl_get_viewport (v);
|
||||
|
||||
/* Now, transform it again with the projection matrix */
|
||||
mtx_transform (mtx_p, &tmp.x, &tmp.y, &tmp.z, &w);
|
||||
mtx_transform (mtx_p, &tmp);
|
||||
|
||||
/* Finaly translate from OpenGL coords to window coords */
|
||||
vertex->x = MTX_GL_SCALE_X (tmp.x, w, v[2], v[0]);
|
||||
vertex->y = MTX_GL_SCALE_Y (tmp.y, w, v[3], v[1]);
|
||||
vertex->z = MTX_GL_SCALE_Z (tmp.z, w, v[2], v[0]);
|
||||
vertex->x =
|
||||
CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_X (tmp.x, tmp.w, v[2], v[0]));
|
||||
vertex->y =
|
||||
CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_Y (tmp.y, tmp.w, v[3], v[1]));
|
||||
vertex->z =
|
||||
CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_Z (tmp.z, tmp.w, v[2], v[0]));
|
||||
}
|
||||
|
||||
/* Recursively tranform supplied vertices with the tranform for the current
|
||||
@ -973,64 +1096,25 @@ clutter_actor_apply_transform_to_point (ClutterActor *self,
|
||||
static void
|
||||
clutter_actor_transform_vertices_relative (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex verts[4],
|
||||
ClutterFixed w[4])
|
||||
fixed_vertex_t vertices[])
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
ClutterFixed mtx[16];
|
||||
ClutterFixed _x, _y, _z, _w;
|
||||
ClutterFixed width, height;
|
||||
|
||||
width = CLUTTER_UNITS_TO_FIXED (priv->allocation.x2 - priv->allocation.x1);
|
||||
height = CLUTTER_UNITS_TO_FIXED (priv->allocation.y2 - priv->allocation.y1);
|
||||
|
||||
cogl_push_matrix();
|
||||
|
||||
_clutter_actor_apply_modelview_transform_recursive (self, ancestor);
|
||||
|
||||
cogl_get_modelview_matrix (mtx);
|
||||
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[0].x = _x;
|
||||
verts[0].y = _y;
|
||||
verts[0].z = _z;
|
||||
w[0] = _w;
|
||||
|
||||
_x = self->priv->allocation.x2 - self->priv->allocation.x1;
|
||||
_y = 0;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[1].x = _x;
|
||||
verts[1].y = _y;
|
||||
verts[1].z = _z;
|
||||
w[1] = _w;
|
||||
|
||||
_x = 0;
|
||||
_y = self->priv->allocation.y2 - self->priv->allocation.y1;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[2].x = _x;
|
||||
verts[2].y = _y;
|
||||
verts[2].z = _z;
|
||||
w[2] = _w;
|
||||
|
||||
_x = self->priv->allocation.x2 - self->priv->allocation.x1;
|
||||
_y = self->priv->allocation.y2 - self->priv->allocation.y1;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[3].x = _x;
|
||||
verts[3].y = _y;
|
||||
verts[3].z = _z;
|
||||
w[3] = _w;
|
||||
fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]);
|
||||
fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]);
|
||||
fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]);
|
||||
fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
@ -1048,9 +1132,12 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
|
||||
ClutterActor *stage;
|
||||
ClutterFixed mtx[16];
|
||||
ClutterFixed mtx_p[16];
|
||||
ClutterFixed _x, _y, _z, _w;
|
||||
ClutterFixed w[4];
|
||||
ClutterFixed v[4];
|
||||
ClutterFixed width, height;
|
||||
fixed_vertex_t vertices[4];
|
||||
|
||||
width = CLUTTER_UNITS_TO_FIXED (box->x2 - box->x1);
|
||||
height = CLUTTER_UNITS_TO_FIXED (box->y2 - box->y1);
|
||||
|
||||
/* We essentially have to dupe some code from clutter_redraw() here
|
||||
* to make sure GL Matrices etc are initialised if we're called and we
|
||||
@ -1071,102 +1158,25 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
|
||||
_clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage));
|
||||
|
||||
cogl_push_matrix();
|
||||
|
||||
_clutter_actor_apply_modelview_transform_recursive (self, NULL);
|
||||
|
||||
cogl_get_modelview_matrix (mtx);
|
||||
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[0].x = _x;
|
||||
verts[0].y = _y;
|
||||
verts[0].z = _z;
|
||||
w[0] = _w;
|
||||
|
||||
_x = box->x2 - box->x1;
|
||||
_y = 0;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[1].x = _x;
|
||||
verts[1].y = _y;
|
||||
verts[1].z = _z;
|
||||
w[1] = _w;
|
||||
|
||||
_x = 0;
|
||||
_y = box->y2 - box->y1;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[2].x = _x;
|
||||
verts[2].y = _y;
|
||||
verts[2].z = _z;
|
||||
w[2] = _w;
|
||||
|
||||
_x = box->x2 - box->x1;
|
||||
_y = box->y2 - box->y1;
|
||||
_z = 0;
|
||||
_w = COGL_FIXED_1;
|
||||
|
||||
mtx_transform (mtx, &_x, &_y, &_z, &_w);
|
||||
|
||||
verts[3].x = _x;
|
||||
verts[3].y = _y;
|
||||
verts[3].z = _z;
|
||||
w[3] = _w;
|
||||
fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]);
|
||||
fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]);
|
||||
fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]);
|
||||
fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
|
||||
cogl_get_projection_matrix (mtx_p);
|
||||
cogl_get_viewport (v);
|
||||
|
||||
mtx_transform (mtx_p,
|
||||
&verts[0].x,
|
||||
&verts[0].y,
|
||||
&verts[0].z,
|
||||
&w[0]);
|
||||
|
||||
verts[0].x = MTX_GL_SCALE_X (verts[0].x, w[0], v[2], v[0]);
|
||||
verts[0].y = MTX_GL_SCALE_Y (verts[0].y, w[0], v[3], v[1]);
|
||||
verts[0].z = MTX_GL_SCALE_Z (verts[0].z, w[0], v[2], v[0]);
|
||||
|
||||
mtx_transform (mtx_p,
|
||||
&verts[1].x,
|
||||
&verts[1].y,
|
||||
&verts[1].z,
|
||||
&w[1]);
|
||||
|
||||
verts[1].x = MTX_GL_SCALE_X (verts[1].x, w[1], v[2], v[0]);
|
||||
verts[1].y = MTX_GL_SCALE_Y (verts[1].y, w[1], v[3], v[1]);
|
||||
verts[1].z = MTX_GL_SCALE_Z (verts[1].z, w[1], v[2], v[0]);
|
||||
|
||||
mtx_transform (mtx_p,
|
||||
&verts[2].x,
|
||||
&verts[2].y,
|
||||
&verts[2].z,
|
||||
&w[2]);
|
||||
|
||||
verts[2].x = MTX_GL_SCALE_X (verts[2].x, w[2], v[2], v[0]);
|
||||
verts[2].y = MTX_GL_SCALE_Y (verts[2].y, w[2], v[3], v[1]);
|
||||
verts[2].z = MTX_GL_SCALE_Z (verts[2].z, w[2], v[2], v[0]);
|
||||
|
||||
mtx_transform (mtx_p,
|
||||
&verts[3].x,
|
||||
&verts[3].y,
|
||||
&verts[3].z,
|
||||
&w[3]);
|
||||
|
||||
verts[3].x = MTX_GL_SCALE_X (verts[3].x, w[3], v[2], v[0]);
|
||||
verts[3].y = MTX_GL_SCALE_Y (verts[3].y, w[3], v[3], v[1]);
|
||||
verts[3].z = MTX_GL_SCALE_Z (verts[3].z, w[3], v[2], v[0]);
|
||||
fixed_vertex_scale (mtx_p, &vertices[0], v, &verts[0]);
|
||||
fixed_vertex_scale (mtx_p, &vertices[1], v, &verts[1]);
|
||||
fixed_vertex_scale (mtx_p, &vertices[2], v, &verts[2]);
|
||||
fixed_vertex_scale (mtx_p, &vertices[3], v, &verts[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1181,10 +1191,10 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
|
||||
* actor in the plane of @ancestor. The returned vertices relate to
|
||||
* the #ClutterActorBox coordinates as follows:
|
||||
* <itemizedlist>
|
||||
* <listitem><para>v[0] contains (x1, y1)</para></listitem>
|
||||
* <listitem><para>v[1] contains (x2, y1)</para></listitem>
|
||||
* <listitem><para>v[2] contains (x1, y2)</para></listitem>
|
||||
* <listitem><para>v[3] contains (x2, y2)</para></listitem>
|
||||
* <listitem><para>@verts[0] contains (x1, y1)</para></listitem>
|
||||
* <listitem><para>@verts[1] contains (x2, y1)</para></listitem>
|
||||
* <listitem><para>@verts[2] contains (x1, y2)</para></listitem>
|
||||
* <listitem><para>@verts[3] contains (x2, y2)</para></listitem>
|
||||
* </itemizedlist>
|
||||
*
|
||||
* If @ancestor is %NULL the ancestor will be the #ClutterStage. In
|
||||
@ -1197,12 +1207,13 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
|
||||
void
|
||||
clutter_actor_get_allocation_vertices (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex verts[4])
|
||||
ClutterVertex verts[])
|
||||
{
|
||||
ClutterFixed v[4];
|
||||
ClutterFixed w[4];
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterActor *stage;
|
||||
ClutterFixed v[4];
|
||||
fixed_vertex_t vertices[4];
|
||||
fixed_vertex_t tmp = { 0, };
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
|
||||
@ -1234,28 +1245,33 @@ clutter_actor_get_allocation_vertices (ClutterActor *self,
|
||||
if (priv->needs_allocation)
|
||||
_clutter_stage_maybe_relayout (stage);
|
||||
|
||||
clutter_actor_transform_vertices_relative (self, ancestor, verts, w);
|
||||
clutter_actor_transform_vertices_relative (self, ancestor, vertices);
|
||||
|
||||
cogl_get_viewport (v);
|
||||
|
||||
/*
|
||||
* The w[3] parameter should always be 1.0 here, so we ignore it; otherwise
|
||||
* we would have to devide the original verts with it.
|
||||
* The w[3] parameter should always be 1.0 here, so we ignore it;
|
||||
* otherwise we would have to divide the original verts with it.
|
||||
*/
|
||||
verts[0].x = COGL_FIXED_MUL ((verts[0].x + COGL_FIXED_0_5), v[2]);
|
||||
verts[0].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[0].y), v[3]);
|
||||
verts[0].z = COGL_FIXED_MUL ((verts[0].z + COGL_FIXED_0_5), v[2]);
|
||||
tmp.x = COGL_FIXED_MUL ((vertices[0].x + COGL_FIXED_0_5), v[2]);
|
||||
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[0].y), v[3]);
|
||||
tmp.z = COGL_FIXED_MUL ((vertices[0].z + COGL_FIXED_0_5), v[2]);
|
||||
fixed_vertex_to_units (&tmp, &verts[0]);
|
||||
|
||||
verts[1].x = COGL_FIXED_MUL ((verts[1].x + COGL_FIXED_0_5), v[2]);
|
||||
verts[1].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[1].y), v[3]);
|
||||
verts[1].z = COGL_FIXED_MUL ((verts[1].z + COGL_FIXED_0_5), v[2]);
|
||||
tmp.x = COGL_FIXED_MUL ((vertices[1].x + COGL_FIXED_0_5), v[2]);
|
||||
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[1].y), v[3]);
|
||||
tmp.z = COGL_FIXED_MUL ((vertices[1].z + COGL_FIXED_0_5), v[2]);
|
||||
fixed_vertex_to_units (&tmp, &verts[1]);
|
||||
|
||||
verts[2].x = COGL_FIXED_MUL ((verts[2].x + COGL_FIXED_0_5), v[2]);
|
||||
verts[2].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[2].y), v[3]);
|
||||
verts[2].z = COGL_FIXED_MUL ((verts[2].z + COGL_FIXED_0_5), v[2]);
|
||||
tmp.x = COGL_FIXED_MUL ((vertices[2].x + COGL_FIXED_0_5), v[2]);
|
||||
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[2].y), v[3]);
|
||||
tmp.z = COGL_FIXED_MUL ((vertices[2].z + COGL_FIXED_0_5), v[2]);
|
||||
fixed_vertex_to_units (&tmp, &verts[2]);
|
||||
|
||||
verts[3].x = COGL_FIXED_MUL ((verts[3].x + COGL_FIXED_0_5), v[2]);
|
||||
verts[3].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[3].y), v[3]);
|
||||
verts[3].z = COGL_FIXED_MUL ((verts[3].z + COGL_FIXED_0_5), v[2]);
|
||||
tmp.x = COGL_FIXED_MUL ((vertices[3].x + COGL_FIXED_0_5), v[2]);
|
||||
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[3].y), v[3]);
|
||||
tmp.z = COGL_FIXED_MUL ((vertices[3].z + COGL_FIXED_0_5), v[2]);
|
||||
fixed_vertex_to_units (&tmp, &verts[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6852,7 +6868,8 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
ClutterFixed ST[3][3];
|
||||
ClutterFixed RQ[3][3];
|
||||
int du, dv, xi, yi;
|
||||
ClutterFixed xf, yf, wf, px, py, det;
|
||||
ClutterUnit px, py;
|
||||
ClutterFixed xf, yf, wf, det;
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
|
||||
@ -6865,11 +6882,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
*
|
||||
* http://www.cs.cmu.edu/~ph/texfund/texfund.pdf
|
||||
*
|
||||
* and the sample implementaion at http://www.cs.cmu.edu/~ph/src/texfund/.
|
||||
* and the sample implementation at http://www.cs.cmu.edu/~ph/src/texfund/.
|
||||
*
|
||||
* Our texture is a rectangle with origin [0,0], so we are mapping from quad
|
||||
* to rectangle only, which significantly simplifies things; the function
|
||||
* calls have been unrolled, and most of the math is done in fixed point.
|
||||
* Our texture is a rectangle with origin [0, 0], so we are mapping from
|
||||
* quad to rectangle only, which significantly simplifies things; the
|
||||
* function calls have been unrolled, and most of the math is done in fixed
|
||||
* point.
|
||||
*/
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (self, v);
|
||||
@ -6886,9 +6904,11 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
|
||||
#define FP2FX COGL_FIXED_FROM_FLOAT
|
||||
#define FX2FP COGL_FIXED_TO_DOUBLE
|
||||
#define UX2FP CLUTTER_UNITS_TO_FLOAT
|
||||
#define UX2FX CLUTTER_UNITS_TO_FIXED
|
||||
#define FP2INT CLUTTER_FLOAT_TO_INT
|
||||
#define DET2X(a,b,c,d) (COGL_FIXED_MUL (a, d) - COGL_FIXED_MUL (b, c))
|
||||
#define DET2FP(a,b,c,d) (a*d - b*c)
|
||||
#define DET2X(a,b,c,d) (COGL_FIXED_MUL ((a), (d)) - COGL_FIXED_MUL ((b), (c)))
|
||||
#define DET2FP(a,b,c,d) ((a) * (d) - (b) * (c))
|
||||
|
||||
/*
|
||||
* First, find mapping from unit uv square to xy quadrilateral; this
|
||||
@ -6900,20 +6920,21 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
py = v[0].y - v[1].y + v[3].y - v[2].y;
|
||||
|
||||
if (!px && !py)
|
||||
{ /* affine transform */
|
||||
RQ[0][0] = v[1].x - v[0].x;
|
||||
RQ[1][0] = v[3].x - v[1].x;
|
||||
RQ[2][0] = v[0].x;
|
||||
RQ[0][1] = v[1].y - v[0].y;
|
||||
RQ[1][1] = v[3].y - v[1].y;
|
||||
RQ[2][1] = v[0].y;
|
||||
{
|
||||
/* affine transform */
|
||||
RQ[0][0] = UX2FX (v[1].x - v[0].x);
|
||||
RQ[1][0] = UX2FX (v[3].x - v[1].x);
|
||||
RQ[2][0] = UX2FX (v[0].x);
|
||||
RQ[0][1] = UX2FX (v[1].y - v[0].y);
|
||||
RQ[1][1] = UX2FX (v[3].y - v[1].y);
|
||||
RQ[2][1] = UX2FX (v[0].y);
|
||||
RQ[0][2] = 0;
|
||||
RQ[1][2] = 0;
|
||||
RQ[2][2] = COGL_FIXED_1;
|
||||
}
|
||||
else
|
||||
{ /*
|
||||
* projective transform
|
||||
{
|
||||
/* projective transform
|
||||
*
|
||||
* Must do this in floating point, as the del value can overflow the
|
||||
* range of ClutterFixed for large actors.
|
||||
@ -6923,13 +6944,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
*/
|
||||
double dx1, dx2, dy1, dy2, del;
|
||||
|
||||
dx1 = FX2FP (v[1].x - v[3].x);
|
||||
dx2 = FX2FP (v[2].x - v[3].x);
|
||||
dy1 = FX2FP (v[1].y - v[3].y);
|
||||
dy2 = FX2FP (v[2].y - v[3].y);
|
||||
dx1 = UX2FP (v[1].x - v[3].x);
|
||||
dx2 = UX2FP (v[2].x - v[3].x);
|
||||
dy1 = UX2FP (v[1].y - v[3].y);
|
||||
dy2 = UX2FP (v[2].y - v[3].y);
|
||||
|
||||
del = DET2FP (dx1, dx2, dy1, dy2);
|
||||
|
||||
if (!del)
|
||||
return FALSE;
|
||||
|
||||
@ -6937,16 +6957,20 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
* The division here needs to be done in floating point for
|
||||
* precisions reasons.
|
||||
*/
|
||||
RQ[0][2] = FP2FX (DET2FP (FX2FP(px),dx2, FX2FP(py),dy2) / del);
|
||||
RQ[1][2] = FP2FX (DET2FP (dx1,FX2FP(px), dy1,FX2FP(py)) / del);
|
||||
RQ[1][2] = FP2FX (DET2FP(dx1,FX2FP(px), dy1,FX2FP(py))/del);
|
||||
RQ[0][2] = FP2FX (DET2FP (UX2FP (px), dx2, UX2FP (py), dy2) / del);
|
||||
RQ[1][2] = FP2FX (DET2FP (dx1, UX2FP (px), dy1, UX2FP (py)) / del);
|
||||
RQ[1][2] = FP2FX (DET2FP (dx1, UX2FP (px), dy1, UX2FP (py)) / del);
|
||||
RQ[2][2] = COGL_FIXED_1;
|
||||
RQ[0][0] = v[1].x - v[0].x + COGL_FIXED_MUL (RQ[0][2], v[1].x);
|
||||
RQ[1][0] = v[2].x - v[0].x + COGL_FIXED_MUL (RQ[1][2], v[2].x);
|
||||
RQ[2][0] = v[0].x;
|
||||
RQ[0][1] = v[1].y - v[0].y + COGL_FIXED_MUL (RQ[0][2], v[1].y);
|
||||
RQ[1][1] = v[2].y - v[0].y + COGL_FIXED_MUL (RQ[1][2], v[2].y);
|
||||
RQ[2][1] = v[0].y;
|
||||
RQ[0][0] = UX2FX (v[1].x - v[0].x)
|
||||
+ COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].x));
|
||||
RQ[1][0] = UX2FX (v[2].x - v[0].x)
|
||||
+ COGL_FIXED_MUL (RQ[1][2], UX2FX (v[2].x));
|
||||
RQ[2][0] = UX2FX (v[0].x);
|
||||
RQ[0][1] = UX2FX (v[1].y - v[0].y)
|
||||
+ COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].y));
|
||||
RQ[1][1] = UX2FX (v[2].y - v[0].y)
|
||||
+ COGL_FIXED_MUL (RQ[1][2], UX2FX (v[2].y));
|
||||
RQ[2][1] = UX2FX (v[0].y);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6985,8 +7009,8 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Now transform our point with the ST matrix; the notional w coordiance
|
||||
* is 1, hence the last part is simply added.
|
||||
* Now transform our point with the ST matrix; the notional w
|
||||
* coordinate is 1, hence the last part is simply added.
|
||||
*/
|
||||
xi = CLUTTER_UNITS_TO_DEVICE (x);
|
||||
yi = CLUTTER_UNITS_TO_DEVICE (y);
|
||||
@ -7000,9 +7024,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
*/
|
||||
if (x_out)
|
||||
*x_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (xf) / FX2FP (wf));
|
||||
|
||||
if (y_out)
|
||||
*y_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (yf) / FX2FP (wf));
|
||||
|
||||
#undef UX2FX
|
||||
#undef UX2FP
|
||||
#undef FP2FX
|
||||
#undef FX2FP
|
||||
#undef FP2INT
|
||||
|
@ -417,7 +417,8 @@ clutter_texture_set_fbo_projection (ClutterActor *self)
|
||||
ClutterTexturePrivate *priv = CLUTTER_TEXTURE (self)->priv;
|
||||
ClutterVertex verts[4];
|
||||
ClutterFixed viewport[4];
|
||||
ClutterFixed x_min, x_max, y_min, y_max;
|
||||
ClutterUnit x_min, x_max, y_min, y_max;
|
||||
ClutterFixed tx_min, tx_max, ty_min, ty_max;
|
||||
ClutterPerspective perspective;
|
||||
ClutterStage *stage;
|
||||
ClutterFixed tan_angle, near_size;
|
||||
@ -450,20 +451,25 @@ clutter_texture_set_fbo_projection (ClutterActor *self)
|
||||
|
||||
/* Convert the coordinates back to [-1,1] range */
|
||||
cogl_get_viewport (viewport);
|
||||
x_min = COGL_FIXED_DIV (x_min, viewport[2]) * 2 - COGL_FIXED_1;
|
||||
x_max = COGL_FIXED_DIV (x_max, viewport[2]) * 2 - COGL_FIXED_1;
|
||||
y_min = COGL_FIXED_DIV (y_min, viewport[3]) * 2 - COGL_FIXED_1;
|
||||
y_max = COGL_FIXED_DIV (y_max, viewport[3]) * 2 - COGL_FIXED_1;
|
||||
|
||||
tx_min = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_min), viewport[2])
|
||||
* 2 - COGL_FIXED_1;
|
||||
tx_max = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_max), viewport[2])
|
||||
* 2 - COGL_FIXED_1;
|
||||
ty_min = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_min), viewport[3])
|
||||
* 2 - COGL_FIXED_1;
|
||||
ty_max = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_max), viewport[3])
|
||||
* 2 - COGL_FIXED_1;
|
||||
|
||||
/* Set up a projection matrix so that the actor will be projected as
|
||||
if it was drawn at its original location */
|
||||
tan_angle = clutter_tani (CLUTTER_ANGLE_FROM_DEGX (perspective.fovy / 2));
|
||||
tan_angle = cogl_angle_tan (COGL_ANGLE_FROM_DEGX (perspective.fovy / 2));
|
||||
near_size = COGL_FIXED_MUL (perspective.z_near, tan_angle);
|
||||
|
||||
cogl_frustum (COGL_FIXED_MUL (x_min, near_size),
|
||||
COGL_FIXED_MUL (x_max, near_size),
|
||||
COGL_FIXED_MUL (-y_min, near_size),
|
||||
COGL_FIXED_MUL (-y_max, near_size),
|
||||
cogl_frustum (COGL_FIXED_MUL (tx_min, near_size),
|
||||
COGL_FIXED_MUL (tx_max, near_size),
|
||||
COGL_FIXED_MUL (-ty_min, near_size),
|
||||
COGL_FIXED_MUL (-ty_max, near_size),
|
||||
perspective.z_near, perspective.z_far);
|
||||
}
|
||||
|
||||
@ -544,8 +550,10 @@ clutter_texture_paint (ClutterActor *self)
|
||||
|
||||
/* Restore the perspective matrix using cogl_perspective so that
|
||||
the inverse matrix will be right */
|
||||
cogl_perspective (perspective.fovy, perspective.aspect,
|
||||
perspective.z_near, perspective.z_far);
|
||||
cogl_perspective (perspective.fovy,
|
||||
perspective.aspect,
|
||||
perspective.z_near,
|
||||
perspective.z_far);
|
||||
|
||||
/* If there is a shader on top of the shader stack, turn it back on. */
|
||||
if (shader)
|
||||
|
@ -5,13 +5,15 @@
|
||||
#include <string.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
ClutterActor *label;
|
||||
|
||||
#define RECT_L 200
|
||||
#define RECT_T 150
|
||||
#define RECT_W 320
|
||||
#define RECT_H 240
|
||||
|
||||
static ClutterActor *test_rectangle = NULL;
|
||||
static ClutterActor *label = NULL;
|
||||
|
||||
|
||||
static gboolean
|
||||
on_event (ClutterStage *stage,
|
||||
ClutterEvent *event,
|
||||
@ -29,7 +31,6 @@ on_event (ClutterStage *stage,
|
||||
|
||||
actor = clutter_stage_get_actor_at_pos (stage, x, y);
|
||||
|
||||
|
||||
if (clutter_actor_transform_stage_point (actor,
|
||||
CLUTTER_UNITS_FROM_DEVICE (x),
|
||||
CLUTTER_UNITS_FROM_DEVICE (y),
|
||||
@ -37,7 +38,7 @@ on_event (ClutterStage *stage,
|
||||
{
|
||||
gchar *txt;
|
||||
|
||||
if (actor != CLUTTER_ACTOR (stage))
|
||||
if (actor == test_rectangle)
|
||||
txt = g_strdup_printf ("Click on rectangle\n"
|
||||
"Screen coords: [%d, %d]\n"
|
||||
"Local coords : [%d, %d]",
|
||||
@ -117,6 +118,7 @@ test_unproject_main (int argc, char *argv[])
|
||||
clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, rotate_y, 0, 0, 0);
|
||||
clutter_actor_set_rotation (rect, CLUTTER_Z_AXIS, rotate_z, 0, 0, 0);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
test_rectangle = rect;
|
||||
|
||||
txt = g_strdup_printf ("Rectangle: L %d, R %d, T %d, B %d\n"
|
||||
"Rotation : x %d, y %d, z %d",
|
||||
@ -146,5 +148,8 @@ test_unproject_main (int argc, char *argv[])
|
||||
|
||||
clutter_main();
|
||||
|
||||
test_rectangle = NULL;
|
||||
label = NULL;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user