diff --git a/README b/README index 4518210fa..d689550d0 100644 --- a/README +++ b/README @@ -287,6 +287,9 @@ Release Notes for Clutter 1.0 density argument isn't just ignored. A cogl_disable_fog function was also added. +* cogl_get_*_matrix were changed to use the CoglMatrix type instead of + GLfloat m[16] arrays. + Release Notes for Clutter 0.8 ------------------------------- diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 9aa3aad9a..1b9dbc627 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -867,57 +867,20 @@ fixed_vertex_to_units (const fixed_vertex_t *f, u->z = CLUTTER_UNITS_FROM_FIXED (f->z); } -/* - * Utility functions for manipulating transformation matrix - * - * Matrix: 4x4 of ClutterFixed - */ -#define M(m,row,col) (m)[(col) * 4 + (row)] - /* 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) +static void +mtx_transform (const CoglMatrix *matrix, + fixed_vertex_t *vertex) { - float _x, _y, _z, _w; - - _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 = CLUTTER_FIXED_MUL (M (m, 0, 0), _x) - + CLUTTER_FIXED_MUL (M (m, 0, 1), _y) - + CLUTTER_FIXED_MUL (M (m, 0, 2), _z) - + CLUTTER_FIXED_MUL (M (m, 0, 3), _w); - - vertex->y = CLUTTER_FIXED_MUL (M (m, 1, 0), _x) - + CLUTTER_FIXED_MUL (M (m, 1, 1), _y) - + CLUTTER_FIXED_MUL (M (m, 1, 2), _z) - + CLUTTER_FIXED_MUL (M (m, 1, 3), _w); - - vertex->z = CLUTTER_FIXED_MUL (M (m, 2, 0), _x) - + CLUTTER_FIXED_MUL (M (m, 2, 1), _y) - + CLUTTER_FIXED_MUL (M (m, 2, 2), _z) - + CLUTTER_FIXED_MUL (M (m, 2, 3), _w); - - vertex->w = CLUTTER_FIXED_MUL (M (m, 3, 0), _x) - + CLUTTER_FIXED_MUL (M (m, 3, 1), _y) - + CLUTTER_FIXED_MUL (M (m, 3, 2), _z) - + CLUTTER_FIXED_MUL (M (m, 3, 3), _w); - - /* Specially for Matthew: was going to put a comment here, but could not - * think of anything at all to say ;) - */ + cogl_matrix_transform_point (matrix, + &vertex->x, + &vertex->y, + &vertex->z, + &vertex->w); } -#undef M - /* Help macros to scale from OpenGL <-1,1> coordinates system to our * X-window based <0,window-size> coordinates */ @@ -932,7 +895,7 @@ mtx_transform (const ClutterFixed m[], * places the result into a fixed @vertex */ static inline void -fixed_vertex_transform (const ClutterFixed matrix[], +fixed_vertex_transform (const CoglMatrix *matrix, ClutterFixed x, ClutterFixed y, ClutterFixed z, @@ -955,7 +918,7 @@ fixed_vertex_transform (const ClutterFixed matrix[], * transforms the result into ClutterUnits, filling @vertex_p */ static inline void -fixed_vertex_scale (const ClutterFixed matrix[], +fixed_vertex_scale (const CoglMatrix *matrix, const fixed_vertex_t *vertex, const ClutterFixed viewport[], ClutterVertex *vertex_p) @@ -994,7 +957,7 @@ clutter_actor_transform_point_relative (ClutterActor *actor, ClutterUnit *z, ClutterUnit *w) { - ClutterFixed mtx[16]; + CoglMatrix matrix; fixed_vertex_t vertex = { 0, }; vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0; @@ -1006,8 +969,8 @@ clutter_actor_transform_point_relative (ClutterActor *actor, _clutter_actor_apply_modelview_transform_recursive (actor, ancestor); - cogl_get_modelview_matrix (mtx); - mtx_transform (mtx, &vertex); + cogl_get_modelview_matrix (&matrix); + mtx_transform (&matrix, &vertex); cogl_pop_matrix(); @@ -1035,7 +998,7 @@ clutter_actor_transform_point (ClutterActor *actor, ClutterUnit *z, ClutterUnit *w) { - ClutterFixed mtx[16]; + CoglMatrix matrix; fixed_vertex_t vertex = { 0, }; vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0; @@ -1047,8 +1010,8 @@ clutter_actor_transform_point (ClutterActor *actor, _clutter_actor_apply_modelview_transform_recursive (actor, NULL); - cogl_get_modelview_matrix (mtx); - mtx_transform (mtx, &vertex); + cogl_get_modelview_matrix (&matrix); + mtx_transform (&matrix, &vertex); cogl_pop_matrix(); @@ -1139,7 +1102,7 @@ clutter_actor_apply_transform_to_point (ClutterActor *self, ClutterVertex *vertex) { ClutterUnit x, y, z, w; - ClutterFixed mtx_p[16]; + CoglMatrix matrix_p; ClutterFixed v[4]; fixed_vertex_t tmp = { 0, }; @@ -1160,11 +1123,11 @@ clutter_actor_apply_transform_to_point (ClutterActor *self, tmp.z = CLUTTER_UNITS_TO_FIXED (z); tmp.w = CLUTTER_UNITS_TO_FIXED (w); - cogl_get_projection_matrix (mtx_p); + cogl_get_projection_matrix (&matrix_p); cogl_get_viewport (v); /* Now, transform it again with the projection matrix */ - mtx_transform (mtx_p, &tmp); + mtx_transform (&matrix_p, &tmp); /* Finaly translate from OpenGL coords to window coords */ vertex->x = @@ -1185,7 +1148,7 @@ clutter_actor_transform_vertices_relative (ClutterActor *self, fixed_vertex_t vertices[]) { ClutterActorPrivate *priv = self->priv; - ClutterFixed mtx[16]; + CoglMatrix mtx; ClutterFixed width, height; width = CLUTTER_UNITS_TO_FIXED (priv->allocation.x2 - priv->allocation.x1); @@ -1195,12 +1158,12 @@ clutter_actor_transform_vertices_relative (ClutterActor *self, _clutter_actor_apply_modelview_transform_recursive (self, ancestor); - cogl_get_modelview_matrix (mtx); + cogl_get_modelview_matrix (&mtx); - fixed_vertex_transform (mtx, 0, 0, 0, 1.0, &vertices[0]); - fixed_vertex_transform (mtx, width, 0, 0, 1.0, &vertices[1]); - fixed_vertex_transform (mtx, 0, height, 0, 1.0, &vertices[2]); - fixed_vertex_transform (mtx, width, height, 0, 1.0, &vertices[3]); + fixed_vertex_transform (&mtx, 0, 0, 0, 1.0, &vertices[0]); + fixed_vertex_transform (&mtx, width, 0, 0, 1.0, &vertices[1]); + fixed_vertex_transform (&mtx, 0, height, 0, 1.0, &vertices[2]); + fixed_vertex_transform (&mtx, width, height, 0, 1.0, &vertices[3]); cogl_pop_matrix(); } @@ -1216,8 +1179,8 @@ clutter_actor_transform_and_project_box (ClutterActor *self, ClutterVertex verts[4]) { ClutterActor *stage; - ClutterFixed mtx[16]; - ClutterFixed mtx_p[16]; + CoglMatrix mtx; + CoglMatrix mtx_p; ClutterFixed v[4]; ClutterFixed width, height; fixed_vertex_t vertices[4]; @@ -1247,22 +1210,22 @@ clutter_actor_transform_and_project_box (ClutterActor *self, _clutter_actor_apply_modelview_transform_recursive (self, NULL); - cogl_get_modelview_matrix (mtx); + cogl_get_modelview_matrix (&mtx); - fixed_vertex_transform (mtx, 0, 0, 0, 1.0, &vertices[0]); - fixed_vertex_transform (mtx, width, 0, 0, 1.0, &vertices[1]); - fixed_vertex_transform (mtx, 0, height, 0, 1.0, &vertices[2]); - fixed_vertex_transform (mtx, width, height, 0, 1.0, &vertices[3]); + fixed_vertex_transform (&mtx, 0, 0, 0, 1.0, &vertices[0]); + fixed_vertex_transform (&mtx, width, 0, 0, 1.0, &vertices[1]); + fixed_vertex_transform (&mtx, 0, height, 0, 1.0, &vertices[2]); + fixed_vertex_transform (&mtx, width, height, 0, 1.0, &vertices[3]); cogl_pop_matrix(); - cogl_get_projection_matrix (mtx_p); + cogl_get_projection_matrix (&mtx_p); cogl_get_viewport (v); - 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]); + 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]); } /** @@ -4510,7 +4473,7 @@ clutter_actor_get_transformed_sizeu (ClutterActor *self, box.x2 = box.x1 + natural_width; box.y2 = box.y1 + natural_height; - + clutter_actor_transform_and_project_box (self, &box, v); } else @@ -7997,7 +7960,7 @@ clutter_actor_allocate_preferred_size (ClutterActor *self, ClutterActorBox actor_box; g_return_if_fail (CLUTTER_IS_ACTOR (self)); - + actor_x = clutter_actor_get_xu (self); actor_y = clutter_actor_get_yu (self); @@ -8005,7 +7968,7 @@ clutter_actor_allocate_preferred_size (ClutterActor *self, NULL, NULL, &natural_width, &natural_height); - + actor_box.x1 = actor_x; actor_box.y1 = actor_y; actor_box.x2 = actor_box.x1 + natural_width; diff --git a/clutter/cogl/cogl-matrix.h b/clutter/cogl/cogl-matrix.h index 1d5942f83..95ec92ffd 100644 --- a/clutter/cogl/cogl-matrix.h +++ b/clutter/cogl/cogl-matrix.h @@ -140,6 +140,42 @@ void cogl_matrix_scale (CoglMatrix *matrix, float sy, float sz); +/** + * cogl_matrix_transform_point: + * @matrix: A 4x4 transformation matrix + * @x: The X component of your points position [in:out] + * @y: The Y component of your points position [in:out] + * @z: The Z component of your points position [in:out] + * @w: The W component of your points position [in:out] + * + * This transforms a point whos position is given and returned + * as four float components. + */ +void +cogl_matrix_transform_point (const CoglMatrix *matrix, + float *x, + float *y, + float *z, + float *w); + +/** + * cogl_matrix_init_from_gl_matrix: + * @matrix: A 4x4 transformation matrix + * @gl_matrix: A linear array of 16 Glfloats (column-major) + * + * This initialises @matrix with the contents of @gl_matrix + */ +void cogl_matrix_init_from_gl_matrix (CoglMatrix *matrix, const float *gl_matrix); + +/** + * cogl_matrix_get_gl_matrix: + * @matrix: A 4x4 transformation matrix + * + * This casts a CoglMatrix to a GLfloat array which can be directly passed to + * OpenGL. + */ +const float *cogl_matrix_get_gl_matrix (const CoglMatrix *matrix); + G_END_DECLS #endif /* __COGL_MATRIX_H */ diff --git a/clutter/cogl/cogl.h.in b/clutter/cogl/cogl.h.in index 5aab2d908..06c32a546 100644 --- a/clutter/cogl/cogl.h.in +++ b/clutter/cogl/cogl.h.in @@ -268,21 +268,19 @@ void cogl_rotate (float angle, /** * cogl_get_modelview_matrix: - * @m: pointer to a 4x4 array of #floats to receive the matrix + * @matrix: pointer to a CoglMatrix to recieve the matrix * - * Stores the current model-view matrix in @m. The matrix is in - * column-major order. + * Stores the current model-view matrix in @matrix. */ -void cogl_get_modelview_matrix (float m[16]); +void cogl_get_modelview_matrix (CoglMatrix *matrix); /** * cogl_get_projection_matrix: - * @m: pointer to a 4x4 array of #floats to receive the matrix + * @matrix: pointer to a CoglMatrix to recieve the matrix * - * Stores the current projection matrix in @m. The matrix is in - * column-major order. + * Stores the current projection matrix in @matrix. */ -void cogl_get_projection_matrix (float m[16]); +void cogl_get_projection_matrix (CoglMatrix *matrix); /** * cogl_get_viewport: diff --git a/clutter/cogl/common/cogl-clip-stack.c b/clutter/cogl/common/cogl-clip-stack.c index 23309202c..b80da0eda 100644 --- a/clutter/cogl/common/cogl-clip-stack.c +++ b/clutter/cogl/common/cogl-clip-stack.c @@ -52,7 +52,7 @@ void _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min, void _cogl_enable_clip_planes (void); void _cogl_disable_clip_planes (void); void _cogl_disable_stencil_buffer (void); -void _cogl_set_matrix (const float *matrix); +void _cogl_set_matrix (const CoglMatrix *matrix); typedef struct _CoglClipStack CoglClipStack; @@ -81,7 +81,7 @@ struct _CoglClipStackEntryRect float height; /* The matrix that was current when the clip was set */ - float matrix[16]; + CoglMatrix matrix; }; struct _CoglClipStackEntryPath @@ -89,7 +89,7 @@ struct _CoglClipStackEntryPath CoglClipStackEntryType type; /* The matrix that was current when the clip was set */ - float matrix[16]; + CoglMatrix matrix; floatVec2 path_nodes_min; floatVec2 path_nodes_max; @@ -120,7 +120,7 @@ cogl_clip_push (float x_offset, entry->width = width; entry->height = height; - cogl_get_modelview_matrix (entry->matrix); + cogl_get_modelview_matrix (&entry->matrix); /* Store it in the stack */ stack->stack_top = g_list_prepend (stack->stack_top, entry); @@ -148,7 +148,7 @@ cogl_clip_push_from_path_preserve (void) memcpy (entry->path, ctx->path_nodes->data, sizeof (CoglPathNode) * ctx->path_nodes->len); - cogl_get_modelview_matrix (entry->matrix); + cogl_get_modelview_matrix (&entry->matrix); /* Store it in the stack */ stack->stack_top = g_list_prepend (stack->stack_top, entry); @@ -226,7 +226,7 @@ _cogl_clip_stack_rebuild (void) CoglClipStackEntryPath *path = (CoglClipStackEntryPath *) entry; cogl_push_matrix (); - _cogl_set_matrix (path->matrix); + _cogl_set_matrix (&path->matrix); _cogl_add_path_to_stencil_buffer (path->path_nodes_min, path->path_nodes_max, @@ -246,7 +246,7 @@ _cogl_clip_stack_rebuild (void) CoglClipStackEntryRect *rect = (CoglClipStackEntryRect *) entry; cogl_push_matrix (); - _cogl_set_matrix (rect->matrix); + _cogl_set_matrix (&rect->matrix); /* If this is the first entry and we support clip planes then use that instead */ diff --git a/clutter/cogl/common/cogl-matrix.c b/clutter/cogl/common/cogl-matrix.c index 4d7ae6f16..26b6b926d 100644 --- a/clutter/cogl/common/cogl-matrix.c +++ b/clutter/cogl/common/cogl-matrix.c @@ -2,6 +2,7 @@ #include #include +#include void cogl_matrix_init_identity (CoglMatrix *matrix) @@ -42,7 +43,7 @@ cogl_matrix_multiply (CoglMatrix *result, r.wy = a->wx * b->xy + a->wy * b->yy + a->wz * b->zy + a->ww * b->wy; r.wz = a->wx * b->xz + a->wy * b->yz + a->wz * b->zz + a->ww * b->wz; r.ww = a->wx * b->xw + a->wy * b->yw + a->wz * b->zw + a->ww * b->ww; - + /* The idea was that having this unrolled; it might be easier for the * compiler to vectorize, but that's probably not true. Mesa does it * using a single for (i=0; i<4; i++) approach, may that's better... @@ -51,19 +52,6 @@ cogl_matrix_multiply (CoglMatrix *result, *result = r; } -/** - * cogl_3dmatrix_rotate: - * @matrix: A 3D Affine transformation matrix - * @angle: The angle in degrees you want to rotate by - * @x: The X component of your rotation vector - * @y: The Y component of your rotation vector - * @z: The Z component of your rotation vector - * - * The matrix is multiplied with a rotation matrix representing a rotation - * of angle degress around the vector (x,y,z) - * - * Since: 1.0 - */ void cogl_matrix_rotate (CoglMatrix *matrix, float angle, @@ -76,7 +64,7 @@ cogl_matrix_rotate (CoglMatrix *matrix, angle *= G_PI / 180.0f; float c = cosf (angle); float s = sinf (angle); - + rotation.xx = x * x * (1.0f - c) + c; rotation.yx = y * x * (1.0f - c) + z * s; rotation.zx = x * z * (1.0f - c) - y * s; @@ -96,7 +84,7 @@ cogl_matrix_rotate (CoglMatrix *matrix, rotation.yw = 0.0f; rotation.zw = 0.0f; rotation.ww = 1.0f; - + cogl_matrix_multiply (&result, matrix, &rotation); *matrix = result; } @@ -137,4 +125,30 @@ cogl_matrix_invert (CoglMatrix *matrix) } #endif +void +cogl_matrix_transform_point (const CoglMatrix *matrix, + float *x, + float *y, + float *z, + float *w) +{ + float _x = *x, _y = *y, _z = *z, _w = *w; + + *x = matrix->xx * _x + matrix->xy * _y + matrix->xz * _z + matrix->xw * _w; + *y = matrix->yx * _x + matrix->yy * _y + matrix->yz * _z + matrix->yw * _w; + *z = matrix->zx * _x + matrix->zy * _y + matrix->zz * _z + matrix->zw * _w; + *w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w; +} + +void +cogl_matrix_init_from_gl_matrix (CoglMatrix *matrix, const float *gl_matrix) +{ + memcpy (matrix, gl_matrix, sizeof (float) * 16); +} + +const float * +cogl_matrix_get_gl_matrix (const CoglMatrix *matrix) +{ + return (float *)matrix; +} diff --git a/clutter/cogl/gl/cogl.c b/clutter/cogl/gl/cogl.c index 27bf0c80d..8073ad10f 100644 --- a/clutter/cogl/gl/cogl.c +++ b/clutter/cogl/gl/cogl.c @@ -530,10 +530,11 @@ _cogl_add_stencil_clip (float x_offset, } void -_cogl_set_matrix (const float *matrix) +_cogl_set_matrix (const CoglMatrix *matrix) { - GE( glLoadIdentity () ); - GE( glMultMatrixf (matrix) ); + const GLfloat *gl_matrix = cogl_matrix_get_gl_matrix (matrix); + + GE (glLoadMatrixf (gl_matrix)); } void @@ -678,7 +679,7 @@ cogl_setup_viewport (guint width, float z_far) { float z_camera; - float projection_matrix[16]; + CoglMatrix projection_matrix; GE( glViewport (0, 0, width, height) ); @@ -727,8 +728,8 @@ cogl_setup_viewport (guint width, * doesn't make sense. */ - cogl_get_projection_matrix (projection_matrix); - z_camera = 0.5 * projection_matrix[0]; + cogl_get_projection_matrix (&projection_matrix); + z_camera = 0.5 * projection_matrix.xx; GE( glLoadIdentity () ); @@ -1122,15 +1123,25 @@ cogl_features_available (CoglFeatureFlags features) } void -cogl_get_modelview_matrix (float m[16]) +cogl_get_modelview_matrix (CoglMatrix *matrix) { + float m[16]; glGetFloatv (GL_MODELVIEW_MATRIX, m); + /* Since it's internal to Cogl and CoglMatrix doesn't currently have + * any flag members, we could avoid this extra copy if it really + * bothers anyone */ + cogl_matrix_init_from_gl_matrix (matrix, m); } void -cogl_get_projection_matrix (float m[16]) +cogl_get_projection_matrix (CoglMatrix *matrix) { + float m[16]; glGetFloatv (GL_PROJECTION_MATRIX, m); + /* Since it's internal to Cogl and CoglMatrix doesn't currently have + * any flag members, we could avoid this extra copy if it really + * bothers anyone */ + cogl_matrix_init_from_gl_matrix (matrix, m); } void diff --git a/clutter/cogl/gles/cogl.c b/clutter/cogl/gles/cogl.c index 7ac60256d..f096a3775 100644 --- a/clutter/cogl/gles/cogl.c +++ b/clutter/cogl/gles/cogl.c @@ -453,10 +453,11 @@ _cogl_add_stencil_clip (float x_offset, } void -_cogl_set_matrix (const float *matrix) +_cogl_set_matrix (const CoglMatrix *matrix) { - GE( glLoadIdentity () ); - GE( glMultMatrixf (matrix) ); + const GLfloat *gl_matrix = cogl_matrix_get_gl_matrix (matrix); + + GE (glLoadMatrixf (gl_matrix)); } void @@ -601,7 +602,7 @@ cogl_setup_viewport (guint width, float z_far) { float z_camera; - float projection_matrix[16]; + CoglMatrix projection_matrix; GE( glViewport (0, 0, width, height) ); @@ -617,8 +618,8 @@ cogl_setup_viewport (guint width, * See comments in ../gl/cogl.c */ - cogl_get_projection_matrix (projection_matrix); - z_camera = 0.5 * projection_matrix[0]; + cogl_get_projection_matrix (&projection_matrix); + z_camera = 0.5 * projection_matrix.xx; GE( glLoadIdentity () ); @@ -679,15 +680,25 @@ cogl_features_available (CoglFeatureFlags features) } void -cogl_get_modelview_matrix (float m[16]) +cogl_get_modelview_matrix (CoglMatrix *matrix) { + float m[16]; glGetFloatv (GL_MODELVIEW_MATRIX, m); + /* Since it's internal to Cogl and CoglMatrix doesn't currently have + * any flag members, we could avoid this extra copy if it really + * bothers anyone */ + cogl_matrix_init_from_gl_matrix (matrix, m); } void -cogl_get_projection_matrix (float m[16]) +cogl_get_projection_matrix (CoglMatrix *matrix) { + float m[16]; glGetFloatv (GL_PROJECTION_MATRIX, m); + /* Since it's internal to Cogl and CoglMatrix doesn't currently have + * any flag members, we could avoid this extra copy if it really + * bothers anyone */ + cogl_matrix_init_from_gl_matrix (matrix, m); } void