diff --git a/.gitignore b/.gitignore index c3d05ec40..4c680d98b 100644 --- a/.gitignore +++ b/.gitignore @@ -114,6 +114,7 @@ stamp-h1 /tests/interactive/test-text-field /tests/interactive/redhand.png /tests/interactive/test-script.json +/tests/interactive/test-clutter-cairo-flowers /tests/conform/test-conformance /tests/conform/test-conformance-results.xml /tests/conform/test-conformance-results.html @@ -153,6 +154,24 @@ stamp-h1 /tests/conform/test-rectangle-opacity /tests/conform/test-backface-culling /tests/conform/test-binding-pool +/tests/conform/test-text-append-some +/tests/conform/test-text-cache +/tests/conform/test-text-cursor +/tests/conform/test-text-delete-chars +/tests/conform/test-text-delete-text +/tests/conform/test-text-empty +/tests/conform/test-text-event +/tests/conform/test-text-get-chars +/tests/conform/test-text-insert +/tests/conform/test-text-password-char +/tests/conform/test-text-prepend-some +/tests/conform/test-text-set-empty +/tests/conform/test-text-set-text +/tests/conform/test-text-utf8-validation +/tests/conform/test-vertex-buffer-contiguous +/tests/conform/test-vertex-buffer-interleved +/tests/conform/test-vertex-buffer-mutability +/tests/micro-bench/test-glyph-perf /tests/micro-bench/test-text /tests/tools/disable-npots.sh /clutter/x11/clutter-x11-enum-types.[ch] diff --git a/clutter/Makefile.am b/clutter/Makefile.am index faa9480cc..ecb3e777f 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -47,6 +47,7 @@ BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES) source_h = \ $(srcdir)/clutter-actor.h \ $(srcdir)/clutter-alpha.h \ + $(srcdir)/clutter-animatable.h \ $(srcdir)/clutter-animation.h \ $(srcdir)/clutter-backend.h \ $(srcdir)/clutter-behaviour.h \ @@ -63,7 +64,6 @@ source_h = \ $(srcdir)/clutter-color.h \ $(srcdir)/clutter-container.h \ $(srcdir)/clutter-deprecated.h \ - $(srcdir)/clutter-effect.h \ $(srcdir)/clutter-event.h \ $(srcdir)/clutter-feature.h \ $(srcdir)/clutter-fixed.h \ @@ -137,6 +137,7 @@ CLEANFILES = $(STAMPFILES) source_c = \ clutter-actor.c \ clutter-alpha.c \ + clutter-animatable.c \ clutter-animation.c \ clutter-backend.c \ clutter-behaviour.c \ @@ -153,7 +154,6 @@ source_c = \ clutter-clone-texture.c \ clutter-color.c \ clutter-container.c \ - clutter-effect.c \ clutter-enum-types.c \ clutter-event.c \ clutter-feature.c \ diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 2f39c4f0c..c8b90c82c 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -610,13 +610,20 @@ clutter_actor_real_pick (ClutterActor *self, */ if (clutter_actor_should_pick_paint (self)) { + ClutterActorBox box = { 0, }; + float width, height; + + clutter_actor_get_allocation_box (self, &box); + + width = CLUTTER_UNITS_TO_FLOAT (box.x2 - box.x1); + height = CLUTTER_UNITS_TO_FLOAT (box.y2 - box.y1); + cogl_set_source_color4ub (color->red, color->green, color->blue, color->alpha); - cogl_rectangle (0, 0, - clutter_actor_get_width (self), - clutter_actor_get_height (self)); + + cogl_rectangle (0, 0, width, height); } } @@ -774,12 +781,12 @@ clutter_actor_real_allocate (ClutterActor *self, g_object_thaw_notify (G_OBJECT (self)); } -/* like ClutterVertex, but using CoglFixed and with a w component */ +/* like ClutterVertex, but using float and with a w component */ typedef struct { - CoglFixed x; - CoglFixed y; - CoglFixed z; - CoglFixed w; + float x; + float y; + float z; + float w; } fixed_vertex_t; /* copies a fixed vertex into a ClutterVertex */ @@ -806,7 +813,7 @@ static inline void mtx_transform (const ClutterFixed m[], fixed_vertex_t *vertex) { - ClutterFixed _x, _y, _z, _w; + float _x, _y, _z, _w; _x = vertex->x; _y = vertex->y; @@ -816,25 +823,25 @@ mtx_transform (const ClutterFixed m[], /* 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); + 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 = 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); + 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 = 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); + 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 = 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); + 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 ;) @@ -846,8 +853,11 @@ mtx_transform (const ClutterFixed 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_X(x,w,v1,v2) \ + (CLUTTER_FIXED_MUL (((CLUTTER_FIXED_DIV ((x), (w)) + 1.0) / 2), (v1)) + (v2)) +#define MTX_GL_SCALE_Y(y,w,v1,v2) \ + ((v1) - CLUTTER_FIXED_MUL (((CLUTTER_FIXED_DIV ((y), (w)) + 1.0) / 2), \ + (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 @@ -1024,7 +1034,7 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, 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; + w = 1.0; /* First we tranform the point using the OpenGL modelview matrix */ clutter_actor_transform_point_relative (self, ancestor, &x, &y, &z, &w); @@ -1035,9 +1045,9 @@ 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. */ - tmp.x = COGL_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (x) + COGL_FIXED_0_5, v[2]); - tmp.y = COGL_FIXED_MUL (COGL_FIXED_0_5 - CLUTTER_UNITS_TO_FIXED (y), v[3]); - tmp.z = COGL_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (z) + COGL_FIXED_0_5, v[2]); + tmp.x = CLUTTER_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (x) + 0.5, v[2]); + tmp.y = CLUTTER_FIXED_MUL (0.5 - CLUTTER_UNITS_TO_FIXED (y), v[3]); + tmp.z = CLUTTER_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (z) + 0.5, v[2]); tmp.w = 0; fixed_vertex_to_units (&tmp, vertex); @@ -1119,10 +1129,10 @@ clutter_actor_transform_vertices_relative (ClutterActor *self, cogl_get_modelview_matrix (mtx); - 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]); + 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(); } @@ -1171,10 +1181,10 @@ clutter_actor_transform_and_project_box (ClutterActor *self, cogl_get_modelview_matrix (mtx); - 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]); + 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(); @@ -1261,24 +1271,24 @@ clutter_actor_get_allocation_vertices (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. */ - 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]); + tmp.x = CLUTTER_FIXED_MUL ((vertices[0].x + 0.5), v[2]); + tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[0].y), v[3]); + tmp.z = CLUTTER_FIXED_MUL ((vertices[0].z + 0.5), v[2]); fixed_vertex_to_units (&tmp, &verts[0]); - 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]); + tmp.x = CLUTTER_FIXED_MUL ((vertices[1].x + 0.5), v[2]); + tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[1].y), v[3]); + tmp.z = CLUTTER_FIXED_MUL ((vertices[1].z + 0.5), v[2]); fixed_vertex_to_units (&tmp, &verts[1]); - 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]); + tmp.x = CLUTTER_FIXED_MUL ((vertices[2].x + 0.5), v[2]); + tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[2].y), v[3]); + tmp.z = CLUTTER_FIXED_MUL ((vertices[2].z + 0.5), v[2]); fixed_vertex_to_units (&tmp, &verts[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]); + tmp.x = CLUTTER_FIXED_MUL ((vertices[3].x + 0.5), v[2]); + tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[3].y), v[3]); + tmp.z = CLUTTER_FIXED_MUL ((vertices[3].z + 0.5), v[2]); fixed_vertex_to_units (&tmp, &verts[3]); } @@ -1345,8 +1355,8 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self) gboolean is_stage = CLUTTER_IS_STAGE (self); if (!is_stage) - cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->allocation.x1), - CLUTTER_UNITS_TO_FIXED (priv->allocation.y1), + cogl_translate (CLUTTER_UNITS_TO_FLOAT (priv->allocation.x1), + CLUTTER_UNITS_TO_FLOAT (priv->allocation.y1), 0); /* @@ -1355,55 +1365,55 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self) * the translations included in the rotation are not scaled and so the * entire object will move on the screen as a result of rotating it). */ - if (priv->scale_x != COGL_FIXED_1 || priv->scale_y != COGL_FIXED_1) + if (priv->scale_x != 1.0 || priv->scale_y != 1.0) cogl_scale (priv->scale_x, priv->scale_y); if (priv->rzang) { - cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->rzx), - CLUTTER_UNITS_TO_FIXED (priv->rzy), + cogl_translate (CLUTTER_UNITS_TO_FLOAT (priv->rzx), + CLUTTER_UNITS_TO_FLOAT (priv->rzy), 0); - cogl_rotatex (priv->rzang, 0, 0, COGL_FIXED_1); + cogl_rotate (priv->rzang, 0, 0, 1.0); - cogl_translatex (CLUTTER_UNITS_TO_FIXED (-priv->rzx), - CLUTTER_UNITS_TO_FIXED (-priv->rzy), + cogl_translate (CLUTTER_UNITS_TO_FLOAT (-priv->rzx), + CLUTTER_UNITS_TO_FLOAT (-priv->rzy), 0); } if (priv->ryang) { - cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->ryx), + cogl_translate (CLUTTER_UNITS_TO_FLOAT (priv->ryx), 0, - CLUTTER_UNITS_TO_FIXED (priv->z + priv->ryz)); + CLUTTER_UNITS_TO_FLOAT (priv->z + priv->ryz)); - cogl_rotatex (priv->ryang, 0, COGL_FIXED_1, 0); + cogl_rotate (priv->ryang, 0, 1.0, 0); - cogl_translatex (CLUTTER_UNITS_TO_FIXED (-priv->ryx), + cogl_translate (CLUTTER_UNITS_TO_FLOAT (-priv->ryx), 0, - CLUTTER_UNITS_TO_FIXED (-(priv->z + priv->ryz))); + CLUTTER_UNITS_TO_FLOAT (-(priv->z + priv->ryz))); } if (priv->rxang) { - cogl_translatex (0, - CLUTTER_UNITS_TO_FIXED (priv->rxy), - CLUTTER_UNITS_TO_FIXED (priv->z + priv->rxz)); + cogl_translate (0, + CLUTTER_UNITS_TO_FLOAT (priv->rxy), + CLUTTER_UNITS_TO_FLOAT (priv->z + priv->rxz)); - cogl_rotatex (priv->rxang, COGL_FIXED_1, 0, 0); + cogl_rotate (priv->rxang, 1.0, 0, 0); - cogl_translatex (0, - CLUTTER_UNITS_TO_FIXED (-priv->rxy), - CLUTTER_UNITS_TO_FIXED (-(priv->z + priv->rxz))); + cogl_translate (0, + CLUTTER_UNITS_TO_FLOAT (-priv->rxy), + CLUTTER_UNITS_TO_FLOAT (-(priv->z + priv->rxz))); } if (!is_stage && (priv->anchor_x || priv->anchor_y)) - cogl_translatex (CLUTTER_UNITS_TO_FIXED (-priv->anchor_x), - CLUTTER_UNITS_TO_FIXED (-priv->anchor_y), + cogl_translate (CLUTTER_UNITS_TO_FLOAT (-priv->anchor_x), + CLUTTER_UNITS_TO_FLOAT (-priv->anchor_y), 0); if (priv->z) - cogl_translatex (0, 0, priv->z); + cogl_translate (0, 0, priv->z); } /* Recursively applies the transforms associated with this actor and @@ -1656,14 +1666,14 @@ clutter_actor_set_property (GObject *object, case PROP_SCALE_X: clutter_actor_set_scalex (actor, - COGL_FIXED_FROM_FLOAT (g_value_get_double (value)), + CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)), priv->scale_y); break; case PROP_SCALE_Y: clutter_actor_set_scalex (actor, priv->scale_x, - COGL_FIXED_FROM_FLOAT (g_value_get_double (value))); + CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value))); break; case PROP_CLIP: { @@ -1681,7 +1691,7 @@ clutter_actor_set_property (GObject *object, { ClutterFixed angle; - angle = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + angle = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); clutter_actor_set_rotation_internal (actor, CLUTTER_X_AXIS, angle, @@ -1694,7 +1704,7 @@ clutter_actor_set_property (GObject *object, { ClutterFixed angle; - angle = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + angle = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); clutter_actor_set_rotation_internal (actor, CLUTTER_Y_AXIS, angle, @@ -1707,7 +1717,7 @@ clutter_actor_set_property (GObject *object, { ClutterFixed angle; - angle = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + angle = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); clutter_actor_set_rotation_internal (actor, CLUTTER_Z_AXIS, angle, @@ -1877,22 +1887,22 @@ clutter_actor_get_property (GObject *object, } break; case PROP_SCALE_X: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->scale_x)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->scale_x)); break; case PROP_SCALE_Y: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->scale_y)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->scale_y)); break; case PROP_REACTIVE: g_value_set_boolean (value, clutter_actor_get_reactive (actor)); break; case PROP_ROTATION_ANGLE_X: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->rxang)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->rxang)); break; case PROP_ROTATION_ANGLE_Y: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->ryang)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->ryang)); break; case PROP_ROTATION_ANGLE_Z: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->rzang)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->rzang)); break; case PROP_ROTATION_CENTER_X: { @@ -3020,8 +3030,8 @@ clutter_actor_init (ClutterActor *self) priv->has_clip = FALSE; priv->opacity = 0xff; priv->id = clutter_id_pool_add (CLUTTER_CONTEXT()->id_pool, self); - priv->scale_x = COGL_FIXED_1; - priv->scale_y = COGL_FIXED_1; + priv->scale_x = 1.0; + priv->scale_y = 1.0; priv->shader_data = NULL; priv->show_on_set_parent = TRUE; @@ -3079,6 +3089,9 @@ clutter_actor_destroy (ClutterActor *self) * * Applications rarely need to call this, as redraws are handled * automatically by modification functions. + * + * This function will not do anything if @self is not visible, or + * if the actor is inside an invisible part of the scenegraph. */ void clutter_actor_queue_redraw (ClutterActor *self) @@ -3087,7 +3100,16 @@ clutter_actor_queue_redraw (ClutterActor *self) g_return_if_fail (CLUTTER_IS_ACTOR (self)); - /* FIXME: should we check we're visible here? */ + /* short-circuit the trivial case */ + if (!CLUTTER_ACTOR_IS_VISIBLE (self)) + return; + + /* check if any part of the scenegraph we're in + * is not visible + */ + if (!clutter_actor_get_paint_visibility (self)) + return; + if ((stage = clutter_actor_get_stage (self)) != NULL) clutter_stage_queue_redraw (CLUTTER_STAGE (stage)); } @@ -4916,8 +4938,8 @@ clutter_actor_set_scale (ClutterActor *self, g_return_if_fail (CLUTTER_IS_ACTOR (self)); clutter_actor_set_scalex (self, - COGL_FIXED_FROM_FLOAT (scale_x), - COGL_FIXED_FROM_FLOAT (scale_y)); + CLUTTER_FLOAT_TO_FIXED (scale_x), + CLUTTER_FLOAT_TO_FIXED (scale_y)); } /** @@ -4964,10 +4986,10 @@ clutter_actor_get_scale (ClutterActor *self, g_return_if_fail (CLUTTER_IS_ACTOR (self)); if (scale_x) - *scale_x = COGL_FIXED_TO_FLOAT (self->priv->scale_x); + *scale_x = CLUTTER_FIXED_TO_FLOAT (self->priv->scale_x); if (scale_y) - *scale_y = COGL_FIXED_TO_FLOAT (self->priv->scale_y); + *scale_y = CLUTTER_FIXED_TO_FLOAT (self->priv->scale_y); } /** @@ -5224,7 +5246,7 @@ clutter_actor_set_rotationu (ClutterActor *self, g_return_if_fail (CLUTTER_IS_ACTOR (self)); clutter_actor_set_rotation_internal (self, axis, - COGL_FIXED_FROM_FLOAT (angle), + CLUTTER_FLOAT_TO_FIXED (angle), x, y, z); } @@ -5294,7 +5316,7 @@ clutter_actor_set_rotation (ClutterActor *self, g_return_if_fail (CLUTTER_IS_ACTOR (self)); clutter_actor_set_rotationx (self, axis, - COGL_FIXED_FROM_FLOAT (angle), + CLUTTER_FLOAT_TO_FIXED (angle), x, y, z); } @@ -5335,7 +5357,7 @@ clutter_actor_get_rotationu (ClutterActor *self, switch (axis) { case CLUTTER_X_AXIS: - retval = COGL_FIXED_TO_DOUBLE (priv->rxang); + retval = CLUTTER_FIXED_TO_DOUBLE (priv->rxang); if (y) *y = priv->rxy; if (z) @@ -5343,7 +5365,7 @@ clutter_actor_get_rotationu (ClutterActor *self, break; case CLUTTER_Y_AXIS: - retval = COGL_FIXED_TO_DOUBLE (priv->ryang); + retval = CLUTTER_FIXED_TO_DOUBLE (priv->ryang); if (x) *x = priv->ryx; if (z) @@ -5351,7 +5373,7 @@ clutter_actor_get_rotationu (ClutterActor *self, break; case CLUTTER_Z_AXIS: - retval = COGL_FIXED_TO_DOUBLE (priv->rzang); + retval = CLUTTER_FIXED_TO_DOUBLE (priv->rzang); if (x) *x = priv->rzx; if (y) @@ -5450,7 +5472,7 @@ clutter_actor_get_rotation (ClutterActor *self, { g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.0); - return COGL_FIXED_TO_FLOAT (clutter_actor_get_rotationx (self, + return CLUTTER_FIXED_TO_FLOAT (clutter_actor_get_rotationx (self, axis, x, y, z)); } @@ -6521,6 +6543,8 @@ parse_units (ClutterActor *self, if (end[0] == '%' && end[1] == '\0') { + ClutterActor *stage; + if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL) { g_warning ("Unable to set percentage of %s on a top-level " @@ -6533,12 +6557,20 @@ parse_units (ClutterActor *self, goto out; } + stage = clutter_actor_get_stage (self); + if (stage == NULL) + stage = clutter_stage_get_default (); + if (dimension == PARSE_X || dimension == PARSE_WIDTH || dimension == PARSE_ANCHOR_X) - retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val); + { + retval = clutter_actor_get_widthu (stage) * val; + } else - retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val); + { + retval = clutter_actor_get_heightu (stage) * val; + } goto out; } @@ -6553,7 +6585,12 @@ parse_units (ClutterActor *self, } else if (G_VALUE_HOLDS (&value, G_TYPE_DOUBLE)) { - gint val; + ClutterActor *stage; + gdouble val; + + stage = clutter_actor_get_stage (self); + if (stage == NULL) + stage = clutter_stage_get_default (); if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL) { @@ -6566,14 +6603,18 @@ parse_units (ClutterActor *self, goto out; } - val = CLAMP (g_value_get_double (&value) * 100, 0, 100); + val = g_value_get_double (&value); if (dimension == PARSE_X || dimension == PARSE_WIDTH || dimension == PARSE_ANCHOR_X) - retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val); + { + retval = clutter_actor_get_widthu (stage) * val; + } else - retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val); + { + retval = clutter_actor_get_heightu (stage) * val; + } } else { @@ -6612,7 +6653,7 @@ parse_rotation_array (ClutterActor *actor, /* angle */ element = json_array_get_element (array, 0); if (JSON_NODE_TYPE (element) == JSON_NODE_VALUE) - info->angle = COGL_FIXED_FROM_FLOAT (json_node_get_double (element)); + info->angle = CLUTTER_FLOAT_TO_FIXED (json_node_get_double (element)); else return FALSE; @@ -6918,12 +6959,12 @@ clutter_actor_transform_stage_point (ClutterActor *self, if (!du || !dv) return FALSE; -#define FP2FX COGL_FIXED_FROM_FLOAT -#define FX2FP COGL_FIXED_TO_DOUBLE +#define FP2FX CLUTTER_FLOAT_TO_FIXED +#define FX2FP CLUTTER_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 DET2X(a,b,c,d) ((a * d) - (b * c)) #define DET2FP(a,b,c,d) ((a) * (d) - (b) * (c)) /* @@ -6946,7 +6987,7 @@ clutter_actor_transform_stage_point (ClutterActor *self, RQ[2][1] = UX2FX (v[0].y); RQ[0][2] = 0; RQ[1][2] = 0; - RQ[2][2] = COGL_FIXED_1; + RQ[2][2] = 1.0; } else { @@ -6976,16 +7017,16 @@ clutter_actor_transform_stage_point (ClutterActor *self, 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[2][2] = 1.0; RQ[0][0] = UX2FX (v[1].x - v[0].x) - + COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].x)); + + CLUTTER_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)); + + CLUTTER_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)); + + CLUTTER_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)); + + CLUTTER_FIXED_MUL (RQ[1][2], UX2FX (v[2].y)); RQ[2][1] = UX2FX (v[0].y); } @@ -7017,9 +7058,9 @@ clutter_actor_transform_stage_point (ClutterActor *self, /* * Check the resutling martix is OK. */ - det = COGL_FIXED_MUL (RQ[0][0], ST[0][0]) - + COGL_FIXED_MUL (RQ[0][1], ST[0][1]) - + COGL_FIXED_MUL (RQ[0][2], ST[0][2]); + det = CLUTTER_FIXED_MUL (RQ[0][0], ST[0][0]) + + CLUTTER_FIXED_MUL (RQ[0][1], ST[0][1]) + + CLUTTER_FIXED_MUL (RQ[0][2], ST[0][2]); if (!det) return FALSE; @@ -7481,7 +7522,7 @@ clutter_actor_is_scaled (ClutterActor *self) priv = self->priv; - if (priv->scale_x != COGL_FIXED_1 || priv->scale_y != COGL_FIXED_1) + if (priv->scale_x != 1.0 || priv->scale_y != 1.0) return TRUE; return FALSE; diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index af962caf1..f6d889982 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -74,10 +74,10 @@ G_BEGIN_DECLS */ #define CLUTTER_ACTOR_UNSET_FLAGS(a,f) (((ClutterActor*)(a))->flags &= ~(f)) -#define CLUTTER_ACTOR_IS_MAPPED(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_MAPPED) -#define CLUTTER_ACTOR_IS_REALIZED(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REALIZED) +#define CLUTTER_ACTOR_IS_MAPPED(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_MAPPED) != FALSE) +#define CLUTTER_ACTOR_IS_REALIZED(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REALIZED) != FALSE) #define CLUTTER_ACTOR_IS_VISIBLE(e) (CLUTTER_ACTOR_IS_MAPPED (e) && CLUTTER_ACTOR_IS_REALIZED (e)) -#define CLUTTER_ACTOR_IS_REACTIVE(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REACTIVE) +#define CLUTTER_ACTOR_IS_REACTIVE(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE) typedef struct _ClutterActorClass ClutterActorClass; typedef struct _ClutterActorBox ClutterActorBox; diff --git a/clutter/clutter-alpha.c b/clutter/clutter-alpha.c index dc1dddeba..31c325363 100644 --- a/clutter/clutter-alpha.c +++ b/clutter/clutter-alpha.c @@ -40,11 +40,15 @@ * alpha value into something meaningful for a #ClutterActor. * * You should provide a #ClutterTimeline and bind it to the #ClutterAlpha - * instance using clutter_alpha_set_timeline(); you should also provide a - * function returning the alpha value depending on the progress of the - * timeline, using clutter_alpha_set_func() or clutter_alpha_set_closure(). - * The alpha function will be executed each time a new frame in the - * #ClutterTimeline is reached. + * instance using clutter_alpha_set_timeline(). You should also set an + * "animation mode", either by using the #ClutterAnimatioMode values that + * Clutter itself provides or by registering custom functions. + * + * Instead of a #ClutterAnimationMode you may provide a function returning + * the alpha value depending on the progress of the timeline, using + * clutter_alpha_set_func() or clutter_alpha_set_closure(). The alpha + * function will be executed each time a new frame in the #ClutterTimeline + * is reached. * * Since the alpha function is controlled by the timeline instance, you can * pause, stop or resume the #ClutterAlpha from calling the alpha function by @@ -85,7 +89,7 @@ struct _ClutterAlphaPrivate GClosure *closure; - ClutterAnimationMode mode; + gulong mode; }; enum @@ -126,9 +130,11 @@ clutter_alpha_set_property (GObject *object, case PROP_TIMELINE: clutter_alpha_set_timeline (alpha, g_value_get_object (value)); break; + case PROP_MODE: - clutter_alpha_set_mode (alpha, g_value_get_enum (value)); + clutter_alpha_set_mode (alpha, g_value_get_ulong (value)); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -152,12 +158,15 @@ clutter_alpha_get_property (GObject *object, case PROP_TIMELINE: g_value_set_object (value, priv->timeline); break; + case PROP_ALPHA: g_value_set_uint (value, priv->alpha); break; + case PROP_MODE: - g_value_set_enum (value, priv->mode); + g_value_set_ulong (value, priv->mode); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -231,22 +240,25 @@ clutter_alpha_class_init (ClutterAlphaClass *klass) /** * ClutterAlpha:mode: * - * The progress function as a #ClutterAnimationMode enumeration - * value. If %CLUTTER_CUSTOM_MODE is used then the function set - * using clutter_alpha_set_closure() or clutter_alpha_set_func() + * The progress function logical id - either a value from the + * #ClutterAnimationMode enumeration or a value returned by + * clutter_alpha_register_func(). + * + * If %CLUTTER_CUSTOM_MODE is used then the function set using + * clutter_alpha_set_closure() or clutter_alpha_set_func() * will be used. * * Since: 1.0 */ g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_enum ("mode", - "Mode", - "Progress mode", - CLUTTER_TYPE_ANIMATION_MODE, - CLUTTER_CUSTOM_MODE, - G_PARAM_CONSTRUCT | - CLUTTER_PARAM_READWRITE)); + g_param_spec_ulong ("mode", + "Mode", + "Progress mode", + 0, G_MAXULONG, + CLUTTER_CUSTOM_MODE, + G_PARAM_CONSTRUCT | + CLUTTER_PARAM_READWRITE)); } static void @@ -313,9 +325,8 @@ clutter_alpha_get_alpha (ClutterAlpha *alpha) * @alpha: A #ClutterAlpha * @closure: A #GClosure * - * Sets the #GClosure used to compute - * the alpha value at each frame of the #ClutterTimeline - * bound to @alpha. + * Sets the #GClosure used to compute the alpha value at each + * frame of the #ClutterTimeline bound to @alpha. * * Since: 0.8 */ @@ -358,6 +369,8 @@ clutter_alpha_set_closure (ClutterAlpha *alpha, * the alpha value at each frame of the #ClutterTimeline * bound to @alpha. * + * This function will not register @func as a global alpha function. + * * Since: 0.2 */ void @@ -462,22 +475,53 @@ clutter_alpha_new (void) /** * clutter_alpha_new_full: * @timeline: #ClutterTimeline timeline - * @func: #ClutterAlphaFunc alpha function - * @data: data to be passed to the alpha function - * @destroy: notify to be called when removing the alpha function + * @mode: animation mode * * Creates a new #ClutterAlpha instance and sets the timeline - * and alpha function. + * and animation mode. + * + * See also clutter_alpha_set_timeline() and clutter_alpha_set_mode(). * * Return Value: the newly created #ClutterAlpha * - * Since: 0.2 + * Since: 1.0 */ ClutterAlpha * -clutter_alpha_new_full (ClutterTimeline *timeline, - ClutterAlphaFunc func, - gpointer data, - GDestroyNotify destroy) +clutter_alpha_new_full (ClutterTimeline *timeline, + gulong mode) +{ + g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); + g_return_val_if_fail (mode != CLUTTER_ANIMATION_LAST, NULL); + + return g_object_new (CLUTTER_TYPE_ALPHA, + "timeline", timeline, + "mode", mode, + NULL); +} + +/** + * clutter_alpha_new_with_func: + * @timeline: a #ClutterTimeline + * @func: a #ClutterAlphaFunc + * @data: data to pass to the function, or %NULL + * @destroy: function to call when removing the alpha function, or %NULL + * + * Creates a new #ClutterAlpha instances and sets the timeline + * and the alpha function. + * + * This function will not register @func as a global alpha function. + * + * See also clutter_alpha_set_timeline() and clutter_alpha_set_func(). + * + * Return value: the newly created #ClutterAlpha + * + * Since: 1.0 + */ +ClutterAlpha * +clutter_alpha_new_with_func (ClutterTimeline *timeline, + ClutterAlphaFunc func, + gpointer data, + GDestroyNotify destroy) { ClutterAlpha *retval; @@ -485,32 +529,12 @@ clutter_alpha_new_full (ClutterTimeline *timeline, g_return_val_if_fail (func != NULL, NULL); retval = clutter_alpha_new (); - clutter_alpha_set_timeline (retval, timeline); clutter_alpha_set_func (retval, func, data, destroy); return retval; } -/** - * clutter_alpha_new_for_mode: - * @mode: a #ClutterAnimationMode value - * - * Creates a new #ClutterAlpha using @mode to set the - * progress function using its symbolic name. - * - * Return value: the newly created #ClutterAlpha - * - * Since: 1.0 - */ -ClutterAlpha * -clutter_alpha_new_for_mode (ClutterAnimationMode mode) -{ - return g_object_new (CLUTTER_TYPE_ALPHA, - "mode", mode, - NULL); -} - /** * clutter_alpha_get_mode: * @alpha: a #ClutterAlpha @@ -521,7 +545,7 @@ clutter_alpha_new_for_mode (ClutterAnimationMode mode) * * Since: 1.0 */ -ClutterAnimationMode +gulong clutter_alpha_get_mode (ClutterAlpha *alpha) { g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), CLUTTER_CUSTOM_MODE); @@ -529,9 +553,13 @@ clutter_alpha_get_mode (ClutterAlpha *alpha) return alpha->priv->mode; } -/* XXX - keep in sync with ClutterAnimationMode */ +/* static enum/function mapping table for the animation modes + * we provide internally + * + * XXX - keep in sync with ClutterAnimationMode + */ static const struct { - ClutterAnimationMode mode; + gulong mode; ClutterAlphaFunc func; } animation_modes[] = { { CLUTTER_CUSTOM_MODE, NULL }, @@ -545,46 +573,161 @@ static const struct { { CLUTTER_EXPO_IN, clutter_exp_in_func }, { CLUTTER_EXPO_OUT, clutter_exp_out_func }, { CLUTTER_EXPO_IN_OUT, clutter_exp_in_out_func }, - { CLUTTER_SMOOTH_IN_OUT, clutter_smoothstep_inc_func } + { CLUTTER_SMOOTH_IN_OUT, clutter_smoothstep_inc_func }, + { CLUTTER_ANIMATION_LAST, NULL }, }; +typedef struct _AlphaData { + guint closure_set : 1; + + ClutterAlphaFunc func; + gpointer data; + + GClosure *closure; +} AlphaData; + +static GPtrArray *clutter_alphas = NULL; + /** * clutter_alpha_set_mode: * @alpha: a #ClutterAlpha * @mode: a #ClutterAnimationMode * * Sets the progress function of @alpha using the symbolic value - * of @mode, as taken by the #ClutterAnimationMode enumeration + * of @mode, as taken by the #ClutterAnimationMode enumeration or + * using the value returned by clutter_alpha_register_func(). * * Since: 1.0 */ void -clutter_alpha_set_mode (ClutterAlpha *alpha, - ClutterAnimationMode mode) +clutter_alpha_set_mode (ClutterAlpha *alpha, + gulong mode) { ClutterAlphaPrivate *priv; g_return_if_fail (CLUTTER_IS_ALPHA (alpha)); + g_return_if_fail (mode != CLUTTER_ANIMATION_LAST); priv = alpha->priv; - /* sanity check to avoid getting an out of sync enum/function mapping */ - g_assert (animation_modes[mode].mode == mode); - if (G_LIKELY (animation_modes[mode].func != NULL)) - clutter_alpha_set_func (alpha, animation_modes[mode].func, NULL, NULL); + if (mode < CLUTTER_ANIMATION_LAST) + { + /* sanity check to avoid getting an out of sync + * enum/function mapping + */ + g_assert (animation_modes[mode].mode == mode); - priv->mode = mode; + if (G_LIKELY (animation_modes[mode].func != NULL)) + clutter_alpha_set_func (alpha, animation_modes[mode].func, NULL, NULL); + + priv->mode = mode; + } + else if (mode > CLUTTER_ANIMATION_LAST) + { + AlphaData *alpha_data = NULL; + gulong real_index = 0; + + if (G_UNLIKELY (clutter_alphas == NULL)) + { + g_warning ("No alpha functions defined for ClutterAlpha to use. " + "Use clutter_alpha_register_func() to register an " + "alpha function."); + return; + } + + real_index = mode - CLUTTER_ANIMATION_LAST - 1; + + alpha_data = g_ptr_array_index (clutter_alphas, real_index); + if (G_UNLIKELY (alpha_data == NULL)) + { + g_warning ("No alpha function registered for mode %lu.", + mode); + return; + } + + if (alpha_data->closure_set) + clutter_alpha_set_closure (alpha, alpha_data->closure); + else + clutter_alpha_set_func (alpha, alpha_data->func, + alpha_data->data, + NULL); + + priv->mode = mode; + } + else + g_assert_not_reached (); g_object_notify (G_OBJECT (alpha), "mode"); } /** - * CLUTTER_ALPHA_RAMP_INC: + * clutter_alpha_register_func: + * @func: a #ClutterAlphaFunc + * @data: user data to pass to @func, or %NULL * - * Convenience symbol for clutter_ramp_inc_func(). + * Registers a global alpha function and returns its logical id + * to be used by clutter_alpha_set_mode() or by #ClutterAnimation. * - * Since: 0.2 + * The logical id is always greater than %CLUTTER_ANIMATION_LAST. + * + * Return value: the logical id of the alpha function + * + * Since: 1.0 */ +gulong +clutter_alpha_register_func (ClutterAlphaFunc func, + gpointer data) +{ + AlphaData *alpha_data; + + g_return_val_if_fail (func != NULL, 0); + + alpha_data = g_slice_new (AlphaData); + alpha_data->closure_set = FALSE; + alpha_data->func = func; + alpha_data->data = data; + + if (G_UNLIKELY (clutter_alphas == NULL)) + clutter_alphas = g_ptr_array_new (); + + g_ptr_array_add (clutter_alphas, alpha_data); + + return clutter_alphas->len + CLUTTER_ANIMATION_LAST; +} + +/** + * clutter_alpha_register_closure: + * @closure: a #GClosure + * + * #GClosure variant of clutter_alpha_register_func(). + * + * Registers a global alpha function and returns its logical id + * to be used by clutter_alpha_set_mode() or by #ClutterAnimation. + * + * The logical id is always greater than %CLUTTER_ANIMATION_LAST. + * + * Return value: the logical id of the alpha function + * + * Since: 1.0 + */ +gulong +clutter_alpha_register_closure (GClosure *closure) +{ + AlphaData *data; + + g_return_val_if_fail (closure != NULL, 0); + + data = g_slice_new (AlphaData); + data->closure_set = TRUE; + data->closure = closure; + + if (G_UNLIKELY (clutter_alphas == NULL)) + clutter_alphas = g_ptr_array_new (); + + g_ptr_array_add (clutter_alphas, data); + + return clutter_alphas->len + CLUTTER_ANIMATION_LAST; +} /** * clutter_ramp_inc_func: @@ -697,14 +840,19 @@ clutter_ramp_func (ClutterAlpha *alpha, } } +#if 0 +/* + * The following three functions are left in place for reference + * purposes. + */ static guint32 sincx1024_func (ClutterAlpha *alpha, - ClutterAngle angle, + float angle, ClutterFixed offset) { ClutterTimeline *timeline; gint current_frame_num, n_frames; - ClutterAngle x; + float x; ClutterFixed sine; timeline = clutter_alpha_get_timeline (alpha); @@ -724,11 +872,6 @@ sincx1024_func (ClutterAlpha *alpha, return sine; } -#if 0 -/* - * The following two functions are left in place for reference - * purposes. - */ static guint32 sincx_func (ClutterAlpha *alpha, ClutterFixed angle, @@ -744,14 +887,14 @@ sincx_func (ClutterAlpha *alpha, n_frames = clutter_timeline_get_n_frames (timeline); x = angle * current_frame_num / n_frames; - x = COGL_FIXED_FAST_MUL (x, COGL_FIXED_PI) - - COGL_FIXED_FAST_DIV (COGL_FIXED_PI, angle); + x = CLUTTER_FIXED_MUL (x, CFX_PI) + - CLUTTER_FIXED_DIV (CFX_PI, angle); - sine = (cogl_fixed_sin (x) + offset) / 2; + sine = (cogl_angle_sin (x) + offset) / 2; - CLUTTER_NOTE (ALPHA, "sine: %2f\n", COGL_FIXED_TO_DOUBLE (sine)); + CLUTTER_NOTE (ALPHA, "sine: %2f\n", CLUTTER_FIXED_TO_DOUBLE (sine)); - return COGL_FIXED_TO_INT (sine * CLUTTER_ALPHA_MAX_ALPHA); + return (sine * CLUTTER_ALPHA_MAX_ALPHA); } /* NB: angle is not in radians but in muliples of PI, i.e., 2.0 @@ -806,11 +949,30 @@ guint32 clutter_sine_func (ClutterAlpha *alpha, gpointer dummy) { -#if 0 +#if 1 + ClutterTimeline *timeline; + gint current_frame_num, n_frames; + float radians, sine; + + timeline = clutter_alpha_get_timeline (alpha); + + current_frame_num = clutter_timeline_get_current_frame (timeline); + n_frames = clutter_timeline_get_n_frames (timeline); + + radians = ((float)current_frame_num / n_frames) * (2.0 * G_PI); + sine = sinf (radians); + + /* shift from range [-1, 1] -> [0, 1] */ + sine = (sine + 1.0) / 2.0; + + CLUTTER_NOTE (ALPHA, "sine: %2f\n", sine); + + return sine * CLUTTER_ALPHA_MAX_ALPHA; +#elif 0 return sinc_func (alpha, 2.0, 1.0); -#else +#elif 0 /* 2.0 above represents full circle */ - return sincx1024_func (alpha, 1024, COGL_FIXED_1); + return sincx1024_func (alpha, 1024, 1.0); #endif } @@ -842,18 +1004,17 @@ clutter_sine_inc_func (ClutterAlpha *alpha, ClutterTimeline * timeline; gint frame; gint n_frames; - ClutterAngle x; - ClutterFixed sine; + float radians; + float sine; timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - x = 256 * frame / n_frames; + radians = ((float)frame / n_frames) * (G_PI / 2); + sine = sinf (radians); - sine = cogl_angle_sin (x) * CLUTTER_ALPHA_MAX_ALPHA; - - return ((guint32) sine) >> COGL_FIXED_Q; + return (guint32) (sine * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -884,18 +1045,17 @@ clutter_sine_dec_func (ClutterAlpha *alpha, ClutterTimeline * timeline; gint frame; gint n_frames; - ClutterAngle x; - ClutterFixed sine; + float radians; + float sine; timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - x = 256 * frame / n_frames + 256; + radians = ((float)frame / n_frames) * (G_PI / 2); + sine = sinf (radians + (G_PI / 2)); - sine = cogl_angle_sin (x) * CLUTTER_ALPHA_MAX_ALPHA; - - return ((guint32) sine) >> COGL_FIXED_Q; + return (guint32) (sine * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -926,18 +1086,17 @@ clutter_sine_half_func (ClutterAlpha *alpha, ClutterTimeline *timeline; gint frame; gint n_frames; - ClutterAngle x; - ClutterFixed sine; + float radians; + float sine; timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - x = 512 * frame / n_frames; + radians = ((float)frame / n_frames) * G_PI; + sine = sinf (radians); - sine = cogl_angle_sin (x) * CLUTTER_ALPHA_MAX_ALPHA; - - return ((guint32) sine) >> COGL_FIXED_Q; + return (guint32) (sine * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -962,19 +1121,20 @@ clutter_sine_in_func (ClutterAlpha *alpha, ClutterTimeline *timeline; gint frame; gint n_frames; - ClutterAngle x; - ClutterFixed sine; + float radians; + float sine; timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - /* XXX- if we use 768 we overflow */ - x = 256 * frame / n_frames + 767; + radians = ((float)frame / n_frames) * (G_PI / 2); + sine = sinf (radians - (G_PI / 2)); - sine = (cogl_angle_sin (x) + 1) * CLUTTER_ALPHA_MAX_ALPHA; + /* shift from range [-1, 0] -> [0, 1] */ + sine = sine + 1.0; - return ((guint32) sine) >> COGL_FIXED_Q; + return (guint32) (sine * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -998,18 +1158,17 @@ clutter_sine_out_func (ClutterAlpha *alpha, ClutterTimeline *timeline; gint frame; gint n_frames; - ClutterAngle x; - ClutterFixed sine; + float radians; + float sine; timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - x = 256 * frame / n_frames; + radians = ((float)frame / n_frames) * (G_PI / 2); + sine = sinf (radians); - sine = cogl_angle_sin (x) * CLUTTER_ALPHA_MAX_ALPHA; - - return ((guint32) sine) >> COGL_FIXED_Q; + return (guint32) (sine * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -1034,18 +1193,20 @@ clutter_sine_in_out_func (ClutterAlpha *alpha, ClutterTimeline *timeline; gint frame; gint n_frames; - ClutterAngle x; - ClutterFixed sine; + float radians; + float sine; timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - x = -256 * frame / n_frames + 256; + radians = ((float)frame / n_frames) * G_PI; + sine = sinf (radians - (G_PI / 2)); - sine = (cogl_angle_sin (x) + 1) / 2 * CLUTTER_ALPHA_MAX_ALPHA; + /* shift from range [-1, 1] -> [0, 1] */ + sine = (sine + 1.0) / 2.0; - return ((guint32) sine) >> COGL_FIXED_Q; + return (guint32) (sine * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -1113,32 +1274,25 @@ clutter_smoothstep_inc_func (ClutterAlpha *alpha, ClutterTimeline *timeline; gint frame; gint n_frames; - guint32 r; - guint32 x; + float r; + float x; /* * The smoothstep function uses f(x) = -2x^3 + 3x^2 where x is from <0,1>, - * and precission is critical -- we use 8.24 fixed format for this operation. - * The earlier operations involve division, which we cannot do in 8.24 for - * numbers in <0,1> we use ClutterFixed. + * and precission is critical. */ timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); n_frames = clutter_timeline_get_n_frames (timeline); - /* - * Convert x to 8.24 for next step. - */ - x = COGL_FIXED_FAST_DIV (frame, n_frames) << 8; + x = (float)frame / n_frames; /* * f(x) = -2x^3 + 3x^2 - * - * Convert result to ClutterFixed to avoid overflow in next step. */ - r = ((x >> 12) * (x >> 12) * 3 - (x >> 15) * (x >> 16) * (x >> 16)) >> 8; + r = -2 * x * x * x + 3 * x * x; - return COGL_FIXED_TO_INT (r * CLUTTER_ALPHA_MAX_ALPHA); + return (r * CLUTTER_ALPHA_MAX_ALPHA); } /** @@ -1204,9 +1358,9 @@ clutter_exp_inc_func (ClutterAlpha *alpha, * * (2^x_alpha_max) - 1 == CLUTTER_ALPHA_MAX_ALPHA */ -#if CLUTTER_ALPHA_MAX_ALPHA != 0xffff -#error Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA -#endif + /* XXX: If this fails: + * Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA */ + g_assert (CLUTTER_ALPHA_MAX_ALPHA == 65535.0); timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); @@ -1214,7 +1368,7 @@ clutter_exp_inc_func (ClutterAlpha *alpha, x = x_alpha_max * frame / n_frames; - result = CLAMP (cogl_fixed_pow2 (x) - 1, 0, CLUTTER_ALPHA_MAX_ALPHA); + result = CLAMP (powf (2, x) - 1, 0, CLUTTER_ALPHA_MAX_ALPHA); return result; } @@ -1255,9 +1409,9 @@ clutter_exp_dec_func (ClutterAlpha *alpha, * * (2^x_alpha_max) - 1 == CLUTTER_ALPHA_MAX_ALPHA */ -#if CLUTTER_ALPHA_MAX_ALPHA != 0xffff -#error Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA -#endif + /* XXX: If this fails: + * Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA */ + g_assert (CLUTTER_ALPHA_MAX_ALPHA == 65535.0); timeline = clutter_alpha_get_timeline (alpha); frame = clutter_timeline_get_current_frame (timeline); @@ -1265,7 +1419,7 @@ clutter_exp_dec_func (ClutterAlpha *alpha, x = (x_alpha_max * (n_frames - frame)) / n_frames; - result = CLAMP (cogl_fixed_pow2 (x) - 1, 0, CLUTTER_ALPHA_MAX_ALPHA); + result = CLAMP (powf (2, x) - 1, 0, CLUTTER_ALPHA_MAX_ALPHA); return result; } diff --git a/clutter/clutter-alpha.h b/clutter/clutter-alpha.h index eba9e3fb8..85f80547a 100644 --- a/clutter/clutter-alpha.h +++ b/clutter/clutter-alpha.h @@ -31,7 +31,6 @@ #ifndef __CLUTTER_ALPHA_H__ #define __CLUTTER_ALPHA_H__ -#include #include #include @@ -106,31 +105,35 @@ struct _ClutterAlphaClass * * Since: 0.2 */ -#define CLUTTER_ALPHA_MAX_ALPHA (0xffff) +#define CLUTTER_ALPHA_MAX_ALPHA (65535.0f) GType clutter_alpha_get_type (void) G_GNUC_CONST; -ClutterAlpha * clutter_alpha_new (void); -ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline, - ClutterAlphaFunc func, - gpointer data, - GDestroyNotify destroy); +ClutterAlpha * clutter_alpha_new (void); +ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline, + gulong mode); +ClutterAlpha * clutter_alpha_new_with_func (ClutterTimeline *timeline, + ClutterAlphaFunc func, + gpointer data, + GDestroyNotify destroy); -ClutterAlpha * clutter_alpha_new_for_mode (ClutterAnimationMode mode); +guint32 clutter_alpha_get_alpha (ClutterAlpha *alpha); +void clutter_alpha_set_func (ClutterAlpha *alpha, + ClutterAlphaFunc func, + gpointer data, + GDestroyNotify destroy); +void clutter_alpha_set_closure (ClutterAlpha *alpha, + GClosure *closure); +void clutter_alpha_set_timeline (ClutterAlpha *alpha, + ClutterTimeline *timeline); +ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha); +void clutter_alpha_set_mode (ClutterAlpha *alpha, + gulong mode); +gulong clutter_alpha_get_mode (ClutterAlpha *alpha); -guint32 clutter_alpha_get_alpha (ClutterAlpha *alpha); -void clutter_alpha_set_func (ClutterAlpha *alpha, - ClutterAlphaFunc func, - gpointer data, - GDestroyNotify destroy); -void clutter_alpha_set_closure (ClutterAlpha *alpha, - GClosure *closure); -void clutter_alpha_set_timeline (ClutterAlpha *alpha, - ClutterTimeline *timeline); -ClutterTimeline * clutter_alpha_get_timeline (ClutterAlpha *alpha); -void clutter_alpha_set_mode (ClutterAlpha *alpha, - ClutterAnimationMode mode); -ClutterAnimationMode clutter_alpha_get_mode (ClutterAlpha *alpha); +gulong clutter_alpha_register_func (ClutterAlphaFunc func, + gpointer data); +gulong clutter_alpha_register_closure (GClosure *closure); /* convenience functions */ guint32 clutter_ramp_inc_func (ClutterAlpha *alpha, diff --git a/clutter/clutter-animatable.c b/clutter/clutter-animatable.c new file mode 100644 index 000000000..fb2b88b19 --- /dev/null +++ b/clutter/clutter-animatable.c @@ -0,0 +1,117 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2009 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:clutter-animatable + * @short_description: Interface for animatable classes + * + * #ClutterAnimatable is an interface that allows a #GObject class + * to control how a #ClutterAnimation will animate a property. + * + * Each #ClutterAnimatable should implement the animate_property() + * virtual function of the interface to compute the animation state + * between two values of an interval depending on a progress factor, + * expressed as a floating point value. + * + * If a #ClutterAnimatable is animated by a #ClutterAnimation + * instance, the #ClutterAnimation will call + * clutter_animatable_animate_property() passing the name of the + * currently animated property; the initial and final values of + * the animation interval; the progress factor. The #ClutterAnimatable + * implementation should return the computed value for the animated + * property. + * + * #ClutterAnimatable is available since Clutter 1.0 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "clutter-animatable.h" +#include "clutter-debug.h" +#include "clutter-private.h" + +GType +clutter_animatable_get_type (void) +{ + static GType a_type = 0; + + if (G_UNLIKELY (a_type == 0)) + a_type = g_type_register_static_simple (G_TYPE_INTERFACE, + I_("ClutterAnimatable"), + sizeof (ClutterAnimatableIface), + NULL, 0, NULL, 0); + + return a_type; +} + +/** + * clutter_animatable_animate_property: + * @animatable: a #ClutterAnimatable + * @animation: a #ClutterAnimation + * @property_name: the name of the animated property + * @initial_value: the initial value of the animation interval + * @final_value: the final value of the animation interval + * @progress: the progress factor + * @value: return location for the animation value + * + * Calls the animate_property() virtual function for @animatable. + * + * The @initial_value and @final_value #GValues must contain + * the same type; @value must have been initialized to the same + * type of @initial_value and @final_value. + * + * All implementation of the #ClutterAnimatable interface must + * implement this function. + * + * Since: 1.0 + */ +void +clutter_animatable_animate_property (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value) +{ + g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); + g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); + g_return_if_fail (property_name != NULL); + g_return_if_fail (initial_value != NULL && final_value != NULL); + g_return_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID); + g_return_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID); + g_return_if_fail (value != NULL); + g_return_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) && + G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value)); + + CLUTTER_ANIMATABLE_GET_IFACE (animatable)->animate_property (animatable, + animation, + property_name, + initial_value, + final_value, + progress, + value); +} diff --git a/clutter/clutter-animatable.h b/clutter/clutter-animatable.h new file mode 100644 index 000000000..aee717ac4 --- /dev/null +++ b/clutter/clutter-animatable.h @@ -0,0 +1,80 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2009 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __CLUTTER_ANIMATABLE_H__ +#define __CLUTTER_ANIMATABLE_H__ + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) +#define CLUTTER_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatable)) +#define CLUTTER_IS_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATABLE)) +#define CLUTTER_ANIMATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatableIface)) + +typedef struct _ClutterAnimatable ClutterAnimatable; /* dummy typedef */ +typedef struct _ClutterAnimatableIface ClutterAnimatableIface; + +/** + * ClutterAnimatableIface: + * @animate_property: virtual function for animating a property + * + * Base interface for #GObjects that can be animated by a + * a #ClutterAnimation. + * + * Since: 1.0 + */ +struct _ClutterAnimatableIface +{ + /*< private >*/ + GTypeInterface parent_iface; + + /*< public >*/ + void (* animate_property) (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value); +}; + +GType clutter_animatable_get_type (void) G_GNUC_CONST; + +void clutter_animatable_animate_property (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value); + +G_END_DECLS + +#endif /* __CLUTTER_ANIMATABLE_H__ */ diff --git a/clutter/clutter-animation.c b/clutter/clutter-animation.c index eae81250d..5994ff38e 100644 --- a/clutter/clutter-animation.c +++ b/clutter/clutter-animation.c @@ -27,12 +27,12 @@ * @short_description: Simple implicit animations * * #ClutterAnimation is an object providing simple, implicit animations - * for #ClutterActors. + * for #GObjects. * * #ClutterAnimation instances will bind a #GObject property belonging - * to a #ClutterActor to a #ClutterInterval, and will then use a - * #ClutterTimeline to interpolate the property between the initial - * and final values of the interval. + * to a #GObject to a #ClutterInterval, and will then use a #ClutterTimeline + * to interpolate the property between the initial and final values of the + * interval. * * For convenience, it is possible to use the clutter_actor_animate() * function call which will take care of setting up and tearing down @@ -50,6 +50,7 @@ #include #include "clutter-alpha.h" +#include "clutter-animatable.h" #include "clutter-animation.h" #include "clutter-debug.h" #include "clutter-enum-types.h" @@ -60,7 +61,7 @@ enum { PROP_0, - PROP_ACTOR, + PROP_OBJECT, PROP_MODE, PROP_DURATION, PROP_LOOP, @@ -79,11 +80,11 @@ enum struct _ClutterAnimationPrivate { - ClutterActor *actor; + GObject *object; GHashTable *properties; - ClutterAnimationMode mode; + gulong mode; guint loop : 1; guint duration; @@ -96,7 +97,7 @@ struct _ClutterAnimationPrivate static guint animation_signals[LAST_SIGNAL] = { 0, }; -static GQuark quark_actor_animation = 0; +static GQuark quark_object_animation = 0; G_DEFINE_TYPE (ClutterAnimation, clutter_animation, G_TYPE_INITIALLY_UNOWNED); @@ -118,16 +119,14 @@ clutter_animation_dispose (GObject *gobject) { ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv; - if (priv->actor) + if (priv->object) { g_object_weak_unref (G_OBJECT (gobject), on_animation_weak_notify, - priv->actor); - g_object_set_qdata (G_OBJECT (priv->actor), - quark_actor_animation, - NULL); - g_object_unref (priv->actor); - priv->actor = NULL; + priv->object); + g_object_set_qdata (priv->object, quark_object_animation, NULL); + g_object_unref (priv->object); + priv->object = NULL; } if (priv->timeline) @@ -168,12 +167,12 @@ clutter_animation_set_property (GObject *gobject, switch (prop_id) { - case PROP_ACTOR: - clutter_animation_set_actor (animation, g_value_get_object (value)); + case PROP_OBJECT: + clutter_animation_set_object (animation, g_value_get_object (value)); break; case PROP_MODE: - clutter_animation_set_mode (animation, g_value_get_enum (value)); + clutter_animation_set_mode (animation, g_value_get_ulong (value)); break; case PROP_DURATION: @@ -208,12 +207,12 @@ clutter_animation_get_property (GObject *gobject, switch (prop_id) { - case PROP_ACTOR: - g_value_set_object (value, priv->actor); + case PROP_OBJECT: + g_value_set_object (value, priv->object); break; case PROP_MODE: - g_value_set_enum (value, priv->mode); + g_value_set_ulong (value, priv->mode); break; case PROP_DURATION: @@ -253,7 +252,7 @@ clutter_animation_class_init (ClutterAnimationClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - quark_actor_animation = + quark_object_animation = g_quark_from_static_string ("clutter-actor-animation"); g_type_class_add_private (klass, sizeof (ClutterAnimationPrivate)); @@ -266,32 +265,34 @@ clutter_animation_class_init (ClutterAnimationClass *klass) gobject_class->finalize = clutter_animation_finalize; /** - * ClutterAnimation:actor: + * ClutterAnimation:objct: * - * The actor to which the animation applies. + * The #GObject to which the animation applies. * * Since: 1.0 */ - pspec = g_param_spec_object ("actor", - "Actor", - "Actor to which the animation applies", - CLUTTER_TYPE_ACTOR, + pspec = g_param_spec_object ("object", + "Object", + "Object to which the animation applies", + G_TYPE_OBJECT, CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_ACTOR, pspec); + g_object_class_install_property (gobject_class, PROP_OBJECT, pspec); /** * ClutterAnimation:mode: * - * The animation mode. + * The animation mode, either a value from #ClutterAnimationMode + * or a value returned by clutter_alpha_register_func(). The + * default value is %CLUTTER_LINEAR. * * Since: 1.0 */ - pspec = g_param_spec_enum ("mode", - "Mode", - "The mode of the animation", - CLUTTER_TYPE_ANIMATION_MODE, - CLUTTER_LINEAR, - CLUTTER_PARAM_READWRITE); + pspec = g_param_spec_ulong ("mode", + "Mode", + "The mode of the animation", + 0, G_MAXULONG, + CLUTTER_LINEAR, + CLUTTER_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_MODE, pspec); /** @@ -427,7 +428,7 @@ clutter_animation_update_property_internal (ClutterAnimation *animation, * @property_name: the property to control * @interval: a #ClutterInterval * - * Binds @interval to the @property_name of the #ClutterActor + * Binds @interval to the @property_name of the #GObject * attached to @animation. The #ClutterAnimation will take * ownership of the passed #ClutterInterval. * @@ -451,10 +452,10 @@ clutter_animation_bind_property (ClutterAnimation *animation, priv = animation->priv; - if (G_UNLIKELY (!priv->actor)) + if (G_UNLIKELY (!priv->object)) { g_warning ("Cannot bind property `%s': the animation has no " - "actor set. You need to call clutter_animation_set_actor() " + "object set. You need to call clutter_animation_set_object() " "first to be able to bind a property", property_name); return; @@ -468,14 +469,14 @@ clutter_animation_bind_property (ClutterAnimation *animation, return; } - klass = G_OBJECT_GET_CLASS (priv->actor); + klass = G_OBJECT_GET_CLASS (priv->object); pspec = g_object_class_find_property (klass, property_name); if (!pspec) { - g_warning ("Cannot bind property `%s': actors of type `%s' have " + g_warning ("Cannot bind property `%s': objects of type `%s' have " "no such property", property_name, - g_type_name (G_OBJECT_TYPE (priv->actor))); + g_type_name (G_OBJECT_TYPE (priv->object))); return; } @@ -592,14 +593,14 @@ clutter_animation_update_property (ClutterAnimation *animation, return; } - klass = G_OBJECT_GET_CLASS (priv->actor); + klass = G_OBJECT_GET_CLASS (priv->object); pspec = g_object_class_find_property (klass, property_name); if (!pspec) { - g_warning ("Cannot bind property `%s': actors of type `%s' have " + g_warning ("Cannot bind property `%s': objects of type `%s' have " "no such property", property_name, - g_type_name (G_OBJECT_TYPE (priv->actor))); + g_type_name (G_OBJECT_TYPE (priv->object))); return; } @@ -664,10 +665,18 @@ on_alpha_notify (GObject *gobject, ClutterAnimationPrivate *priv = animation->priv; GList *properties, *p; guint32 alpha_value; + gboolean is_animatable = FALSE; + ClutterAnimatable *animatable = NULL; alpha_value = clutter_alpha_get_alpha (CLUTTER_ALPHA (gobject)); - g_object_freeze_notify (G_OBJECT (priv->actor)); + if (CLUTTER_IS_ANIMATABLE (priv->object)) + { + animatable = CLUTTER_ANIMATABLE (priv->object); + is_animatable = TRUE; + } + + g_object_freeze_notify (priv->object); properties = g_hash_table_get_keys (priv->properties); for (p = properties; p != NULL; p = p->next) @@ -683,16 +692,37 @@ on_alpha_notify (GObject *gobject, g_value_init (&value, clutter_interval_get_value_type (interval)); factor = (gdouble) alpha_value / CLUTTER_ALPHA_MAX_ALPHA; - clutter_interval_compute_value (interval, factor, &value); - g_object_set_property (G_OBJECT (priv->actor), p_name, &value); + if (is_animatable) + { + const GValue *initial, *final; + + initial = clutter_interval_peek_initial_value (interval); + final = clutter_interval_peek_final_value (interval); + + CLUTTER_NOTE (ANIMATION, "Animatable property `%s'", p_name); + clutter_animatable_animate_property (animatable, animation, + p_name, + initial, final, + factor, + &value); + + g_object_set_property (priv->object, p_name, &value); + } + else + { + CLUTTER_NOTE (ANIMATION, "Standard property `%s'", p_name); + + if (clutter_interval_compute_value (interval, factor, &value)) + g_object_set_property (priv->object, p_name, &value); + } g_value_unset (&value); } g_list_free (properties); - g_object_thaw_notify (G_OBJECT (priv->actor)); + g_object_thaw_notify (priv->object); } /* @@ -709,7 +739,7 @@ on_animation_weak_notify (gpointer data, clutter_actor_get_gid (CLUTTER_ACTOR (actor)), actor); - g_object_set_qdata (actor, quark_actor_animation, NULL); + g_object_set_qdata (actor, quark_object_animation, NULL); } ClutterAnimation * @@ -719,66 +749,64 @@ clutter_animation_new (void) } /** - * clutter_animation_set_actor: + * clutter_animation_set_object: * @animation: a #ClutterAnimation - * @actor: a #ClutterActor + * @object: a #GObject * - * Attaches @animation to @actor. The #ClutterAnimation will take a - * reference on @actor. + * Attaches @animation to @object. The #ClutterAnimation will take a + * reference on @object. * * Since: 1.0 */ void -clutter_animation_set_actor (ClutterAnimation *animation, - ClutterActor *actor) +clutter_animation_set_object (ClutterAnimation *animation, + GObject *object) { ClutterAnimationPrivate *priv; g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + g_return_if_fail (G_IS_OBJECT (object)); priv = animation->priv; - g_object_ref (actor); + g_object_ref (object); - if (priv->actor) + if (priv->object) { g_object_weak_unref (G_OBJECT (animation), on_animation_weak_notify, - priv->actor); - g_object_set_qdata (G_OBJECT (priv->actor), - quark_actor_animation, - NULL); - g_object_unref (priv->actor); + priv->object); + g_object_set_qdata (priv->object, quark_object_animation, NULL); + g_object_unref (priv->object); } - priv->actor = actor; + priv->object = object; g_object_weak_ref (G_OBJECT (animation), on_animation_weak_notify, - priv->actor); - g_object_set_qdata (G_OBJECT (priv->actor), - quark_actor_animation, + priv->object); + g_object_set_qdata (G_OBJECT (priv->object), + quark_object_animation, animation); - g_object_notify (G_OBJECT (animation), "actor"); + g_object_notify (G_OBJECT (animation), "object"); } /** - * clutter_animation_get_actor: + * clutter_animation_get_object: * @animation: a #ClutterAnimation * - * Retrieves the #ClutterActor attached to @animation. + * Retrieves the #GObject attached to @animation. * - * Return value: a #ClutterActor + * Return value: a #GObject * * Since: 1.0 */ -ClutterActor * -clutter_animation_get_actor (ClutterAnimation *animation) +GObject * +clutter_animation_get_object (ClutterAnimation *animation) { g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - return animation->priv->actor; + return animation->priv->object; } static inline void @@ -794,15 +822,17 @@ clutter_animation_set_mode_internal (ClutterAnimation *animation, /** * clutter_animation_set_mode: * @animation: a #ClutterAnimation - * @mode: a #ClutterAnimationMode + * @mode: an animation mode logical id * - * Sets the animation @mode of @animation. + * Sets the animation @mode of @animation. The animation @mode is + * a logical id, either coming from the #ClutterAnimationMode enumeration + * or the return value of clutter_alpha_register_func(). * * Since: 1.0 */ void -clutter_animation_set_mode (ClutterAnimation *animation, - ClutterAnimationMode mode) +clutter_animation_set_mode (ClutterAnimation *animation, + gulong mode) { ClutterAnimationPrivate *priv; @@ -820,13 +850,14 @@ clutter_animation_set_mode (ClutterAnimation *animation, * clutter_animation_get_mode: * @animation: a #ClutterAnimation * - * Retrieves the animation mode of @animation. + * Retrieves the animation mode of @animation, as set by + * clutter_animation_set_mode(). * - * Return value: the #ClutterAnimationMode for the animation + * Return value: the mode for the animation * * Since: 1.0 */ -ClutterAnimationMode +gulong clutter_animation_get_mode (ClutterAnimation *animation) { g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), CLUTTER_LINEAR); @@ -1125,7 +1156,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, GObjectClass *klass; const gchar *property_name; - klass = G_OBJECT_GET_CLASS (priv->actor); + klass = G_OBJECT_GET_CLASS (priv->object); property_name = first_property_name; while (property_name != NULL) @@ -1145,10 +1176,10 @@ clutter_animation_setup_valist (ClutterAnimation *animation, pspec = g_object_class_find_property (klass, property_name); if (!pspec) { - g_warning ("Cannot bind property `%s': actors of type `%s' do " + g_warning ("Cannot bind property `%s': objects of type `%s' do " "not have this property", property_name, - g_type_name (G_OBJECT_TYPE (priv->actor))); + g_type_name (G_OBJECT_TYPE (priv->object))); break; } @@ -1178,9 +1209,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, GValue initial = { 0, }; g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property (G_OBJECT (priv->actor), - property_name, - &initial); + g_object_get_property (priv->object, property_name, &initial); interval = clutter_interval_new_with_values (G_PARAM_SPEC_VALUE_TYPE (pspec), @@ -1199,7 +1228,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, g_value_unset (&initial); } else - g_object_set_property (G_OBJECT (priv->actor), property_name, &final); + g_object_set_property (priv->object, property_name, &final); g_value_unset (&final); @@ -1254,7 +1283,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor, return NULL; } - animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation); + animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); if (G_LIKELY (!animation)) { animation = clutter_animation_new (); @@ -1265,7 +1294,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor, clutter_animation_set_timeline (animation, timeline); clutter_animation_set_alpha (animation, alpha); - clutter_animation_set_actor (animation, actor); + clutter_animation_set_object (animation, G_OBJECT (actor)); va_start (args, first_property_name); clutter_animation_setup_valist (animation, first_property_name, args); @@ -1277,7 +1306,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor, /** * clutter_actor_animate_with_timeline: * @actor: a #ClutterActor - * @mode: a #ClutterAnimationMode value + * @mode: an animation mode logical id * @timeline: a #ClutterTimeline * @first_property_name: the name of a property * @VarArgs: a %NULL terminated list of property names and @@ -1298,10 +1327,10 @@ clutter_actor_animate_with_alpha (ClutterActor *actor, * Since: 1.0 */ ClutterAnimation * -clutter_actor_animate_with_timeline (ClutterActor *actor, - ClutterAnimationMode mode, - ClutterTimeline *timeline, - const gchar *first_property_name, +clutter_actor_animate_with_timeline (ClutterActor *actor, + gulong mode, + ClutterTimeline *timeline, + const gchar *first_property_name, ...) { ClutterAnimation *animation; @@ -1311,7 +1340,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); g_return_val_if_fail (first_property_name != NULL, NULL); - animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation); + animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); if (G_LIKELY (!animation)) { animation = clutter_animation_new (); @@ -1323,7 +1352,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, clutter_animation_set_timeline (animation, timeline); clutter_animation_set_alpha (animation, NULL); clutter_animation_set_mode (animation, mode); - clutter_animation_set_actor (animation, actor); + clutter_animation_set_object (animation, G_OBJECT (actor)); va_start (args, first_property_name); clutter_animation_setup_valist (animation, first_property_name, args); @@ -1335,7 +1364,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, /** * clutter_actor_animate: * @actor: a #ClutterActor - * @mode: a #ClutterAnimationMode value + * @mode: an animation mode logical id * @duration: duration of the animation, in milliseconds * @first_property_name: the name of a property * @VarArgs: a %NULL terminated list of property names and @@ -1357,6 +1386,9 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, * will make width and height properties of the #ClutterActor "rectangle" * grow linearly between the current value and 100 pixels, in 250 milliseconds. * + * The animation @mode is a logical id, either from the #ClutterAnimationMode + * enumeration of from clutter_alpha_register_func(). + * * All the properties specified will be animated between the current value * and the final value. If a property should be set at the beginning of * the animation but not updated during the animation, it should be prefixed @@ -1392,10 +1424,10 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, * Since: 1.0 */ ClutterAnimation * -clutter_actor_animate (ClutterActor *actor, - ClutterAnimationMode mode, - guint duration, - const gchar *first_property_name, +clutter_actor_animate (ClutterActor *actor, + gulong mode, + guint duration, + const gchar *first_property_name, ...) { ClutterAnimation *animation; @@ -1406,7 +1438,7 @@ clutter_actor_animate (ClutterActor *actor, g_return_val_if_fail (duration > 0, NULL); g_return_val_if_fail (first_property_name != NULL, NULL); - animation = g_object_get_qdata (G_OBJECT (actor), quark_actor_animation); + animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); if (G_LIKELY (!animation)) { /* if there is no animation already attached to the actor, @@ -1416,7 +1448,7 @@ clutter_actor_animate (ClutterActor *actor, animation = clutter_animation_new (); clutter_animation_set_timeline (animation, NULL); clutter_animation_set_alpha (animation, NULL); - clutter_animation_set_actor (animation, actor); + clutter_animation_set_object (animation, G_OBJECT (actor)); CLUTTER_NOTE (ANIMATION, "Created new Animation [%p]", animation); } diff --git a/clutter/clutter-animation.h b/clutter/clutter-animation.h index 115e0a0b5..1b7e42656 100644 --- a/clutter/clutter-animation.h +++ b/clutter/clutter-animation.h @@ -97,12 +97,12 @@ GType clutter_animation_get_type (void) G_GNUC_CONST; ClutterAnimation * clutter_animation_new (void); -void clutter_animation_set_actor (ClutterAnimation *animation, - ClutterActor *actor); -ClutterActor * clutter_animation_get_actor (ClutterAnimation *animation); +void clutter_animation_set_object (ClutterAnimation *animation, + GObject *object); +GObject * clutter_animation_get_object (ClutterAnimation *animation); void clutter_animation_set_mode (ClutterAnimation *animation, - ClutterAnimationMode mode); -ClutterAnimationMode clutter_animation_get_mode (ClutterAnimation *animation); + gulong mode); +gulong clutter_animation_get_mode (ClutterAnimation *animation); void clutter_animation_set_duration (ClutterAnimation *animation, gint msecs); guint clutter_animation_get_duration (ClutterAnimation *animation); @@ -130,12 +130,12 @@ ClutterInterval *clutter_animation_get_interval (ClutterAnimation *an const gchar *property_name); ClutterAnimation * clutter_actor_animate (ClutterActor *actor, - ClutterAnimationMode mode, + gulong mode, guint duration, const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED; ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor, - ClutterAnimationMode mode, + gulong mode, ClutterTimeline *timeline, const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED; diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index efeeac185..da8f77ee6 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -60,7 +60,8 @@ struct _ClutterBackendPrivate guint double_click_time; guint double_click_distance; - ClutterFixed resolution; + gdouble resolution; + gdouble units_per_em; cairo_font_options_t *font_options; @@ -87,7 +88,9 @@ clutter_backend_dispose (GObject *gobject) if (clutter_context && clutter_context->events_queue) { - g_queue_foreach (clutter_context->events_queue, (GFunc) clutter_event_free, NULL); + g_queue_foreach (clutter_context->events_queue, + (GFunc) clutter_event_free, + NULL); g_queue_free (clutter_context->events_queue); clutter_context->events_queue = NULL; } @@ -99,6 +102,57 @@ clutter_backend_dispose (GObject *gobject) G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); } +static inline void +update_units_per_em (ClutterBackend *backend) +{ + ClutterBackendPrivate *priv = backend->priv; + const gchar *font_name; + gdouble dpi; + + font_name = clutter_backend_get_font_name (backend); + dpi = clutter_backend_get_resolution (backend); + + if (G_LIKELY (font_name != NULL && *font_name != '\0')) + { + PangoFontDescription *font_desc; + gdouble font_size = 0; + + font_desc = pango_font_description_from_string (font_name); + if (G_LIKELY (font_desc != NULL)) + { + gint pango_size; + gboolean is_absolute; + + pango_size = pango_font_description_get_size (font_desc); + is_absolute = + pango_font_description_get_size_is_absolute (font_desc); + if (!is_absolute) + font_size = ((gdouble) font_size) / PANGO_SCALE; + + pango_font_description_free (font_desc); + } + + /* 10 points at 96 DPI is 12 pixels */ + priv->units_per_em = 1.2 * font_size + * dpi + / 96.0; + } + else + priv->units_per_em = -1.0; +} + +static void +clutter_backend_real_resolution_changed (ClutterBackend *backend) +{ + update_units_per_em (backend); +} + +static void +clutter_backend_real_font_changed (ClutterBackend *backend) +{ + update_units_per_em (backend); +} + static void clutter_backend_class_init (ClutterBackendClass *klass) { @@ -111,7 +165,7 @@ clutter_backend_class_init (ClutterBackendClass *klass) backend_signals[RESOLUTION_CHANGED] = g_signal_new (I_("resolution-changed"), G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed), NULL, NULL, clutter_marshal_VOID__VOID, @@ -120,11 +174,14 @@ clutter_backend_class_init (ClutterBackendClass *klass) backend_signals[FONT_CHANGED] = g_signal_new (I_("font-changed"), G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterBackendClass, font_changed), NULL, NULL, clutter_marshal_VOID__VOID, G_TYPE_NONE, 0); + + klass->resolution_changed = clutter_backend_real_resolution_changed; + klass->font_changed = clutter_backend_real_font_changed; } static void @@ -132,8 +189,10 @@ clutter_backend_init (ClutterBackend *backend) { ClutterBackendPrivate *priv; - priv = backend->priv = CLUTTER_BACKEND_GET_PRIVATE(backend); + priv = backend->priv = CLUTTER_BACKEND_GET_PRIVATE (backend); + priv->resolution = -1.0; + priv->units_per_em = -1.0; } void @@ -289,15 +348,30 @@ _clutter_backend_init_events (ClutterBackend *backend) klass->init_events (backend); } +ClutterUnit +_clutter_backend_get_units_per_em (ClutterBackend *backend) +{ + ClutterBackendPrivate *priv; + + g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), 0); + + priv = backend->priv; + + if (G_UNLIKELY (priv->units_per_em < 0)) + update_units_per_em (backend); + + return priv->units_per_em; +} /** * clutter_get_default_backend: * - * FIXME + * Retrieves the default #ClutterBackend used by Clutter. The + * #ClutterBackend holds backend-specific configuration options. * * Return value: the default backend. You should not ref or - * unref the returned object. Applications should not rarely need - * to use this. + * unref the returned object. Applications should rarely need + * to use this. * * Since: 0.4 */ @@ -406,19 +480,16 @@ void clutter_backend_set_resolution (ClutterBackend *backend, gdouble dpi) { - ClutterFixed fixed_dpi; ClutterBackendPrivate *priv; g_return_if_fail (CLUTTER_IS_BACKEND (backend)); + priv = backend->priv; + if (dpi < 0) dpi = -1.0; - priv = backend->priv; - - fixed_dpi = COGL_FIXED_FROM_FLOAT (dpi); - if (priv->resolution != fixed_dpi) - priv->resolution = fixed_dpi; + priv->resolution = dpi; if (CLUTTER_CONTEXT ()->font_map) cogl_pango_font_map_set_resolution (CLUTTER_CONTEXT ()->font_map, dpi); @@ -443,7 +514,7 @@ clutter_backend_get_resolution (ClutterBackend *backend) { g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), -1.0); - return COGL_FIXED_TO_FLOAT (backend->priv->resolution); + return backend->priv->resolution; } /** diff --git a/clutter/clutter-behaviour-depth.c b/clutter/clutter-behaviour-depth.c index 90fc456af..0749b8e4d 100644 --- a/clutter/clutter-behaviour-depth.c +++ b/clutter/clutter-behaviour-depth.c @@ -83,9 +83,9 @@ clutter_behaviour_depth_alpha_notify (ClutterBehaviour *behaviour, priv = CLUTTER_BEHAVIOUR_DEPTH (behaviour)->priv; /* Need to create factor as to avoid borking signedness */ - factor = COGL_FIXED_FROM_INT (alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; + factor = (float)(alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; depth = priv->depth_start - + COGL_FIXED_TO_INT (factor * (priv->depth_end - priv->depth_start)); + + (factor * (priv->depth_end - priv->depth_start)); CLUTTER_NOTE (BEHAVIOUR, "alpha: %d, depth: %d", alpha_value, depth); diff --git a/clutter/clutter-behaviour-ellipse.c b/clutter/clutter-behaviour-ellipse.c index a5d4bff35..0bd8c86fe 100644 --- a/clutter/clutter-behaviour-ellipse.c +++ b/clutter/clutter-behaviour-ellipse.c @@ -86,11 +86,11 @@ struct _ClutterBehaviourEllipsePrivate gint a; gint b; - ClutterAngle angle_start; - ClutterAngle angle_end; - ClutterAngle angle_tilt_x; - ClutterAngle angle_tilt_y; - ClutterAngle angle_tilt_z; + float angle_start; + float angle_end; + float angle_tilt_x; + float angle_tilt_y; + float angle_tilt_z; ClutterRotateDirection direction; }; @@ -104,14 +104,14 @@ typedef struct _knot3d static void clutter_behaviour_ellipse_advance (ClutterBehaviourEllipse *e, - ClutterAngle angle, + float angle, knot3d *knot) { ClutterBehaviourEllipsePrivate *priv = e->priv; gint x, y, z; - x = COGL_FIXED_TO_INT (priv->a * cogl_angle_cos (angle)); - y = COGL_FIXED_TO_INT (priv->b * cogl_angle_sin (angle)); + x = (priv->a * cosf (angle * (G_PI/180.0))); + y = (priv->b * sinf (angle * (G_PI/180.0))); z = 0; if (priv->angle_tilt_z) @@ -126,47 +126,47 @@ clutter_behaviour_ellipse_advance (ClutterBehaviourEllipse *e, */ ClutterFixed x2, y2; - x2 = x * cogl_angle_cos (priv->angle_tilt_z) - - y * cogl_angle_sin (priv->angle_tilt_z); + x2 = x * cosf (priv->angle_tilt_z * (G_PI/180.0)) + - y * sinf (priv->angle_tilt_z * (G_PI/180.0)); - y2 = y * cogl_angle_cos (priv->angle_tilt_z) - + x * cogl_angle_sin (priv->angle_tilt_z); + y2 = y * cosf (priv->angle_tilt_z * (G_PI/180.0)) + + x * sinf (priv->angle_tilt_z * (G_PI/180.0)); - x = COGL_FIXED_TO_INT (x2); - y = COGL_FIXED_TO_INT (y2); + x = (x2); + y = (y2); } if (priv->angle_tilt_x) { ClutterFixed z2, y2; - z2 = - y * cogl_angle_sin (priv->angle_tilt_x); + z2 = - y * sinf (priv->angle_tilt_x * (G_PI/180.0)); - y2 = y * cogl_angle_cos (priv->angle_tilt_x); + y2 = y * cosf (priv->angle_tilt_x * (G_PI/180.0)); - z = COGL_FIXED_TO_INT (z2); - y = COGL_FIXED_TO_INT (y2); + z = (z2); + y = (y2); } if (priv->angle_tilt_y) { ClutterFixed x2, z2; - x2 = x * cogl_angle_cos (priv->angle_tilt_y) - - z * cogl_angle_sin (priv->angle_tilt_y); + x2 = x * cosf (priv->angle_tilt_y * (G_PI/180.0)) + - z * sinf (priv->angle_tilt_y * (G_PI/180.0)); - z2 = z * cogl_angle_cos (priv->angle_tilt_y) - + x * cogl_angle_sin (priv->angle_tilt_y); + z2 = z * cosf (priv->angle_tilt_y * (G_PI/180.0)) + + x * sinf (priv->angle_tilt_y * (G_PI/180.0)); - x = COGL_FIXED_TO_INT (x2); - z = COGL_FIXED_TO_INT (z2); + x = (x2); + z = (z2); } knot->x = x; knot->y = y; knot->z = z; - CLUTTER_NOTE (BEHAVIOUR, "advancing to angle %d [%d, %d] (a: %d, b: %d)", + CLUTTER_NOTE (BEHAVIOUR, "advancing to angle %.2f [%d, %d] (a: %d, b: %d)", angle, knot->x, knot->y, priv->a, priv->b); @@ -187,20 +187,16 @@ actor_apply_knot_foreach (ClutterBehaviour *behave, clutter_actor_set_depth (actor, knot->z); } -static inline ClutterAngle -clamp_angle (ClutterAngle a) +static inline float +clamp_angle (float a) { - ClutterAngle a1, a2; gint rounds; - /* Need to add the 256 offset here, since the user space 0 maps to our - * -256 - */ - rounds = (a + 256) / 1024; - a1 = rounds * 1024; - a2 = a - a1; + rounds = a / 360; + if (a < 0) + rounds--; - return a2; + return a - 360 * rounds; } static void @@ -209,20 +205,20 @@ clutter_behaviour_ellipse_alpha_notify (ClutterBehaviour *behave, { ClutterBehaviourEllipse *self = CLUTTER_BEHAVIOUR_ELLIPSE (behave); ClutterBehaviourEllipsePrivate *priv = self->priv; - ClutterAngle start, end; + float start, end; knot3d knot; - ClutterAngle angle = 0; + float angle = 0; start = priv->angle_start; end = priv->angle_end; if (priv->direction == CLUTTER_ROTATE_CW && start >= end) { - end += 1024; + end += 360; } else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end) { - end -= 1024; + end -= 360; } angle = (end - start) * alpha / CLUTTER_ALPHA_MAX_ALPHA + start; @@ -247,30 +243,25 @@ clutter_behaviour_ellipse_set_property (GObject *gobject, switch (prop_id) { case PROP_ANGLE_START: - priv->angle_start = - COGL_ANGLE_FROM_DEG (g_value_get_double (value)) - 256; + priv->angle_start = g_value_get_double (value); break; case PROP_ANGLE_END: - priv->angle_end = - COGL_ANGLE_FROM_DEG (g_value_get_double (value)) - 256; + priv->angle_end = g_value_get_double (value); break; case PROP_ANGLE_TILT_X: - priv->angle_tilt_x = - COGL_ANGLE_FROM_DEG (g_value_get_double (value)); + priv->angle_tilt_x = g_value_get_double (value); break; case PROP_ANGLE_TILT_Y: - priv->angle_tilt_y = - COGL_ANGLE_FROM_DEG (g_value_get_double (value)); + priv->angle_tilt_y = g_value_get_double (value); break; case PROP_ANGLE_TILT_Z: - priv->angle_tilt_z = - COGL_ANGLE_FROM_DEG (g_value_get_double (value)); + priv->angle_tilt_z = g_value_get_double (value); break; case PROP_WIDTH: - priv->a = g_value_get_int (value) >> 1; + priv->a = g_value_get_int (value) / 2; break; case PROP_HEIGHT: - priv->b = g_value_get_int (value) >> 1; + priv->b = g_value_get_int (value) / 2; break; case PROP_CENTER: { @@ -301,30 +292,25 @@ clutter_behaviour_ellipse_get_property (GObject *gobject, switch (prop_id) { case PROP_ANGLE_START: - g_value_set_double (value, - COGL_ANGLE_TO_DEG (priv->angle_start + 256)); + g_value_set_double (value, priv->angle_start); break; case PROP_ANGLE_END: - g_value_set_double (value, - COGL_ANGLE_TO_DEG (priv->angle_end + 256)); + g_value_set_double (value, priv->angle_end); break; case PROP_ANGLE_TILT_X: - g_value_set_double (value, - COGL_ANGLE_TO_DEG (priv->angle_tilt_x)); + g_value_set_double (value, priv->angle_tilt_x); break; case PROP_ANGLE_TILT_Y: - g_value_set_double (value, - COGL_ANGLE_TO_DEG (priv->angle_tilt_y)); + g_value_set_double (value, priv->angle_tilt_y); break; case PROP_ANGLE_TILT_Z: - g_value_set_double (value, - COGL_ANGLE_TO_DEG (priv->angle_tilt_z)); + g_value_set_double (value, priv->angle_tilt_z); break; case PROP_WIDTH: - g_value_set_int (value, (priv->a << 1)); + g_value_set_int (value, (priv->a * 2)); break; case PROP_HEIGHT: - g_value_set_int (value, (priv->b << 1)); + g_value_set_int (value, (priv->b * 2)); break; case PROP_CENTER: g_value_set_boxed (value, &priv->center); @@ -513,12 +499,8 @@ clutter_behaviour_ellipse_init (ClutterBehaviourEllipse * self) priv->direction = CLUTTER_ROTATE_CW; - /* The inital values have to reflect the 90 degree offset between the normal - * mathematical space and the clutter clock-based space; the default end - * value of 360 is clamped to 0. - */ - priv->angle_start = -256; - priv->angle_end = -256; + priv->angle_start = 0; + priv->angle_end = 0; } /** @@ -611,8 +593,8 @@ clutter_behaviour_ellipse_newx (ClutterAlpha * alpha, "width", width, "height", height, "direction", direction, - "angle-start", COGL_ANGLE_FROM_DEGX (start), - "angle-end", COGL_ANGLE_FROM_DEGX (end), + "angle-start", (double)CLUTTER_FIXED_TO_FLOAT (start), + "angle-end", (double)CLUTTER_FIXED_TO_FLOAT (end), NULL); } @@ -695,9 +677,9 @@ clutter_behaviour_ellipse_set_width (ClutterBehaviourEllipse * self, priv = self->priv; - if (priv->a != width >> 1) + if (priv->a != width / 2) { - priv->a = width >> 1; + priv->a = width / 2; g_object_notify (G_OBJECT (self), "width"); } @@ -718,7 +700,7 @@ clutter_behaviour_ellipse_get_width (ClutterBehaviourEllipse *self) { g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0); - return self->priv->a << 1; + return self->priv->a * 2; } /** @@ -740,9 +722,9 @@ clutter_behaviour_ellipse_set_height (ClutterBehaviourEllipse *self, priv = self->priv; - if (priv->b != height >> 1) + if (priv->b != height / 2) { - priv->b = height >> 1; + priv->b = height / 2; g_object_notify (G_OBJECT (self), "height"); } @@ -763,7 +745,7 @@ clutter_behaviour_ellipse_get_height (ClutterBehaviourEllipse *self) { g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0); - return self->priv->b << 1; + return self->priv->b * 2; } /** @@ -780,10 +762,11 @@ void clutter_behaviour_ellipse_set_angle_start (ClutterBehaviourEllipse *self, gdouble angle_start) { + ClutterFixed new_angle = CLUTTER_FLOAT_TO_FIXED (angle_start); + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - clutter_behaviour_ellipse_set_angle_startx (self, - COGL_FIXED_FROM_FLOAT (angle_start)); + clutter_behaviour_ellipse_set_angle_startx (self, new_angle); } /** @@ -802,10 +785,10 @@ clutter_behaviour_ellipse_set_angle_startx (ClutterBehaviourEllipse *self, ClutterFixed angle_start) { ClutterBehaviourEllipsePrivate *priv; - ClutterAngle new_angle; + float new_angle; g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - new_angle = clamp_angle (COGL_ANGLE_FROM_DEGX (angle_start) - 256); + new_angle = clamp_angle (CLUTTER_FIXED_TO_FLOAT (angle_start)); priv = self->priv; if (priv->angle_start != new_angle) @@ -830,7 +813,7 @@ clutter_behaviour_ellipse_get_angle_start (ClutterBehaviourEllipse *self) { g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0.0); - return COGL_ANGLE_TO_DEG (self->priv->angle_start + 256); + return (double)self->priv->angle_start; } /** @@ -848,7 +831,7 @@ clutter_behaviour_ellipse_get_angle_startx (ClutterBehaviourEllipse *self) { g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0); - return COGL_ANGLE_TO_DEGX (self->priv->angle_start); + return CLUTTER_FLOAT_TO_FIXED (self->priv->angle_start); } /** @@ -865,10 +848,11 @@ void clutter_behaviour_ellipse_set_angle_end (ClutterBehaviourEllipse *self, gdouble angle_end) { + ClutterFixed new_angle = CLUTTER_FLOAT_TO_FIXED (angle_end); + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - clutter_behaviour_ellipse_set_angle_endx (self, - COGL_FIXED_FROM_FLOAT (angle_end)); + clutter_behaviour_ellipse_set_angle_endx (self, new_angle); } /** @@ -887,11 +871,11 @@ clutter_behaviour_ellipse_set_angle_endx (ClutterBehaviourEllipse *self, ClutterFixed angle_end) { ClutterBehaviourEllipsePrivate *priv; - ClutterAngle new_angle; + float new_angle; g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - new_angle = clamp_angle (COGL_ANGLE_FROM_DEGX (angle_end) - 256); + new_angle = clamp_angle (CLUTTER_FIXED_TO_FLOAT (angle_end)); priv = self->priv; @@ -918,7 +902,7 @@ clutter_behaviour_ellipse_get_angle_end (ClutterBehaviourEllipse *self) { g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0.0); - return COGL_ANGLE_TO_DEG (self->priv->angle_end + 256); + return self->priv->angle_end; } /** @@ -936,7 +920,7 @@ clutter_behaviour_ellipse_get_angle_endx (ClutterBehaviourEllipse *self) { g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0); - return COGL_ANGLE_TO_DEGX (self->priv->angle_end); + return CLUTTER_FLOAT_TO_FIXED (self->priv->angle_end); } /** @@ -955,11 +939,11 @@ clutter_behaviour_ellipse_set_angle_tilt (ClutterBehaviourEllipse *self, ClutterRotateAxis axis, gdouble angle_tilt) { + ClutterFixed new_angle = CLUTTER_FLOAT_TO_FIXED (angle_tilt); + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - clutter_behaviour_ellipse_set_angle_tiltx (self, - axis, - COGL_FIXED_FROM_FLOAT (angle_tilt)); + clutter_behaviour_ellipse_set_angle_tiltx (self, axis, new_angle); } /** @@ -979,11 +963,11 @@ clutter_behaviour_ellipse_set_angle_tiltx (ClutterBehaviourEllipse *self, ClutterFixed angle_tilt) { ClutterBehaviourEllipsePrivate *priv; - ClutterAngle new_angle; + float new_angle; g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - new_angle = COGL_ANGLE_FROM_DEGX (angle_tilt); + new_angle = CLUTTER_FIXED_TO_FLOAT (angle_tilt); priv = self->priv; @@ -1038,11 +1022,11 @@ clutter_behaviour_ellipse_get_angle_tilt (ClutterBehaviourEllipse *self, switch (axis) { case CLUTTER_X_AXIS: - return COGL_ANGLE_TO_DEG (self->priv->angle_tilt_x); + return self->priv->angle_tilt_x; case CLUTTER_Y_AXIS: - return COGL_ANGLE_TO_DEG (self->priv->angle_tilt_y); + return self->priv->angle_tilt_y; case CLUTTER_Z_AXIS: - return COGL_ANGLE_TO_DEG (self->priv->angle_tilt_z); + return self->priv->angle_tilt_z; } return 0; @@ -1068,11 +1052,11 @@ clutter_behaviour_ellipse_get_angle_tiltx (ClutterBehaviourEllipse *self, switch (axis) { case CLUTTER_X_AXIS: - return COGL_ANGLE_TO_DEGX (self->priv->angle_tilt_x); + return CLUTTER_FLOAT_TO_FIXED (self->priv->angle_tilt_x); case CLUTTER_Y_AXIS: - return COGL_ANGLE_TO_DEGX (self->priv->angle_tilt_y); + return CLUTTER_FLOAT_TO_FIXED (self->priv->angle_tilt_y); case CLUTTER_Z_AXIS: - return COGL_ANGLE_TO_DEGX (self->priv->angle_tilt_z); + return CLUTTER_FLOAT_TO_FIXED (self->priv->angle_tilt_z); } return 0; @@ -1096,13 +1080,13 @@ clutter_behaviour_ellipse_set_tilt (ClutterBehaviourEllipse *self, gdouble angle_tilt_z) { ClutterBehaviourEllipsePrivate *priv; - ClutterAngle new_angle_x, new_angle_y, new_angle_z; + float new_angle_x, new_angle_y, new_angle_z; g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - new_angle_x = COGL_ANGLE_FROM_DEG (angle_tilt_x); - new_angle_y = COGL_ANGLE_FROM_DEG (angle_tilt_y); - new_angle_z = COGL_ANGLE_FROM_DEG (angle_tilt_z); + new_angle_x = (float)angle_tilt_x; + new_angle_y = (float)angle_tilt_y; + new_angle_z = (float)angle_tilt_z; priv = self->priv; @@ -1150,13 +1134,13 @@ clutter_behaviour_ellipse_set_tiltx (ClutterBehaviourEllipse *self, ClutterFixed angle_tilt_z) { ClutterBehaviourEllipsePrivate *priv; - ClutterAngle new_angle_x, new_angle_y, new_angle_z; + float new_angle_x, new_angle_y, new_angle_z; g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - new_angle_x = COGL_ANGLE_FROM_DEGX (angle_tilt_x); - new_angle_y = COGL_ANGLE_FROM_DEGX (angle_tilt_y); - new_angle_z = COGL_ANGLE_FROM_DEGX (angle_tilt_z); + new_angle_x = CLUTTER_FIXED_TO_FLOAT (angle_tilt_x); + new_angle_y = CLUTTER_FIXED_TO_FLOAT (angle_tilt_y); + new_angle_z = CLUTTER_FIXED_TO_FLOAT (angle_tilt_z); priv = self->priv; @@ -1210,13 +1194,13 @@ clutter_behaviour_ellipse_get_tilt (ClutterBehaviourEllipse *self, priv = self->priv; if (angle_tilt_x) - *angle_tilt_x = COGL_ANGLE_TO_DEG (priv->angle_tilt_x); + *angle_tilt_x = priv->angle_tilt_x; if (angle_tilt_y) - *angle_tilt_y = COGL_ANGLE_TO_DEG (priv->angle_tilt_y); + *angle_tilt_y = priv->angle_tilt_y; if (angle_tilt_z) - *angle_tilt_z = COGL_ANGLE_TO_DEG (priv->angle_tilt_z); + *angle_tilt_z = priv->angle_tilt_z; } /** @@ -1246,13 +1230,13 @@ clutter_behaviour_ellipse_get_tiltx (ClutterBehaviourEllipse *self, priv = self->priv; if (angle_tilt_x) - *angle_tilt_x = COGL_ANGLE_TO_DEGX (priv->angle_tilt_x); + *angle_tilt_x = priv->angle_tilt_x; if (angle_tilt_y) - *angle_tilt_y = COGL_ANGLE_TO_DEGX (priv->angle_tilt_y); + *angle_tilt_y = priv->angle_tilt_y; if (angle_tilt_z) - *angle_tilt_z = COGL_ANGLE_TO_DEGX (priv->angle_tilt_z); + *angle_tilt_z = priv->angle_tilt_z; } /** diff --git a/clutter/clutter-behaviour-rotate.c b/clutter/clutter-behaviour-rotate.c index 3e13c6dab..8bfa16e14 100644 --- a/clutter/clutter-behaviour-rotate.c +++ b/clutter/clutter-behaviour-rotate.c @@ -108,8 +108,8 @@ ClutterFixed clamp_angle (ClutterFixed a) ClutterFixed a1, a2; gint rounds; - rounds = a / COGL_FIXED_360; - a1 = rounds * COGL_FIXED_360; + rounds = a / 360.0; + a1 = rounds * 360.0; a2 = a - a1; return a2; @@ -126,7 +126,7 @@ clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour, rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); priv = rotate_behaviour->priv; - factor = COGL_FIXED_FROM_INT (alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; + factor = (float)(alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; angle = 0; start = priv->angle_start; @@ -134,14 +134,14 @@ clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour, if (priv->direction == CLUTTER_ROTATE_CW && start >= end) { - end += COGL_FIXED_360; + end += 360.0; } else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end) { - end -= COGL_FIXED_360; + end -= 360.0; } - angle = COGL_FIXED_FAST_MUL ((end - start), factor) + start; + angle = CLUTTER_FIXED_MUL ((end - start), factor) + start; clutter_behaviour_actors_foreach (behaviour, alpha_notify_foreach, @@ -163,10 +163,10 @@ clutter_behaviour_rotate_set_property (GObject *gobject, switch (prop_id) { case PROP_ANGLE_START: - priv->angle_start = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + priv->angle_start = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); break; case PROP_ANGLE_END: - priv->angle_end = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + priv->angle_end = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); break; case PROP_AXIS: priv->axis = g_value_get_enum (value); @@ -211,10 +211,10 @@ clutter_behaviour_rotate_get_property (GObject *gobject, switch (prop_id) { case PROP_ANGLE_START: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->angle_start)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->angle_start)); break; case PROP_ANGLE_END: - g_value_set_double (value, COGL_FIXED_TO_DOUBLE (priv->angle_end)); + g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->angle_end)); break; case PROP_AXIS: g_value_set_enum (value, priv->axis); @@ -367,8 +367,8 @@ clutter_behaviour_rotate_init (ClutterBehaviourRotate *rotate) rotate->priv = priv = CLUTTER_BEHAVIOUR_ROTATE_GET_PRIVATE (rotate); - priv->angle_start = COGL_FIXED_FROM_FLOAT (0.0); - priv->angle_end = COGL_FIXED_FROM_FLOAT (0.0); + priv->angle_start = CLUTTER_FLOAT_TO_FIXED (0.0); + priv->angle_end = CLUTTER_FLOAT_TO_FIXED (0.0); priv->axis = CLUTTER_Z_AXIS; priv->direction = CLUTTER_ROTATE_CW; priv->center_x = priv->center_y = priv->center_z = 0; @@ -568,10 +568,10 @@ clutter_behaviour_rotate_get_bounds (ClutterBehaviourRotate *rotate, priv = rotate->priv; if (angle_start) - *angle_start = COGL_FIXED_TO_DOUBLE (priv->angle_start); + *angle_start = CLUTTER_FIXED_TO_DOUBLE (priv->angle_start); if (angle_end) - *angle_end = COGL_FIXED_TO_DOUBLE (priv->angle_end); + *angle_end = CLUTTER_FIXED_TO_DOUBLE (priv->angle_end); } /** @@ -593,8 +593,8 @@ clutter_behaviour_rotate_set_bounds (ClutterBehaviourRotate *rotate, g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); clutter_behaviour_rotate_set_boundsx (rotate, - COGL_FIXED_FROM_FLOAT (angle_start), - COGL_FIXED_FROM_FLOAT (angle_end)); + CLUTTER_FLOAT_TO_FIXED (angle_start), + CLUTTER_FLOAT_TO_FIXED (angle_end)); } /** diff --git a/clutter/clutter-behaviour-scale.c b/clutter/clutter-behaviour-scale.c index f358a71f0..66d4542d2 100644 --- a/clutter/clutter-behaviour-scale.c +++ b/clutter/clutter-behaviour-scale.c @@ -115,14 +115,14 @@ clutter_behaviour_scale_alpha_notify (ClutterBehaviour *behave, { ClutterFixed factor; - factor = COGL_FIXED_FROM_INT (alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; + factor = (float)(alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; scale_x = - COGL_FIXED_FAST_MUL (factor, (priv->x_scale_end - priv->x_scale_start)); + CLUTTER_FIXED_MUL (factor, (priv->x_scale_end - priv->x_scale_start)); scale_x += priv->x_scale_start; scale_y = - COGL_FIXED_FAST_MUL (factor, (priv->y_scale_end - priv->y_scale_start)); + CLUTTER_FIXED_MUL (factor, (priv->y_scale_end - priv->y_scale_start)); scale_y += priv->y_scale_start; } @@ -147,16 +147,16 @@ clutter_behaviour_scale_set_property (GObject *gobject, switch (prop_id) { case PROP_X_SCALE_START: - priv->x_scale_start = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + priv->x_scale_start = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); break; case PROP_X_SCALE_END: - priv->x_scale_end = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + priv->x_scale_end = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); break; case PROP_Y_SCALE_START: - priv->y_scale_start = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + priv->y_scale_start = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); break; case PROP_Y_SCALE_END: - priv->y_scale_end = COGL_FIXED_FROM_FLOAT (g_value_get_double (value)); + priv->y_scale_end = CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); @@ -177,16 +177,16 @@ clutter_behaviour_scale_get_property (GObject *gobject, switch (prop_id) { case PROP_X_SCALE_START: - g_value_set_double (value, COGL_FIXED_TO_FLOAT (priv->x_scale_start)); + g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->x_scale_start)); break; case PROP_X_SCALE_END: - g_value_set_double (value, COGL_FIXED_TO_FLOAT (priv->x_scale_end)); + g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->x_scale_end)); break; case PROP_Y_SCALE_START: - g_value_set_double (value, COGL_FIXED_TO_FLOAT (priv->y_scale_start)); + g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->y_scale_start)); break; case PROP_Y_SCALE_END: - g_value_set_double (value, COGL_FIXED_TO_FLOAT (priv->y_scale_end)); + g_value_set_double (value, CLUTTER_FIXED_TO_FLOAT (priv->y_scale_end)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); @@ -276,8 +276,8 @@ clutter_behaviour_scale_init (ClutterBehaviourScale *self) self->priv = priv = CLUTTER_BEHAVIOUR_SCALE_GET_PRIVATE (self); - priv->x_scale_start = priv->x_scale_end = COGL_FIXED_1; - priv->y_scale_start = priv->y_scale_end = COGL_FIXED_1; + priv->x_scale_start = priv->x_scale_end = 1.0; + priv->y_scale_start = priv->y_scale_end = 1.0; } /** @@ -304,10 +304,10 @@ clutter_behaviour_scale_new (ClutterAlpha *alpha, g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL); return clutter_behaviour_scale_newx (alpha, - COGL_FIXED_FROM_FLOAT (x_scale_start), - COGL_FIXED_FROM_FLOAT (y_scale_start), - COGL_FIXED_FROM_FLOAT (x_scale_end), - COGL_FIXED_FROM_FLOAT (y_scale_end)); + CLUTTER_FLOAT_TO_FIXED (x_scale_start), + CLUTTER_FLOAT_TO_FIXED (y_scale_start), + CLUTTER_FLOAT_TO_FIXED (x_scale_end), + CLUTTER_FLOAT_TO_FIXED (y_scale_end)); } /** @@ -367,10 +367,10 @@ clutter_behaviour_scale_set_bounds (ClutterBehaviourScale *scale, g_return_if_fail (CLUTTER_IS_BEHAVIOUR_SCALE (scale)); clutter_behaviour_scale_set_boundsx (scale, - COGL_FIXED_FROM_FLOAT (x_scale_start), - COGL_FIXED_FROM_FLOAT (y_scale_start), - COGL_FIXED_FROM_FLOAT (x_scale_end), - COGL_FIXED_FROM_FLOAT (y_scale_end)); + CLUTTER_FLOAT_TO_FIXED (x_scale_start), + CLUTTER_FLOAT_TO_FIXED (y_scale_start), + CLUTTER_FLOAT_TO_FIXED (x_scale_end), + CLUTTER_FLOAT_TO_FIXED (y_scale_end)); } /** @@ -403,16 +403,16 @@ clutter_behaviour_scale_get_bounds (ClutterBehaviourScale *scale, priv = scale->priv; if (x_scale_start) - *x_scale_start = COGL_FIXED_TO_DOUBLE (priv->x_scale_start); + *x_scale_start = CLUTTER_FIXED_TO_DOUBLE (priv->x_scale_start); if (x_scale_end) - *x_scale_end = COGL_FIXED_TO_DOUBLE (priv->x_scale_end); + *x_scale_end = CLUTTER_FIXED_TO_DOUBLE (priv->x_scale_end); if (y_scale_start) - *y_scale_start = COGL_FIXED_TO_DOUBLE (priv->y_scale_start); + *y_scale_start = CLUTTER_FIXED_TO_DOUBLE (priv->y_scale_start); if (y_scale_end) - *y_scale_end = COGL_FIXED_TO_DOUBLE (priv->y_scale_end); + *y_scale_end = CLUTTER_FIXED_TO_DOUBLE (priv->y_scale_end); } /** diff --git a/clutter/clutter-bezier.c b/clutter/clutter-bezier.c index 6a476268f..66c4ddfd1 100644 --- a/clutter/clutter-bezier.c +++ b/clutter/clutter-bezier.c @@ -252,7 +252,7 @@ _clutter_bezier_init (ClutterBezier *b, int x = _clutter_bezier_t2x (b, t); int y = _clutter_bezier_t2y (b, t); - guint l = clutter_sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp)); + guint l = cogl_sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp)); l += length[i-1]; diff --git a/clutter/clutter-binding-pool.c b/clutter/clutter-binding-pool.c index 78a483f72..73398a58d 100644 --- a/clutter/clutter-binding-pool.c +++ b/clutter/clutter-binding-pool.c @@ -104,6 +104,10 @@ #include "clutter-marshal.h" #include "clutter-private.h" +#define CLUTTER_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass)) +#define CLUTTER_IS_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CLUTTER_TYPE_BINDING_POOL)) +#define CLUTTER_BINDING_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass)) + #define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \ CLUTTER_CONTROL_MASK | \ CLUTTER_MOD1_MASK | \ @@ -111,19 +115,27 @@ CLUTTER_HYPER_MASK | \ CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK) -typedef struct _ClutterBindingEntry ClutterBindingEntry; +typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass; +typedef struct _ClutterBindingEntry ClutterBindingEntry; -static GSList *binding_pools = NULL; +static GSList *clutter_binding_pools = NULL; static GQuark key_class_bindings = 0; struct _ClutterBindingPool { + GObject parent_instance; + gchar *name; /* interned string, do not free */ GSList *entries; GHashTable *entries_hash; }; +struct _ClutterBindingPoolClass +{ + GObjectClass parent_class; +}; + struct _ClutterBindingEntry { gchar *name; /* interned string, do not free */ @@ -136,6 +148,15 @@ struct _ClutterBindingEntry guint is_blocked : 1; }; +enum +{ + PROP_0, + + PROP_NAME +}; + +G_DEFINE_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT); + static guint binding_entry_hash (gconstpointer v) { @@ -204,24 +225,112 @@ binding_entry_free (gpointer data) } static void -binding_pool_free (gpointer data) +clutter_binding_pool_finalize (GObject *gobject) { - if (G_LIKELY (data)) + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + /* remove from the pools */ + clutter_binding_pools = g_slist_remove (clutter_binding_pools, pool); + + g_hash_table_destroy (pool->entries_hash); + + g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL); + g_slist_free (pool->entries); + + G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject); +} + +static void +clutter_binding_pool_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + switch (prop_id) { - ClutterBindingPool *pool = data; + case PROP_NAME: + pool->name = (gchar *) g_intern_string (g_value_get_string (value)); + break; - /* remove from the pools */ - binding_pools = g_slist_remove (binding_pools, pool); - - g_hash_table_destroy (pool->entries_hash); - - g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL); - g_slist_free (pool->entries); - - g_slice_free (ClutterBindingPool, pool); + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; } } +static void +clutter_binding_pool_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, pool->name); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +clutter_binding_pool_constructed (GObject *gobject) +{ + ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); + + /* bad monkey! bad, bad monkey! */ + if (G_UNLIKELY (pool->name == NULL)) + g_critical ("No name set for ClutterBindingPool %p", pool); + + if (G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed) + G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed (gobject); +} + +static void +clutter_binding_pool_class_init (ClutterBindingPoolClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec = NULL; + + gobject_class->constructed = clutter_binding_pool_constructed; + gobject_class->set_property = clutter_binding_pool_set_property; + gobject_class->get_property = clutter_binding_pool_get_property; + gobject_class->finalize = clutter_binding_pool_finalize; + + /** + * ClutterBindingPool:name: + * + * The unique name of the #ClutterBindingPool. + * + * Since: 1.0 + */ + pspec = g_param_spec_string ("name", + "Name", + "The unique name of the binding pool", + NULL, + CLUTTER_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (gobject_class, PROP_NAME, pspec); +} + +static void +clutter_binding_pool_init (ClutterBindingPool *pool) +{ + pool->name = NULL; + pool->entries = NULL; + pool->entries_hash = g_hash_table_new (binding_entry_hash, + binding_entry_compare); + + clutter_binding_pools = g_slist_prepend (clutter_binding_pools, pool); +} + /** * clutter_binding_pool_new: * @name: the name of the binding pool @@ -232,8 +341,7 @@ binding_pool_free (gpointer data) * be able to return the correct binding pool. * * Return value: the newly created binding pool with the given - * name. The binding pool is owned by Clutter and should not - * be freed directly + * name. Use g_object_unref() when done. * * Since: 1.0 */ @@ -253,15 +361,7 @@ clutter_binding_pool_new (const gchar *name) return NULL; } - pool = g_slice_new (ClutterBindingPool); - pool->name = (gchar *) g_intern_string (name); - pool->entries = NULL; - pool->entries_hash = g_hash_table_new (binding_entry_hash, - binding_entry_compare); - - binding_pools = g_slist_prepend (binding_pools, pool); - - return pool; + return g_object_new (CLUTTER_TYPE_BINDING_POOL, "name", name, NULL); } /** @@ -306,7 +406,7 @@ clutter_binding_pool_get_for_class (gpointer klass) pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass)); g_dataset_id_set_data_full (klass, key_class_bindings, pool, - binding_pool_free); + g_object_unref); return pool; } @@ -328,7 +428,7 @@ clutter_binding_pool_find (const gchar *name) g_return_val_if_fail (name != NULL, NULL); - for (l = binding_pools; l != NULL; l = l->next) + for (l = clutter_binding_pools; l != NULL; l = l->next) { ClutterBindingPool *pool = l->data; diff --git a/clutter/clutter-binding-pool.h b/clutter/clutter-binding-pool.h index 55b5273c8..fd85f2664 100644 --- a/clutter/clutter-binding-pool.h +++ b/clutter/clutter-binding-pool.h @@ -33,6 +33,18 @@ G_BEGIN_DECLS +#define CLUTTER_TYPE_BINDING_POOL (clutter_binding_pool_get_type ()) +#define CLUTTER_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPool)) +#define CLUTTER_IS_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BINDING_POOL)) + +/** + * ClutterBindingPool: + * + * Container of key bindings. The #ClutterBindingPool struct is + * private. + * + * Since: 1.0 + */ typedef struct _ClutterBindingPool ClutterBindingPool; /** @@ -56,6 +68,8 @@ typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject, guint key_val, ClutterModifierType modifiers); +GType clutter_binding_pool_get_type (void) G_GNUC_CONST; + ClutterBindingPool * clutter_binding_pool_new (const gchar *name); ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass); ClutterBindingPool * clutter_binding_pool_find (const gchar *name); diff --git a/clutter/clutter-clone-texture.c b/clutter/clutter-clone-texture.c index 0810a90fe..2cd19899e 100644 --- a/clutter/clutter-clone-texture.c +++ b/clutter/clutter-clone-texture.c @@ -209,15 +209,15 @@ clutter_clone_texture_paint (ClutterActor *self) tex_height = cogl_texture_get_height (cogl_texture); if (priv->repeat_x && tex_width > 0) - t_w = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (x_2 - x_1), - COGL_FIXED_FROM_INT (tex_width)); + t_w = CLUTTER_FIXED_DIV ((float)(x_2 - x_1), + (float)(tex_width)); else - t_w = COGL_FIXED_1; + t_w = 1.0; if (priv->repeat_y && tex_height > 0) - t_h = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (y_2 - y_1), - COGL_FIXED_FROM_INT (tex_height)); + t_h = CLUTTER_FIXED_DIV ((float)(y_2 - y_1), + (float)(tex_height)); else - t_h = COGL_FIXED_1; + t_h = 1.0; #if USE_COGL_MATERIAL cogl_set_source (cogl_material); @@ -234,8 +234,8 @@ clutter_clone_texture_paint (ClutterActor *self) #else /* Parent paint translated us into position */ cogl_texture_rectangle (cogl_texture, 0, 0, - COGL_FIXED_FROM_INT (x_2 - x_1), - COGL_FIXED_FROM_INT (y_2 - y_1), + (float)(x_2 - x_1), + (float)(y_2 - y_1), 0, 0, t_w, t_h); #endif } diff --git a/clutter/clutter-color.c b/clutter/clutter-color.c index 411bb1377..b77b3a7f4 100644 --- a/clutter/clutter-color.c +++ b/clutter/clutter-color.c @@ -154,9 +154,9 @@ clutter_color_to_hlsx (const ClutterColor *src, g_return_if_fail (src != NULL); - red = COGL_FIXED_FROM_INT (src->red) / 255; - green = COGL_FIXED_FROM_INT (src->green) / 255; - blue = COGL_FIXED_FROM_INT (src->blue) / 255; + red = (float)(src->red) / 255; + green = (float)(src->green) / 255; + blue = (float)(src->blue) / 255; if (red > green) { @@ -189,31 +189,31 @@ clutter_color_to_hlsx (const ClutterColor *src, if (max != min) { - if (l <= COGL_FIXED_0_5) - s = COGL_FIXED_FAST_DIV ((max - min), (max + min)); + if (l <= 0.5) + s = CLUTTER_FIXED_DIV ((max - min), (max + min)); else - s = COGL_FIXED_FAST_DIV ((max - min), - (COGL_FIXED_FROM_INT (2) - max - min)); + s = CLUTTER_FIXED_DIV ((max - min), + ((float)(2) - max - min)); delta = max - min; if (red == max) - h = COGL_FIXED_FAST_DIV ((green - blue), delta); + h = CLUTTER_FIXED_DIV ((green - blue), delta); else if (green == max) { - h = COGL_FIXED_FROM_INT (2) - + COGL_FIXED_FAST_DIV ((blue - red), delta); + h = (float)(2) + + CLUTTER_FIXED_DIV ((blue - red), delta); } else if (blue == max) { - h = COGL_FIXED_FROM_INT (4) - + COGL_FIXED_FAST_DIV ((red - green), delta); + h = (float)(4) + + CLUTTER_FIXED_DIV ((red - green), delta); } h *= 60; if (h < 0) - h += COGL_FIXED_360; + h += 360.0; } if (hue) @@ -251,102 +251,102 @@ clutter_color_from_hlsx (ClutterColor *dest, l = luminance; s = saturation; - if (l <= COGL_FIXED_0_5) - m2 = COGL_FIXED_FAST_MUL (l, (COGL_FIXED_1 + s)); + if (l <= 0.5) + m2 = CLUTTER_FIXED_MUL (l, (1.0 + s)); else - m2 = l + s - COGL_FIXED_FAST_MUL (l, s); + m2 = l + s - CLUTTER_FIXED_MUL (l, s); m1 = 2 * l - m2; if (s == 0) { - dest->red = (guint8) COGL_FIXED_TO_INT (l * 255); - dest->green = (guint8) COGL_FIXED_TO_INT (l * 255); - dest->blue = (guint8) COGL_FIXED_TO_INT (l * 255); + dest->red = (guint8) (l * 255); + dest->green = (guint8) (l * 255); + dest->blue = (guint8) (l * 255); } else { - h = hue + COGL_FIXED_120; + h = hue + 120.0; - while (h > COGL_FIXED_360) - h -= COGL_FIXED_360; + while (h > 360.0) + h -= 360.0; while (h < 0) - h += COGL_FIXED_360; + h += 360.0; - if (h < COGL_FIXED_60) + if (h < 60.0) { - CoglFixed tmp; + float tmp; - tmp = (m1 + COGL_FIXED_FAST_MUL ((m2 - m1), h) / 60); - dest->red = (guint8) COGL_FIXED_TO_INT (tmp * 255); + tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), h) / 60); + dest->red = (guint8) (tmp * 255); } - else if (h < COGL_FIXED_180) - dest->red = (guint8) COGL_FIXED_TO_INT (m2 * 255); - else if (h < COGL_FIXED_240) + else if (h < 180.0) + dest->red = (guint8) (m2 * 255); + else if (h < 240.0) { - CoglFixed tmp; + float tmp; - tmp = (m1 + COGL_FIXED_FAST_MUL ((m2 - m1), (COGL_FIXED_240 - h))) + tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), (240.0 - h))) / 60; - dest->red = (guint8) COGL_FIXED_TO_INT (tmp * 255); + dest->red = (guint8) (tmp * 255); } else - dest->red = (guint8) COGL_FIXED_TO_INT (m1 * 255); + dest->red = (guint8) (m1 * 255); h = hue; - while (h > COGL_FIXED_360) - h -= COGL_FIXED_360; + while (h > 360.0) + h -= 360.0; while (h < 0) - h += COGL_FIXED_360; + h += 360.0; - if (h < COGL_FIXED_60) + if (h < 60.0) { - CoglFixed tmp; + float tmp; - tmp = (m1 + COGL_FIXED_FAST_MUL ((m2 - m1), h) / 60); - dest->green = (guint8) COGL_FIXED_TO_INT (tmp * 255); + tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), h) / 60); + dest->green = (guint8) (tmp * 255); } - else if (h < COGL_FIXED_180) - dest->green = (guint8) COGL_FIXED_TO_INT (m2 * 255); - else if (h < COGL_FIXED_240) + else if (h < 180.0) + dest->green = (guint8) (m2 * 255); + else if (h < 240.0) { - CoglFixed tmp; + float tmp; - tmp = (m1 + COGL_FIXED_FAST_MUL ((m2 - m1) , (COGL_FIXED_240 - h))) + tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1) , (240.0 - h))) / 60; - dest->green = (guint8) COGL_FIXED_TO_INT (tmp * 255); + dest->green = (guint8) (tmp * 255); } else - dest->green = (guint8) COGL_FIXED_TO_INT (m1 * 255); + dest->green = (guint8) (m1 * 255); - h = hue - COGL_FIXED_120; + h = hue - 120.0; - while (h > COGL_FIXED_360) - h -= COGL_FIXED_360; + while (h > 360.0) + h -= 360.0; while (h < 0) - h += COGL_FIXED_360; + h += 360.0; - if (h < COGL_FIXED_60) + if (h < 60.0) { - CoglFixed tmp; + float tmp; - tmp = (m1 + COGL_FIXED_FAST_MUL ((m2 - m1), h) / 60); - dest->blue = (guint8) COGL_FIXED_TO_INT (tmp * 255); + tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), h) / 60); + dest->blue = (guint8) (tmp * 255); } - else if (h < COGL_FIXED_180) - dest->blue = (guint8) COGL_FIXED_TO_INT (m2 * 255); - else if (h < COGL_FIXED_240) + else if (h < 180.0) + dest->blue = (guint8) (m2 * 255); + else if (h < 240.0) { - CoglFixed tmp; + float tmp; - tmp = (m1 + COGL_FIXED_FAST_MUL ((m2 - m1), (COGL_FIXED_240 - h))) + tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), (240.0 - h))) / 60; - dest->blue = (guint8) COGL_FIXED_TO_INT (tmp * 255); + dest->blue = (guint8) (tmp * 255); } else - dest->blue = (guint8) COGL_FIXED_TO_INT (m1 * 255); + dest->blue = (guint8) (m1 * 255); } } @@ -371,13 +371,13 @@ clutter_color_to_hls (const ClutterColor *src, clutter_color_to_hlsx (src, &h, &l, &s); if (hue) - *hue = (guint8) COGL_FIXED_TO_INT (h * 255) / 360; + *hue = (guint8) (h * 255) / 360; if (luminance) - *luminance = (guint8) COGL_FIXED_TO_INT (l * 255); + *luminance = (guint8) (l * 255); if (saturation) - *saturation = (guint8) COGL_FIXED_TO_INT (s * 255); + *saturation = (guint8) (s * 255); } /** @@ -399,9 +399,9 @@ clutter_color_from_hls (ClutterColor *dest, { ClutterFixed h, l, s; - h = COGL_FIXED_FROM_INT (hue * 360) / 255; - l = COGL_FIXED_FROM_INT (luminance) / 255; - s = COGL_FIXED_FROM_INT (saturation) / 255; + h = (float)(hue * 360) / 255; + l = (float)(luminance) / 255; + s = (float)(saturation) / 255; clutter_color_from_hlsx (dest, h, l, s); } @@ -420,7 +420,7 @@ clutter_color_shade (const ClutterColor *src, ClutterColor *dest, gdouble shade) { - clutter_color_shadex (src, dest, COGL_FIXED_FROM_FLOAT (shade)); + clutter_color_shadex (src, dest, CLUTTER_FLOAT_TO_FIXED (shade)); } /** @@ -448,15 +448,15 @@ clutter_color_shadex (const ClutterColor *src, clutter_color_to_hlsx (src, &h, &l, &s); - l = COGL_FIXED_FAST_MUL (l, shade); - if (l > COGL_FIXED_1) - l = COGL_FIXED_1; + l = CLUTTER_FIXED_MUL (l, shade); + if (l > 1.0) + l = 1.0; else if (l < 0) l = 0; - s = COGL_FIXED_FAST_MUL (s, shade); - if (s > COGL_FIXED_1) - s = COGL_FIXED_1; + s = CLUTTER_FIXED_MUL (s, shade); + if (s > 1.0) + s = 1.0; else if (s < 0) s = 0; diff --git a/clutter/clutter-effect.c b/clutter/clutter-effect.c deleted file mode 100644 index 64fd25b4a..000000000 --- a/clutter/clutter-effect.c +++ /dev/null @@ -1,848 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:clutter-effect - * @short_description: Utility Class for basic visual effects - * - * The #ClutterEffectTemplate class provides a simple API for applying - * pre-defined effects to a single actor. It works as a wrapper around - * the #ClutterBehaviour objects - * - * Since: 0.4 - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "clutter-alpha.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-debug.h" -#include "clutter-behaviour-depth.h" -#include "clutter-behaviour-ellipse.h" -#include "clutter-behaviour-opacity.h" -#include "clutter-behaviour-path.h" -#include "clutter-behaviour-rotate.h" -#include "clutter-behaviour-scale.h" - -#include "clutter-effect.h" - -typedef struct ClutterEffectClosure -{ - ClutterActor *actor; - ClutterTimeline *timeline; - ClutterAlpha *alpha; - ClutterBehaviour *behave; - - gulong signal_id; - - ClutterEffectCompleteFunc completed_func; - gpointer completed_data; - ClutterEffectTemplate *template; -} -ClutterEffectClosure; - -G_DEFINE_TYPE (ClutterEffectTemplate, clutter_effect_template, G_TYPE_OBJECT); - -#define EFFECT_TEMPLATE_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, \ - ClutterEffectTemplatePrivate)) - -struct _ClutterEffectTemplatePrivate -{ - ClutterTimeline *timeline; - - guint do_clone : 1; - guint dirty : 1; - - ClutterAlphaFunc alpha_func; - gpointer alpha_data; - GDestroyNotify alpha_notify; -}; - -enum -{ - PROP_0, - - PROP_TIMELINE, - PROP_DO_CLONE -}; - -static void -clutter_effect_template_finalize (GObject *gobject) -{ - ClutterEffectTemplate *template = CLUTTER_EFFECT_TEMPLATE (gobject); - ClutterEffectTemplatePrivate *priv = template->priv; - - if (priv->alpha_notify) - { - priv->alpha_notify (priv->alpha_data); - priv->alpha_notify = NULL; - } - - priv->alpha_data = NULL; - priv->alpha_func = NULL; - - G_OBJECT_CLASS (clutter_effect_template_parent_class)->finalize (gobject); -} - -static void -clutter_effect_template_dispose (GObject *object) -{ - ClutterEffectTemplate *template; - ClutterEffectTemplatePrivate *priv; - - template = CLUTTER_EFFECT_TEMPLATE (object); - priv = template->priv; - - if (priv->timeline) - { - g_object_unref (priv->timeline); - priv->timeline = NULL; - } - - G_OBJECT_CLASS (clutter_effect_template_parent_class)->dispose (object); -} - -static void -clutter_effect_template_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterEffectTemplate *template; - ClutterEffectTemplatePrivate *priv; - - template = CLUTTER_EFFECT_TEMPLATE (object); - priv = template->priv; - - switch (prop_id) - { - case PROP_TIMELINE: - priv->timeline = g_value_dup_object (value); - break; - case PROP_DO_CLONE: - clutter_effect_template_set_timeline_clone (template, - g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_effect_template_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterEffectTemplate *template; - ClutterEffectTemplatePrivate *priv; - - template = CLUTTER_EFFECT_TEMPLATE (object); - priv = template->priv; - - switch (prop_id) - { - case PROP_TIMELINE: - g_value_set_object (value, priv->timeline); - break; - case PROP_DO_CLONE: - g_value_set_boolean (value, priv->do_clone); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_effect_template_class_init (ClutterEffectTemplateClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (ClutterEffectTemplatePrivate)); - - object_class->finalize = clutter_effect_template_finalize; - object_class->dispose = clutter_effect_template_dispose; - object_class->set_property = clutter_effect_template_set_property; - object_class->get_property = clutter_effect_template_get_property; - - /** - * ClutterEffectTemplate:timeline: - * - * #ClutterTimeline to be used by the template - * - * Since: 0.4 - */ - g_object_class_install_property - (object_class, - PROP_TIMELINE, - g_param_spec_object ("timeline", - "Timeline", - "Timeline to use as a reference for the Template", - CLUTTER_TYPE_TIMELINE, - G_PARAM_CONSTRUCT_ONLY | - CLUTTER_PARAM_READWRITE)); - - /** - * ClutterEffectTemplate:clone: - * - * Controls if effects should clone or reference the templated timeline - * - * Since: 0.6 - */ - g_object_class_install_property - (object_class, - PROP_DO_CLONE, - g_param_spec_boolean ("clone", - "Clone", - "controls if effects should clone or reference the templated timeline", - TRUE, - CLUTTER_PARAM_READWRITE)); - -} - -static void -clutter_effect_template_init (ClutterEffectTemplate *self) -{ - self->priv = EFFECT_TEMPLATE_PRIVATE (self); - - self->priv->do_clone = TRUE; - self->priv->dirty = TRUE; -} - -static void -clutter_effect_template_set_alpha_func (ClutterEffectTemplate *self, - ClutterAlphaFunc alpha_func, - gpointer alpha_data, - GDestroyNotify alpha_notify) -{ - ClutterEffectTemplatePrivate *priv; - - priv = self->priv; - - if (priv->alpha_notify) - { - priv->alpha_notify (priv->alpha_data); - priv->alpha_notify = NULL; - } - - priv->alpha_data = alpha_data; - priv->alpha_notify = alpha_notify; - priv->alpha_func = alpha_func; - - priv->dirty = FALSE; -} - -/** - * clutter_effect_template_set_timeline_clone: - * @template_: A #ClutterEffectTemplate - * @setting: A boolean indicating if effects should clone the timeline. - * - * Sets if effects using this template should make a copy of the - * templates timeline (default) or reference the effects timeline. - * - * Since: 0.6 - */ -void -clutter_effect_template_set_timeline_clone (ClutterEffectTemplate *template_, - gboolean setting) -{ - g_return_if_fail (CLUTTER_IS_EFFECT_TEMPLATE (template_)); - - if (template_->priv->do_clone != setting) - { - template_->priv->do_clone = setting; - - g_object_notify (G_OBJECT (template_), "clone"); - } -} - -/** - * clutter_effect_template_get_timeline_clone: - * @template_: A #ClutterEffectTemplate - * - * Gets whether timelines should be cloned when creating a new - * effect or just referenced. - * - * Return value: %TRUE if the templates timeline is to be cloned. - * - * Since: 0.6 - */ -gboolean -clutter_effect_template_get_timeline_clone (ClutterEffectTemplate *template_) -{ - g_return_val_if_fail (CLUTTER_IS_EFFECT_TEMPLATE (template_), FALSE); - - return template_->priv->do_clone; -} - - -/** - * clutter_effect_template_new: - * @timeline: A #ClutterTimeline for the template (will be cloned) - * @alpha_func: An alpha func to use for the template. - * - * Creates a new #ClutterEffectTemplate, to be used with the effects API. - * - * A #ClutterEffectTemplate binds a timeline and an alpha function and can - * be used as a template for multiple calls of clutter_effect_fade(), - * clutter_effect_move() and clutter_effect_scale(). - * - * This API is intended for simple animations involving a single actor; - * for more complex animations, you should see #ClutterBehaviour and the - * derived classes. - * - * Return value: a #ClutterEffectTemplate - * - * Since: 0.4 - */ -ClutterEffectTemplate* -clutter_effect_template_new (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func) -{ - ClutterEffectTemplate *retval; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (alpha_func != NULL, NULL); - - retval = g_object_new (CLUTTER_TYPE_EFFECT_TEMPLATE, - "timeline", timeline, - NULL); - - clutter_effect_template_set_alpha_func (retval, alpha_func, NULL, NULL); - - return retval; -} - -/** - * clutter_effect_template_new_full: - * @timeline: a #ClutterTimeline - * @alpha_func: an alpha function to use for the template - * @user_data: data to be passed to the alpha function, or %NULL - * @notify: function to be called when disposing the alpha function's use - * data, or %NULL - * - * Creates a new #ClutterEffectTemplate, to be used with the effects API. - * - * A #ClutterEffectTemplate binds a timeline and an alpha function and can - * be used as a template for multiple calls of clutter_effect_fade(), - * clutter_effect_move() and clutter_effect_scale(). - * - * This API is intended for simple animations involving a single actor; - * for more complex animations, you should see #ClutterBehaviour and the - * derived classes. - * - * This function is intended for language bindings only: if @notify is - * not %NULL it will be called to dispose of @user_data. - * - * Return value: the newly created #ClutterEffectTemplate object - * - * Since: 0.4 - */ -ClutterEffectTemplate * -clutter_effect_template_new_full (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterEffectTemplate *retval; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (alpha_func != NULL, NULL); - - retval = g_object_new (CLUTTER_TYPE_EFFECT_TEMPLATE, - "timeline", timeline, - NULL); - - clutter_effect_template_set_alpha_func (retval, - alpha_func, - user_data, notify); - - return retval; -} - -/** - * clutter_effect_template_new_for_duration: - * @msecs: the duration of the effects, in milliseconds - * @alpha_func: an alpha function to use for the template - * - * Creates a new #ClutterEffectTemplate, to be used with the effects API. - * - * A #ClutterEffectTemplate binds a timeline and an alpha function and can - * be used as a template for multiple calls of clutter_effect_fade(), - * clutter_effect_move() and clutter_effect_scale(). - * - * This API is intended for simple animations involving a single actor; - * for more complex animations, you should see #ClutterBehaviour and the - * derived classes. - * - * This function creates a #ClutterTimeline with a duration of @msecs - * milliseconds and transfers ownership of the timeline object to the - * returned #ClutterEffectTemplate. - * - * Return value: the newly created #ClutterEffectTemplate object - * - * Since: 0.6 - */ -ClutterEffectTemplate * -clutter_effect_template_new_for_duration (guint msecs, - ClutterAlphaFunc alpha_func) -{ - ClutterTimeline *timeline; - ClutterEffectTemplate *retval; - - g_return_val_if_fail (msecs > 0, NULL); - g_return_val_if_fail (alpha_func != NULL, NULL); - - timeline = clutter_timeline_new_for_duration (msecs); - retval = clutter_effect_template_new (timeline, alpha_func); - - /* the effect template takes ownership of the timeline */ - g_object_unref (timeline); - - return retval; -} - -/** - * clutter_effect_template_construct: - * @template_: a #ClutterEffectTemplate - * @timeline: a #ClutterTimeline - * @alpha_func: an alpha function to use for the template - * @user_data: data to be passed to the alpha function, or %NULL - * @notify: function to be called when disposing the alpha function's use - * data, or %NULL - * - * Constructs a #ClutterEffectTemplate, to be used with the effects API. - * - * This function can only be called once after the creation of @template_ - * and is only useful for language bindings. - * - * Since: 0.6 - */ -void -clutter_effect_template_construct (ClutterEffectTemplate *template_, - ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterEffectTemplatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_EFFECT_TEMPLATE (template_)); - g_return_if_fail (CLUTTER_IS_TIMELINE (timeline)); - g_return_if_fail (alpha_func != NULL); - - if (!template_->priv->dirty) - return; - - priv = template_->priv; - - if (priv->timeline) - g_object_unref (priv->timeline); - - priv->timeline = g_object_ref (timeline); - clutter_effect_template_set_alpha_func (template_, - alpha_func, - user_data, notify); -} - -static void -clutter_effect_closure_destroy (ClutterEffectClosure *c) -{ - g_signal_handler_disconnect (c->timeline, c->signal_id); - - g_object_unref (c->actor); - g_object_unref (c->template); - g_object_unref (c->behave); - g_object_unref (c->timeline); - - g_slice_free (ClutterEffectClosure, c); -} - -static ClutterEffectClosure * -clutter_effect_closure_new (ClutterEffectTemplate *template, - ClutterActor *actor, - GCallback complete) -{ - ClutterEffectClosure *c; - ClutterEffectTemplatePrivate *priv = EFFECT_TEMPLATE_PRIVATE(template); - - c = g_slice_new0(ClutterEffectClosure); - - g_object_ref (actor); - g_object_ref (template); - - c->template = template; - c->actor = actor; - - if (clutter_effect_template_get_timeline_clone (template)) - c->timeline = clutter_timeline_clone (priv->timeline); - else - { - c->timeline = priv->timeline; - g_object_ref (priv->timeline); - } - - c->alpha = clutter_alpha_new_full (c->timeline, - priv->alpha_func, - priv->alpha_data, - NULL); - - c->signal_id = - g_signal_connect (c->timeline, "completed", G_CALLBACK (complete), c); - - return c; -} - -static void -on_effect_complete (ClutterTimeline *timeline, - gpointer user_data) -{ - ClutterEffectClosure *c = (ClutterEffectClosure*)user_data; - - if (c->completed_func) - c->completed_func (c->actor, c->completed_data); - - clutter_effect_closure_destroy (c); -} - -/** - * clutter_effect_fade: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @opacity_end: Final opacity value to apply to actor - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for fading a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unrefed by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_fade (ClutterEffectTemplate *template_, - ClutterActor *actor, - guint8 opacity_end, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - guint8 opacity_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - opacity_start = clutter_actor_get_opacity (actor); - - c->behave = clutter_behaviour_opacity_new (c->alpha, - opacity_start, - opacity_end); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_depth: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @depth_end: Final depth value to apply to actor - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for changing the depth of a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unrefed by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_depth (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint depth_end, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - gint depth_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - depth_start = clutter_actor_get_depth (actor); - - c->behave = clutter_behaviour_depth_new (c->alpha, depth_start, depth_end); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_move: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @x: X coordinate of the destination - * @y: Y coordinate of the destination - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for moving a single #ClutterActor along to a - * destination point. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_move (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint x, - gint y, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - ClutterPath *path; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - path = clutter_path_new (); - - clutter_path_add_move_to (path, - clutter_actor_get_x (actor), - clutter_actor_get_y (actor)); - clutter_path_add_line_to (path, x, y); - - c->behave = clutter_behaviour_path_new (c->alpha, path); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} -/** - * clutter_effect_path: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @knots: An array of #ClutterKnots representing path for the actor - * @n_knots: Number of #ClutterKnots in passed array. - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or %NULL - * - * Simple effect for moving a single #ClutterActor along a path. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_path (ClutterEffectTemplate *template_, - ClutterActor *actor, - const ClutterKnot *knots, - guint n_knots, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - ClutterPath *path; - guint i; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - path = clutter_path_new (); - - c->completed_func = func; - c->completed_data = data; - - path = clutter_path_new (); - - if (n_knots) - { - clutter_actor_set_position (actor, knots[0].x, knots[0].y); - clutter_path_add_move_to (path, knots[0].x, knots[0].y); - - for (i = 1; i < n_knots; i++) - clutter_path_add_line_to (path, knots[i].x, knots[i].y); - } - - c->behave = clutter_behaviour_path_new (c->alpha, path); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_scale: - * @template_: A #ClutterEffectTemplate - * @actor: A #ClutterActor to apply the effect to. - * @x_scale_end: Final X axis scale factor to apply to actor - * @y_scale_end: Final Y axis scale factor to apply to actor - * @func: A #ClutterEffectCompleteFunc to call on effect - * completion or NULL - * @data: Data to pass to supplied #ClutterEffectCompleteFunc - * or NULL - * - * Simple effect for scaling a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_scale (ClutterEffectTemplate *template_, - ClutterActor *actor, - gdouble x_scale_end, - gdouble y_scale_end, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - gdouble x_scale_start, y_scale_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - clutter_actor_get_scale (actor, &x_scale_start, &y_scale_start); - c->behave = clutter_behaviour_scale_new (c->alpha, - x_scale_start, y_scale_start, - x_scale_end, y_scale_end); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} - -/** - * clutter_effect_rotate: - * @template_: a #ClutterEffectTemplate - * @actor: a #ClutterActor to apply the effect to. - * @axis: axis of rotation - * @angle: final angle to apply to actor - * @center_x: position on X axis to rotate about. - * @center_y: position on Y axis to rotate about. - * @center_z: position on Z axis to rotate about. - * @direction: a #ClutterRotateDirection for the rotation. - * @func: a #ClutterEffectCompleteFunc to call on effect - * completion or %NULL - * @data: user data to pass to supplied @func or %NULL - * - * Simple effect for rotating a single #ClutterActor. - * - * Return value: a #ClutterTimeline for the effect. Will be unreferenced by - * the effect when completed. - * - * Since: 0.6 - */ -ClutterTimeline * -clutter_effect_rotate (ClutterEffectTemplate *template_, - ClutterActor *actor, - ClutterRotateAxis axis, - gdouble angle_end, - gint center_x, - gint center_y, - gint center_z, - ClutterRotateDirection direction, - ClutterEffectCompleteFunc func, - gpointer data) -{ - ClutterEffectClosure *c; - gdouble angle_start; - - c = clutter_effect_closure_new (template_, - actor, - G_CALLBACK (on_effect_complete)); - - c->completed_func = func; - c->completed_data = data; - - angle_start = clutter_actor_get_rotation (actor, axis, NULL, NULL, NULL); - - c->behave = clutter_behaviour_rotate_new (c->alpha, - axis, - direction, - angle_start, - angle_end); - g_object_set (c->behave, - "center-x", center_x, - "center-y", center_y, - "center-z", center_z, - NULL); - - clutter_behaviour_apply (c->behave, actor); - clutter_timeline_start (c->timeline); - - return c->timeline; -} diff --git a/clutter/clutter-effect.h b/clutter/clutter-effect.h deleted file mode 100644 index 0d1fb176d..000000000 --- a/clutter/clutter-effect.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006, 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_EFFECT_H__ -#define __CLUTTER_EFFECT_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -/** - * ClutterEffectCompleteFunc: - * @actor: a #ClutterActor - * @user_data: user data - * - * Callback function invoked when an effect is complete. - * - * Since: 0.4 - */ -typedef void (*ClutterEffectCompleteFunc) (ClutterActor *actor, - gpointer user_data); - -#define CLUTTER_TYPE_EFFECT_TEMPLATE clutter_effect_template_get_type() - -#define CLUTTER_EFFECT_TEMPLATE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplate)) - -#define CLUTTER_EFFECT_TEMPLATE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplateClass)) - -#define CLUTTER_IS_EFFECT_TEMPLATE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_EFFECT_TEMPLATE)) - -#define CLUTTER_IS_EFFECT_TEMPLATE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_EFFECT_TEMPLATE)) - -#define CLUTTER_EFFECT_TEMPLATE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplateClass)) - -typedef struct _ClutterEffectTemplate ClutterEffectTemplate; -typedef struct _ClutterEffectTemplatePrivate ClutterEffectTemplatePrivate; -typedef struct _ClutterEffectTemplateClass ClutterEffectTemplateClass; - - -struct _ClutterEffectTemplate -{ - /*< private >*/ - GObject parent_instance; - - ClutterEffectTemplatePrivate *priv; -}; - -struct _ClutterEffectTemplateClass -{ - /*< private >*/ - GObjectClass parent_class; - - /* padding, for future expansion */ - void (*_clutter_reserved1) (void); - void (*_clutter_reserved2) (void); - void (*_clutter_reserved3) (void); - void (*_clutter_reserved4) (void); -}; - -GType clutter_effect_template_get_type (void) G_GNUC_CONST; -ClutterEffectTemplate *clutter_effect_template_new (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func); -ClutterEffectTemplate *clutter_effect_template_new_full (ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify); -ClutterEffectTemplate *clutter_effect_template_new_for_duration (guint msecs, - ClutterAlphaFunc alpha_func); -void clutter_effect_template_construct (ClutterEffectTemplate *template_, - ClutterTimeline *timeline, - ClutterAlphaFunc alpha_func, - gpointer user_data, - GDestroyNotify notify); -void clutter_effect_template_set_timeline_clone (ClutterEffectTemplate *template_, - gboolean setting); -gboolean clutter_effect_template_get_timeline_clone (ClutterEffectTemplate *template_); - - -/* - * Clutter effects - */ - -ClutterTimeline *clutter_effect_fade (ClutterEffectTemplate *template_, - ClutterActor *actor, - guint8 opacity_end, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_depth (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint depth_end, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_move (ClutterEffectTemplate *template_, - ClutterActor *actor, - gint x, - gint y, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_path (ClutterEffectTemplate *template_, - ClutterActor *actor, - const ClutterKnot *knots, - guint n_knots, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_scale (ClutterEffectTemplate *template_, - ClutterActor *actor, - gdouble x_scale_end, - gdouble y_scale_end, - ClutterEffectCompleteFunc func, - gpointer data); -ClutterTimeline *clutter_effect_rotate (ClutterEffectTemplate *template_, - ClutterActor *actor, - ClutterRotateAxis axis, - gdouble angle, - gint center_x, - gint center_y, - gint center_z, - ClutterRotateDirection direction, - ClutterEffectCompleteFunc func, - gpointer data); - -G_END_DECLS - -#endif /* __CLUTTER_EFFECT_H__ */ diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h index 4c557ca3a..9ee18f4ab 100644 --- a/clutter/clutter-event.h +++ b/clutter/clutter-event.h @@ -264,8 +264,8 @@ struct _ClutterKeyEvent * @flags: event flags * @stage: event source stage * @source: event source actor - * @x: event X coordinate - * @y: event Y coordinate + * @x: event X coordinate, relative to the stage + * @y: event Y coordinate, relative to the stage * @modifier_state: button modifiers * @button: event button * @click_count: number of button presses within the default time @@ -273,7 +273,11 @@ struct _ClutterKeyEvent * @axes: reserved for future use * @device: reserved for future use * - * Button event + * Button event. + * + * The event coordinates are relative to the stage that received the + * event, and can be transformed into actor-relative coordinates by + * using clutter_actor_transform_stage_point(). * * Since: 0.2 */ @@ -447,7 +451,7 @@ ClutterModifierType clutter_event_get_state (ClutterEvent *event); void clutter_event_get_coords (ClutterEvent *event, gint *x, gint *y); -gint clutter_event_get_device_id (ClutterEvent *event); +gint clutter_event_get_device_id (ClutterEvent *event); ClutterActor* clutter_event_get_source (ClutterEvent *event); guint clutter_key_event_symbol (ClutterKeyEvent *keyev); @@ -458,7 +462,7 @@ guint32 clutter_button_event_button (ClutterButtonEvent *buttev); guint32 clutter_keysym_to_unicode (guint keyval); -ClutterStage* clutter_event_get_stage (ClutterEvent *event); +ClutterStage* clutter_event_get_stage (ClutterEvent *event); G_END_DECLS diff --git a/clutter/clutter-fixed.c b/clutter/clutter-fixed.c index af616e6fe..315fe32e2 100644 --- a/clutter/clutter-fixed.c +++ b/clutter/clutter-fixed.c @@ -130,42 +130,42 @@ static void clutter_value_transform_fixed_int (const GValue *src, GValue *dest) { - dest->data[0].v_int = COGL_FIXED_TO_INT (src->data[0].v_int); + dest->data[0].v_int = (src->data[0].v_int); } static void clutter_value_transform_fixed_double (const GValue *src, GValue *dest) { - dest->data[0].v_double = COGL_FIXED_TO_DOUBLE (src->data[0].v_int); + dest->data[0].v_double = CLUTTER_FIXED_TO_DOUBLE (src->data[0].v_int); } static void clutter_value_transform_fixed_float (const GValue *src, GValue *dest) { - dest->data[0].v_float = COGL_FIXED_TO_FLOAT (src->data[0].v_int); + dest->data[0].v_float = CLUTTER_FIXED_TO_FLOAT (src->data[0].v_int); } static void clutter_value_transform_int_fixed (const GValue *src, GValue *dest) { - dest->data[0].v_int = COGL_FIXED_FROM_INT (src->data[0].v_int); + dest->data[0].v_int = (float)(src->data[0].v_int); } static void clutter_value_transform_double_fixed (const GValue *src, GValue *dest) { - dest->data[0].v_int = COGL_FIXED_FROM_FLOAT (src->data[0].v_double); + dest->data[0].v_int = CLUTTER_FLOAT_TO_FIXED (src->data[0].v_double); } static void clutter_value_transform_float_fixed (const GValue *src, GValue *dest) { - dest->data[0].v_int = COGL_FIXED_FROM_FLOAT (src->data[0].v_float); + dest->data[0].v_int = CLUTTER_FLOAT_TO_FIXED (src->data[0].v_float); } @@ -251,8 +251,8 @@ param_fixed_init (GParamSpec *pspec) { ClutterParamSpecFixed *fspec = CLUTTER_PARAM_SPEC_FIXED (pspec); - fspec->minimum = COGL_FIXED_MIN; - fspec->maximum = COGL_FIXED_MAX; + fspec->minimum = CLUTTER_MAXFIXED; + fspec->maximum = CLUTTER_MINFIXED; fspec->default_value = 0; } @@ -268,7 +268,7 @@ param_fixed_validate (GParamSpec *pspec, GValue *value) { ClutterParamSpecFixed *fspec = CLUTTER_PARAM_SPEC_FIXED (pspec); - gint oval = COGL_FIXED_TO_INT (value->data[0].v_int); + gint oval = (value->data[0].v_int); gint min, max, val; g_assert (CLUTTER_IS_PARAM_SPEC_FIXED (pspec)); @@ -279,7 +279,7 @@ param_fixed_validate (GParamSpec *pspec, min = fspec->minimum; max = fspec->maximum; - val = COGL_FIXED_TO_INT (value->data[0].v_int); + val = (value->data[0].v_int); val = CLAMP (val, min, max); if (val != oval) diff --git a/clutter/clutter-fixed.h b/clutter/clutter-fixed.h index 3ae0916df..61e2fd4be 100644 --- a/clutter/clutter-fixed.h +++ b/clutter/clutter-fixed.h @@ -39,126 +39,118 @@ G_BEGIN_DECLS * * Fixed point number (16.16) */ -typedef CoglFixed ClutterFixed; +typedef float ClutterFixed; /** * ClutterAngle: * - * Integer representation of an angle such that 1024 corresponds to - * full circle (i.e., 2*Pi). + * An abstract representation of an angle. */ -typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ +typedef float ClutterAngle; -#define CLUTTER_ANGLE_FROM_DEG(x) (COGL_ANGLE_FROM_DEG (x)) -#define CLUTTER_ANGLE_FROM_DEGX(x) (COGL_ANGLE_FROM_DEGX (x)) -#define CLUTTER_ANGLE_TO_DEG(x) (COGL_ANGLE_TO_DEG (x)) -#define CLUTTER_ANGLE_TO_DEGX(x) (COGL_ANGLE_TO_DEGX (x)) +#define CLUTTER_ANGLE_FROM_DEG(x) ((float)(x)) +#define CLUTTER_ANGLE_FROM_DEGX(x) (CLUTTER_FIXED_TO_FLOAT (x)) +#define CLUTTER_ANGLE_TO_DEG(x) ((float)(x)) +#define CLUTTER_ANGLE_TO_DEGX(x) (CLUTTER_FLOAT_TO_FIXED (x)) /* * some commonly used constants */ -/** - * CFX_Q: - * - * Size in bits of decimal part of floating point value. - */ -#define CFX_Q COGL_FIXED_Q - /** * CFX_ONE: * * 1.0 represented as a fixed point value. */ -#define CFX_ONE COGL_FIXED_1 +#define CFX_ONE 1.0 /** * CFX_HALF: * * 0.5 represented as a fixed point value. */ -#define CFX_HALF COGL_FIXED_0_5 +#define CFX_HALF 0.5 /** * CFX_MAX: * * Maximum fixed point value. */ -#define CFX_MAX COGL_FIXED_MAX +#define CFX_MAX G_MAXFLOAT /** * CFX_MIN: * * Minimum fixed point value. */ -#define CFX_MIN COGL_FIXED_MIN +#define CFX_MIN (-G_MAXFLOAT) /** * CFX_PI: * * Fixed point representation of Pi */ -#define CFX_PI COGL_FIXED_PI +#define CFX_PI G_PI /** * CFX_2PI: * * Fixed point representation of Pi*2 */ -#define CFX_2PI COGL_FIXED_2_PI +#define CFX_2PI (G_PI * 2) /** * CFX_PI_2: * * Fixed point representation of Pi/2 */ -#define CFX_PI_2 COGL_FIXED_PI_2 +#define CFX_PI_2 (G_PI / 2) /** * CFX_PI_4: * * Fixed point representation of Pi/4 */ -#define CFX_PI_4 COGL_FIXED_PI_4 +#define CFX_PI_4 (G_PI / 4) /** * CFX_360: * * Fixed point representation of the number 360 */ -#define CFX_360 COGL_FIXED_360 +#define CFX_360 360.0 /** * CFX_240: * * Fixed point representation of the number 240 */ -#define CFX_240 COGL_FIXED_240 +#define CFX_240 240.0 /** * CFX_180: * * Fixed point representation of the number 180 */ -#define CFX_180 COGL_FIXED_180 +#define CFX_180 180.0 /** * CFX_120: * * Fixed point representation of the number 120 */ -#define CFX_120 COGL_FIXED_120 +#define CFX_120 120.0 /** * CFX_60: * * Fixed point representation of the number 60 */ -#define CFX_60 COGL_FIXED_60 +#define CFX_60 60.0 /** * CFX_RADIANS_TO_DEGREES: * * Fixed point representation of the number 180 / pi */ -#define CFX_RADIANS_TO_DEGREES COGL_RADIANS_TO_DEGREES +#define CFX_RADIANS_TO_DEGREES (180.0 / G_PI) /** * CFX_255: * * Fixed point representation of the number 255 */ -#define CFX_255 COGL_FIXED_255 +#define CFX_255 255.0 /** * CLUTTER_FIXED_TO_FLOAT: @@ -166,7 +158,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Convert a fixed point value to float. */ -#define CLUTTER_FIXED_TO_FLOAT(x) COGL_FIXED_TO_FLOAT ((x)) +#define CLUTTER_FIXED_TO_FLOAT(x) (x) /** * CLUTTER_FIXED_TO_DOUBLE: @@ -174,7 +166,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Convert a fixed point value to double. */ -#define CLUTTER_FIXED_TO_DOUBLE(x) COGL_FIXED_TO_DOUBLE ((x)) +#define CLUTTER_FIXED_TO_DOUBLE(x) ((double)(x)) /** * CLUTTER_FLOAT_TO_FIXED: @@ -182,7 +174,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Convert a float value to fixed. */ -#define CLUTTER_FLOAT_TO_FIXED(x) COGL_FIXED_FROM_FLOAT ((x)) +#define CLUTTER_FLOAT_TO_FIXED(x) ((x)) /** * CLUTTER_FLOAT_TO_INT: @@ -190,7 +182,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Convert a float value to int. */ -#define CLUTTER_FLOAT_TO_INT(x) COGL_FLOAT_TO_INT ((x)) +#define CLUTTER_FLOAT_TO_INT(x) ((int)(x)) /** * CLUTTER_FLOAT_TO_UINT: @@ -198,7 +190,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Convert a float value to unsigned int. */ -#define CLUTTER_FLOAT_TO_UINT(x) COGL_FLOAT_TO_UINT ((x)) +#define CLUTTER_FLOAT_TO_UINT(x) ((unsigned int)(x)) /** * CLUTTER_INT_TO_FIXED: @@ -206,7 +198,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Convert an integer value to fixed point. */ -#define CLUTTER_INT_TO_FIXED(x) COGL_FIXED_FROM_INT ((x)) +#define CLUTTER_INT_TO_FIXED(x) ((float)(x)) /** * CLUTTER_FIXED_TO_INT: @@ -216,7 +208,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Since: 0.6 */ -#define CLUTTER_FIXED_TO_INT(x) COGL_FIXED_TO_INT ((x)) +#define CLUTTER_FIXED_TO_INT(x) ((int)(x)) /** * CLUTTER_FIXED_FRACTION: @@ -224,7 +216,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Retrieves the fractionary part of a fixed point value */ -#define CLUTTER_FIXED_FRACTION(x) COGL_FIXED_FRACTION ((x)) +#define CLUTTER_FIXED_FRACTION(x) ((x)-floorf (x)) /** * CLUTTER_FIXED_FLOOR: @@ -232,7 +224,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Round down a fixed point value to an integer. */ -#define CLUTTER_FIXED_FLOOR(x) COGL_FIXED_FLOOR ((x)) +#define CLUTTER_FIXED_FLOOR(x) (floorf (x)) /** * CLUTTER_FIXED_CEIL: @@ -240,7 +232,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Round up a fixed point value to an integer. */ -#define CLUTTER_FIXED_CEIL(x) COGL_FIXED_CEIL ((x)) +#define CLUTTER_FIXED_CEIL(x) (ceilf (x)) /** * CLUTTER_FIXED_MUL: @@ -249,7 +241,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Multiply two fixed point values */ -#define CLUTTER_FIXED_MUL(x,y) COGL_FIXED_MUL ((x), (y)) +#define CLUTTER_FIXED_MUL(x,y) ((x) * (y)) /** * CLUTTER_FIXED_DIV: @@ -258,54 +250,16 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */ * * Divide two fixed point values */ -#define CLUTTER_FIXED_DIV(x,y) COGL_FIXED_DIV ((x), (y)) +#define CLUTTER_FIXED_DIV(x,y) ((x) / (y)) -#define clutter_qmulx(x,y) cogl_fixed_mul ((x), (y)) -#define clutter_qdivx(x,y) cogl_fixed_div ((x), (y)) +#define clutter_qmulx(x,y) ((x) * (y)) +#define clutter_qdivx(x,y) ((x) / (y)) -#define clutter_sinx(a) cogl_fixed_sin ((a)) -#define clutter_sini(a) cogl_angle_sin ((a)) -#define clutter_tani(a) cogl_angle_tan ((a)) -#define clutter_atani(a) cogl_fixed_atan ((a)) -#define clutter_atan2i(x,y) cogl_fixed_atan2 ((x), (y)) -#define clutter_cosx(a) cogl_fixed_cos ((a)) -#define clutter_cosi(a) cogl_angle_cos ((a)) - -/** - * CLUTTER_SQRTI_ARG_MAX - * - * Maximum argument that can be passed to #clutter_sqrti function. - * - * Since: 0.6 - */ -#define CLUTTER_SQRTI_ARG_MAX COGL_SQRTI_ARG_MAX - -/** - * CLUTTER_SQRTI_ARG_5_PERCENT - * - * Maximum argument that can be passed to #clutter_sqrti for which the - * resulting error is < 5% - * - * Since: 0.6 - */ -#define CLUTTER_SQRTI_ARG_5_PERCENT COGL_SQRTI_ARG_5_PERCENT - -/** - * CLUTTER_SQRTI_ARG_10_PERCENT - * - * Maximum argument that can be passed to #clutter_sqrti for which the - * resulting error is < 10% - * - * Since: 0.6 - */ -#define CLUTTER_SQRTI_ARG_10_PERCENT COGL_SQRTI_ARG_10_PERCENT - -#define clutter_sqrtx(x) cogl_fixed_sqrt ((x)) -#define clutter_sqrti(x) cogl_sqrti ((x)) - -#define clutter_log2x(x) cogl_fixed_log2 ((x)) -#define clutter_pow2x(x) cogl_fixed_pow2 ((x)) -#define clutter_powx(x,y) cogl_fixed_pow ((x), (y)) +#define clutter_sinx(a) sinf (a * (G_PI/180.0)) +#define clutter_tanx(a) tanf (a * (G_PI/180.0)) +#define clutter_atanx(a) atanf (a * (G_PI/180.0)) +#define clutter_atan2x(x,y) atan2f (x, y) +#define clutter_cosx(a) cosf (a * (G_PI/180.0)) #define CLUTTER_TYPE_FIXED (clutter_fixed_get_type ()) #define CLUTTER_TYPE_PARAM_FIXED (clutter_param_fixed_get_type ()) @@ -331,7 +285,7 @@ typedef struct _ClutterParamSpecFixed ClutterParamSpecFixed; * * Since: 0.8 */ -#define CLUTTER_MAXFIXED COGL_FIXED_MAX +#define CLUTTER_MAXFIXED G_MAXFLOAT /** * CLUTTER_MINFIXED: @@ -340,7 +294,7 @@ typedef struct _ClutterParamSpecFixed ClutterParamSpecFixed; * * Since: 0.8 */ -#define CLUTTER_MINFIXED COGL_FIXED_MIN +#define CLUTTER_MINFIXED (-G_MAXFLOAT) /** * ClutterParamSpecFixed diff --git a/clutter/clutter-interval.c b/clutter/clutter-interval.c index 5f2924d09..ea98ce113 100644 --- a/clutter/clutter-interval.c +++ b/clutter/clutter-interval.c @@ -57,9 +57,18 @@ #include #include +#include "clutter-color.h" +#include "clutter-fixed.h" #include "clutter-interval.h" #include "clutter-units.h" -#include "clutter-fixed.h" + +typedef struct +{ + GType value_type; + ClutterProgressFunc func; +} ProgressData; + +static GHashTable *progress_funcs = NULL; enum { @@ -171,19 +180,39 @@ clutter_interval_real_validate (ClutterInterval *interval, return TRUE; } -static void +static gboolean clutter_interval_real_compute_value (ClutterInterval *interval, gdouble factor, GValue *value) { GValue *initial, *final; GType value_type; + gboolean retval = FALSE; initial = clutter_interval_peek_initial_value (interval); final = clutter_interval_peek_final_value (interval); value_type = clutter_interval_get_value_type (interval); + if (G_UNLIKELY (progress_funcs != NULL)) + { + ProgressData *p_data; + + p_data = + g_hash_table_lookup (progress_funcs, GUINT_TO_POINTER (value_type)); + + /* if we have a progress function, and that function was + * successful in computing the progress, then we bail out + * as fast as we can + */ + if (p_data != NULL) + { + retval = p_data->func (initial, final, factor, value); + if (retval) + return retval; + } + } + switch (G_TYPE_FUNDAMENTAL (value_type)) { case G_TYPE_INT: @@ -196,6 +225,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, res = (factor * (ib - ia)) + ia; g_value_set_int (value, res); + + retval = TRUE; } break; @@ -209,6 +240,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, res = (factor * (ib - (gdouble) ia)) + ia; g_value_set_uint (value, res); + + retval = TRUE; } break; @@ -222,6 +255,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval, res = (factor * (ib - (gdouble) ia)) + ia; g_value_set_uchar (value, res); + + retval = TRUE; } break; @@ -239,19 +274,45 @@ clutter_interval_real_compute_value (ClutterInterval *interval, g_value_set_double (value, res); else g_value_set_float (value, res); + + retval = TRUE; } break; case G_TYPE_BOOLEAN: - if (COGL_FIXED_FROM_FLOAT (factor) > COGL_FIXED_0_5) + if (CLUTTER_FLOAT_TO_FIXED (factor) > 0.5) g_value_set_boolean (value, TRUE); else g_value_set_boolean (value, FALSE); + + retval = TRUE; + break; + + case G_TYPE_BOXED: + if (value_type == CLUTTER_TYPE_COLOR) + { + const ClutterColor *ia, *ib; + ClutterColor res = { 0, }; + + ia = clutter_value_get_color (initial); + ib = clutter_value_get_color (final); + + res.red = (factor * (ib->red - (gdouble) ia->red)) + ia->red; + res.green = (factor * (ib->green - (gdouble) ia->green)) + ia->green; + res.blue = (factor * (ib->blue - (gdouble) ia->blue)) + ia->blue; + res.alpha = (factor * (ib->alpha - (gdouble) ia->alpha)) + ia->alpha; + + clutter_value_set_color (value, &res); + + retval = TRUE; + } break; default: break; } + + return retval; } static void @@ -818,19 +879,99 @@ clutter_interval_validate (ClutterInterval *interval, * Computes the value between the @interval boundaries given the * progress @factor and puts it into @value. * + * Return value: %TRUE if the operation was successful + * * Since: 1.0 */ -void +gboolean clutter_interval_compute_value (ClutterInterval *interval, gdouble factor, GValue *value) { - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - g_return_if_fail (value != NULL); + g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); + g_return_val_if_fail (value != NULL, FALSE); factor = CLAMP (factor, 0.0, 1.0); - CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, - factor, - value); + return CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, + factor, + value); +} + +/** + * clutter_interval_register_progress_func: + * @value_type: a #GType + * @func: a #ClutterProgressFunc, or %NULL to unset a previously + * set progress function + * + * Sets the progress function for a given @value_type, like: + * + * |[ + * clutter_interval_register_progress_func (MY_TYPE_FOO, + * my_foo_progress); + * ]| + * + * Whenever a #ClutterInterval instance using the default + * #ClutterInterval::compute_value implementation is set as an + * interval between two #GValue of type @value_type, it will call + * @func to establish the value depending on the given progress, + * for instance: + * + * |[ + * static gboolean + * my_int_progress (const GValue *a, + * const GValue *b, + * gdouble progress, + * GValue *retval) + * { + * gint ia = g_value_get_int (a); + * gint ib = g_value_get_int (b); + * gint res = factor * (ib - ia) + ia; + * + * g_value_set_int (retval, res); + * + * return TRUE; + * } + * + * clutter_interval_register_progress_func (G_TYPE_INT, my_int_progress); + * ]| + * + * To unset a previously set progress function of a #GType, pass %NULL + * for @func. + * + * Since: 1.0 + */ +void +clutter_interval_register_progress_func (GType value_type, + ClutterProgressFunc func) +{ + ProgressData *progress_func; + + g_return_if_fail (value_type != G_TYPE_INVALID); + + if (G_UNLIKELY (progress_funcs == NULL)) + progress_funcs = g_hash_table_new (NULL, NULL); + + progress_func = + g_hash_table_lookup (progress_funcs, GUINT_TO_POINTER (value_type)); + if (G_UNLIKELY (progress_func)) + { + if (func == NULL) + { + g_hash_table_remove (progress_funcs, GUINT_TO_POINTER (value_type)); + g_slice_free (ProgressData, progress_func); + } + else + progress_func->func = func; + } + else + { + progress_func = g_slice_new (ProgressData); + progress_func->value_type = value_type; + progress_func->func = func; + + g_hash_table_replace (progress_funcs, + GUINT_TO_POINTER (value_type), + progress_func); + } } diff --git a/clutter/clutter-interval.h b/clutter/clutter-interval.h index 56d155f28..72ae5304c 100644 --- a/clutter/clutter-interval.h +++ b/clutter/clutter-interval.h @@ -44,6 +44,34 @@ typedef struct _ClutterInterval ClutterInterval; typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate; typedef struct _ClutterIntervalClass ClutterIntervalClass; +/** + * ClutterProgressFunc: + * @a: the initial value of an interval + * @b: the final value of an interval + * @progress: the progress factor, between 0 and 1 + * @retval: the value used to store the progress + * + * Prototype of the progress function used to compute the value + * between the two ends @a and @b of an interval depending on + * the value of @progress. + * + * The #GValue in @retval is already initialized with the same + * type as @a and @b. + * + * This function will be called by #ClutterInterval if the + * type of the values of the interval was registered using + * clutter_interval_register_progress_func(). + * + * Return value: %TRUE if the function successfully computed + * the value and stored it inside @retval + * + * Since: 1.0 + */ +typedef gboolean (* ClutterProgressFunc) (const GValue *a, + const GValue *b, + gdouble progress, + GValue *retval); + /** * ClutterInterval: * @@ -79,7 +107,7 @@ struct _ClutterIntervalClass /*< public >*/ gboolean (* validate) (ClutterInterval *interval, GParamSpec *pspec); - void (* compute_value) (ClutterInterval *interval, + gboolean (* compute_value) (ClutterInterval *interval, gdouble factor, GValue *value); @@ -122,10 +150,13 @@ void clutter_interval_get_interval (ClutterInterval *interval, gboolean clutter_interval_validate (ClutterInterval *interval, GParamSpec *pspec); -void clutter_interval_compute_value (ClutterInterval *interval, +gboolean clutter_interval_compute_value (ClutterInterval *interval, gdouble factor, GValue *value); +void clutter_interval_register_progress_func (GType value_type, + ClutterProgressFunc func); + G_END_DECLS #endif /* __CLUTTER_INTERVAL_H__ */ diff --git a/clutter/clutter-media.c b/clutter/clutter-media.c index 17494f59c..a0ab6d5aa 100644 --- a/clutter/clutter-media.c +++ b/clutter/clutter-media.c @@ -3,9 +3,11 @@ * * An OpenGL based 'interactive canvas' library. * - * Authored By Matthew Allum + * Authored By: Matthew Allum + * Emmanuele Bassi * * Copyright (C) 2006 OpenedHand + * Copyright (C) 2009 Intel Corp. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,22 +20,20 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /** * SECTION:clutter-media - * @short_description: An interface for controlling playback of media data. + * @short_description: An interface for controlling playback of media data * * #ClutterMedia is an interface for controlling playback of media sources. * - * It is not implemented inside Clutter, but other integration libraries - * like Clutter-GStreamer, implement it to offer a uniform API for - * applications. + * Clutter core does not provide an implementation of this interface, but + * other integration libraries like Clutter-GStreamer implement it to offer + * a uniform API for applications. * - * ClutterMedia is available since Clutter 0.2 + * #ClutterMedia is available since Clutter 0.2 */ #ifdef HAVE_CONFIG_H @@ -53,118 +53,119 @@ enum LAST_SIGNAL }; -static void clutter_media_base_init (gpointer g_class); - static guint media_signals[LAST_SIGNAL] = { 0, }; -GType -clutter_media_get_type (void) -{ - static GType media_type = 0; - - if (!media_type) - { - static const GTypeInfo media_info = - { - sizeof (ClutterMediaInterface), - clutter_media_base_init, - NULL, - }; - - media_type = g_type_register_static (G_TYPE_INTERFACE, "ClutterMedia", - &media_info, 0); - } - - return media_type; -} - static void clutter_media_base_init (gpointer g_iface) { - static gboolean initialized = FALSE; + static gboolean was_initialized = FALSE; - if (G_UNLIKELY (!initialized)) + if (G_UNLIKELY (!was_initialized)) { - initialized = TRUE; + GParamSpec *pspec = NULL; - /* props */ + was_initialized = TRUE; - g_object_interface_install_property - (g_iface, - g_param_spec_string - ("uri", - "URI", - "The loaded URI.", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:uri: + * + * The location of a media file, expressed as a valid URI. + * + * Since: 0.2 + */ + pspec = g_param_spec_string ("uri", + "URI", + "URI of a media file", + NULL, + CLUTTER_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); - g_object_interface_install_property - (g_iface, - g_param_spec_boolean - ("playing", - "Playing", - "TRUE if playing.", - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:playing: + * + * Whether the #ClutterMedia actor is playing. + * + * Since: 0.2 + */ + pspec = g_param_spec_boolean ("playing", + "Playing", + "Wheter the actor is playing", + FALSE, + CLUTTER_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); - g_object_interface_install_property - (g_iface, - g_param_spec_int - ("position", - "Position", - "The position in the current stream in seconds.", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:progress: + * + * The current progress of the playback, as a normalized + * value between 0.0 and 1.0. + * + * Since: 1.0 + */ + pspec = g_param_spec_double ("progress", + "Progress", + "Current progress of the playback", + 0.0, 1.0, 0.0, + CLUTTER_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); - g_object_interface_install_property - (g_iface, - g_param_spec_double - ("volume", - "Volume", - "The audio volume.", - 0, 100, 50, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:audio-volume: + * + * The volume of the audio, as a normalized value between + * 0.0 and 1.0. + * + * Since: 1.0 + */ + pspec = g_param_spec_double ("audio-volume", + "Audio Volume", + "The volume of the audio", + 0.0, 1.0, 0.5, + CLUTTER_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); - g_object_interface_install_property - (g_iface, - g_param_spec_boolean - ("can-seek", - "Can seek", - "TRUE if the current stream is seekable.", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:can-seek: + * + * Whether the current stream is seekable. + * + * Since: 0.2 + */ + pspec = g_param_spec_boolean ("can-seek", + "Can Seek", + "Whether the current stream is seekable", + FALSE, + CLUTTER_PARAM_READABLE); + g_object_interface_install_property (g_iface, pspec); - g_object_interface_install_property - (g_iface, - g_param_spec_int - ("buffer-percent", - "Buffer percent", - "The percentage the current stream buffer is filled.", - 0, 100, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:buffer-fill: + * + * The fill level of the buffer for the current stream, + * as a value between 0.0 and 1.0. + * + * Since: 1.0 + */ + pspec = g_param_spec_double ("buffer-fill", + "Buffer Fill", + "The fill level of the buffer", + 0.0, 1.0, 0.0, + CLUTTER_PARAM_READABLE); + g_object_interface_install_property (g_iface, pspec); - g_object_interface_install_property - (g_iface, - g_param_spec_int - ("duration", - "Duration", - "The duration of the current stream in seconds.", - 0, G_MAXINT, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); + /** + * ClutterMedia:duration: + * + * The duration of the current stream, in seconds + * + * Since: 0.2 + */ + pspec = g_param_spec_uint ("duration", + "Duration", + "The duration of the stream, in seconds", + 0, G_MAXUINT, 0, + CLUTTER_PARAM_READABLE); + g_object_interface_install_property (g_iface, pspec); /** * ClutterMedia::eos: @@ -178,7 +179,7 @@ clutter_media_base_init (gpointer g_iface) g_signal_new ("eos", CLUTTER_TYPE_MEDIA, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaInterface, eos), + G_STRUCT_OFFSET (ClutterMediaIface, eos), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -195,7 +196,7 @@ clutter_media_base_init (gpointer g_iface) g_signal_new ("error", CLUTTER_TYPE_MEDIA, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaInterface, error), + G_STRUCT_OFFSET (ClutterMediaIface, error), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -203,10 +204,32 @@ clutter_media_base_init (gpointer g_iface) } } + +GType +clutter_media_get_type (void) +{ + static GType media_type = 0; + + if (G_UNLIKELY (media_type == 0)) + { + const GTypeInfo media_info = { + sizeof (ClutterMediaIface), /* class size */ + clutter_media_base_init, /* base_init */ + NULL, /* base_finalize */ + }; + + media_type = g_type_register_static (G_TYPE_INTERFACE, + I_("ClutterMedia"), + &media_info, 0); + } + + return media_type; +} + /** * clutter_media_set_uri: - * @media: #ClutterMedia object - * @uri: URI + * @media: a #ClutterMedia + * @uri: the URI of the media stream * * Sets the URI of @media to @uri. * @@ -214,37 +237,42 @@ clutter_media_base_init (gpointer g_iface) */ void clutter_media_set_uri (ClutterMedia *media, - const char *uri) + const gchar *uri) { g_return_if_fail (CLUTTER_IS_MEDIA(media)); - CLUTTER_MEDIA_GET_INTERFACE (media)->set_uri (media, uri); + g_object_set (G_OBJECT (media), "uri", uri, NULL); } /** * clutter_media_get_uri: - * @media: A #ClutterMedia object + * @media: a #ClutterMedia * * Retrieves the URI from @media. * - * Return value: The URI as a string. + * Return value: the URI of the media stream. Use g_free() + * to free the returned string * * Since: 0.2 */ -const char* +gchar * clutter_media_get_uri (ClutterMedia *media) { + gchar *retval = NULL; + g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL); - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_uri (media); + g_object_get (G_OBJECT (media), "uri", &retval, NULL); + + return retval; } /** * clutter_media_set_playing: - * @media: A #ClutterMedia object - * @playing: TRUE to start playing, FALSE to stop. + * @media: a #ClutterMedia + * @playing: %TRUE to start playing * - * Starts or stops @media playing. + * Starts or stops playing of @media. * * Since: 0.2 */ @@ -254,7 +282,7 @@ clutter_media_set_playing (ClutterMedia *media, { g_return_if_fail (CLUTTER_IS_MEDIA(media)); - CLUTTER_MEDIA_GET_INTERFACE (media)->set_playing (media, playing); + g_object_set (G_OBJECT (media), "playing", playing, NULL); } /** @@ -270,86 +298,99 @@ clutter_media_set_playing (ClutterMedia *media, gboolean clutter_media_get_playing (ClutterMedia *media) { - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), FALSE); + gboolean is_playing = FALSE; - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_playing (media); + g_return_val_if_fail (CLUTTER_IS_MEDIA (media), FALSE); + + g_object_get (G_OBJECT (media), "playing", &is_playing, NULL); + + return is_playing; } /** - * clutter_media_set_position: - * @media: A #ClutterMedia object - * @position: The desired position. + * clutter_media_set_progress: + * @media: a #ClutterMedia + * @progress: the progress of the playback, between 0.0 and 1.0 * - * Sets the playback position of @media to @position. + * Sets the playback progress of @media. The @progress is + * a normalized value between 0.0 (begin) and 1.0 (end). * - * Since: 0.2 + * Since: 1.0 */ void -clutter_media_set_position (ClutterMedia *media, - int position) +clutter_media_set_progress (ClutterMedia *media, + gdouble progress) { - g_return_if_fail (CLUTTER_IS_MEDIA(media)); + g_return_if_fail (CLUTTER_IS_MEDIA (media)); - CLUTTER_MEDIA_GET_INTERFACE (media)->set_position (media, position); + g_object_set (G_OBJECT (media), "progress", progress, NULL); } /** - * clutter_media_get_position: - * @media: A #ClutterMedia object + * clutter_media_get_progress: + * @media: a #ClutterMedia * - * Retrieves the position of @media. + * Retrieves the playback progress of @media. * - * Return value: The playback position. + * Return value: the playback progress, between 0.0 and 1.0 * - * Since: 0.2 + * Since: 1.0 */ -int -clutter_media_get_position (ClutterMedia *media) +gdouble +clutter_media_get_progress (ClutterMedia *media) { - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); + gdouble retval = 0.0; - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_position (media); + g_return_val_if_fail (CLUTTER_IS_MEDIA (media), 0); + + g_object_get (G_OBJECT (media), "progress", &retval, NULL); + + return retval; } /** - * clutter_media_set_volume: - * @media: A #ClutterMedia object - * @volume: The volume as a double between 0.0 and 1.0 + * clutter_media_set_audio_volume: + * @media: a #ClutterMedia + * @volume: the volume as a double between 0.0 and 1.0 * * Sets the playback volume of @media to @volume. * - * Since: 0.2 + * Since: 1.0 */ void -clutter_media_set_volume (ClutterMedia *media, - double volume) +clutter_media_set_audio_volume (ClutterMedia *media, + gdouble volume) { g_return_if_fail (CLUTTER_IS_MEDIA(media)); - CLUTTER_MEDIA_GET_INTERFACE (media)->set_volume (media, volume); + g_object_set (G_OBJECT (media), "audio-volume", volume, NULL); } /** - * clutter_media_get_volume: - * @media: A #ClutterMedia object + * clutter_media_get_audio_volume: + * @media: a #ClutterMedia * * Retrieves the playback volume of @media. * * Return value: The playback volume between 0.0 and 1.0 * - * Since: 0.2 + * Since: 1.0 */ -double -clutter_media_get_volume (ClutterMedia *media) +gdouble +clutter_media_get_audio_volume (ClutterMedia *media) { - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0.0); + gdouble retval = 0.0; - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_volume (media); + g_return_val_if_fail (CLUTTER_IS_MEDIA (media), 0.0); + + g_object_get (G_OBJECT (media), "audio-volume", &retval, NULL); + + return retval; } /** * clutter_media_get_can_seek: - * @media: A #ClutterMedia object + * @media: a #ClutterMedia * * Retrieves whether @media is seekable or not. * @@ -360,55 +401,67 @@ clutter_media_get_volume (ClutterMedia *media) gboolean clutter_media_get_can_seek (ClutterMedia *media) { - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), FALSE); + gboolean retval = FALSE; - return CLUTTER_MEDIA_GET_INTERFACE (media)->can_seek (media); + g_return_val_if_fail (CLUTTER_IS_MEDIA (media), FALSE); + + g_object_get (G_OBJECT (media), "can-seek", &retval, NULL); + + return retval; } /** - * clutter_media_get_buffer_percent: - * @media: A #ClutterMedia object + * clutter_media_get_buffer_fill: + * @media: a #ClutterMedia * * Retrieves the amount of the stream that is buffered. * - * Return value: percentage value + * Return value: the fill level, between 0.0 and 1.0 * - * Since: 0.2 + * Since: 1.0 */ -int -clutter_media_get_buffer_percent (ClutterMedia *media) +gdouble +clutter_media_get_buffer_fill (ClutterMedia *media) { - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); + gdouble retval = 0.0; - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_buffer_percent (media); + g_return_val_if_fail (CLUTTER_IS_MEDIA (media), 0); + + g_object_get (G_OBJECT (media), "buffer-fill", &retval, NULL); + + return retval; } /** * clutter_media_get_duration: - * @media: A #ClutterMedia object + * @media: a #ClutterMedia * * Retrieves the duration of the media stream that @media represents. * - * Return value: The length of the media stream. + * Return value: the duration of the media stream, in seconds * * Since: 0.2 */ -int +guint clutter_media_get_duration (ClutterMedia *media) { + guint retval = 0; + g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_duration (media); + g_object_get (G_OBJECT (media), "duration", &retval, NULL); + + return retval; } /* helper funcs */ /** * clutter_media_set_filename: - * @media: A #ClutterMedia object - * @filename: A filename to media file. + * @media: a #ClutterMedia + * @filename: A filename * - * Sets the filename of the media source. + * Sets the source of @media using a file path. * * Since: 0.2 */ diff --git a/clutter/clutter-media.h b/clutter/clutter-media.h index f930e3f49..6c71c9c75 100644 --- a/clutter/clutter-media.h +++ b/clutter/clutter-media.h @@ -3,9 +3,11 @@ * * An OpenGL based 'interactive canvas' library. * - * Authored By Matthew Allum + * Authored By: Matthew Allum + * Emmanuele Bassi * * Copyright (C) 2006 OpenedHand + * Copyright (C) 2009 Intel Corp. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,79 +39,40 @@ G_BEGIN_DECLS #define CLUTTER_IS_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MEDIA)) #define CLUTTER_MEDIA_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_MEDIA, ClutterMediaInterface)) -typedef struct _ClutterMedia ClutterMedia; /* dummy typedef */ -typedef struct _ClutterMediaInterface ClutterMediaInterface; +typedef struct _ClutterMedia ClutterMedia; /* dummy typedef */ +typedef struct _ClutterMediaIface ClutterMediaIface; -struct _ClutterMediaInterface +struct _ClutterMediaIface { /*< private >*/ - GTypeInterface base_iface; - - /*< public >*/ - void (*set_uri) (ClutterMedia *media, - const char *uri); - const char *(*get_uri) (ClutterMedia *media); - void (*set_playing) (ClutterMedia *media, - gboolean playing); - gboolean (*get_playing) (ClutterMedia *media); - void (*set_position) (ClutterMedia *media, - int position); - int (*get_position) (ClutterMedia *media); - void (*set_volume) (ClutterMedia *media, - double volume); - double (*get_volume) (ClutterMedia *media); - gboolean (*can_seek) (ClutterMedia *media); - int (*get_buffer_percent) (ClutterMedia *media); - int (*get_duration) (ClutterMedia *media); + GTypeInterface base_iface; /* signals */ - void (* eos) (ClutterMedia *media); - void (* error) (ClutterMedia *media, - GError *error); + void (* eos) (ClutterMedia *media); + void (* error) (ClutterMedia *media, + const GError *error); }; +GType clutter_media_get_type (void) G_GNUC_CONST; -GType clutter_media_get_type (void) G_GNUC_CONST; +void clutter_media_set_uri (ClutterMedia *media, + const gchar *uri); +gchar * clutter_media_get_uri (ClutterMedia *media); +void clutter_media_set_filename (ClutterMedia *media, + const gchar *filename); -void -clutter_media_set_uri (ClutterMedia *media, - const char *uri); -const char * -clutter_media_get_uri (ClutterMedia *media); - -void -clutter_media_set_playing (ClutterMedia *media, - gboolean playing); - -gboolean -clutter_media_get_playing (ClutterMedia *media); - -void -clutter_media_set_position (ClutterMedia *media, - int position); - -int -clutter_media_get_position (ClutterMedia *media); - -void -clutter_media_set_volume (ClutterMedia *media, - double volume); - -double -clutter_media_get_volume (ClutterMedia *media); - -gboolean -clutter_media_get_can_seek (ClutterMedia *media); - -int -clutter_media_get_buffer_percent (ClutterMedia *media); - -int -clutter_media_get_duration (ClutterMedia *media); - -void -clutter_media_set_filename (ClutterMedia *media, - const gchar *filename); +void clutter_media_set_playing (ClutterMedia *media, + gboolean playing); +gboolean clutter_media_get_playing (ClutterMedia *media); +void clutter_media_set_progress (ClutterMedia *media, + gdouble progress); +gdouble clutter_media_get_progress (ClutterMedia *media); +void clutter_media_set_audio_volume (ClutterMedia *media, + gdouble volume); +gdouble clutter_media_get_audio_volume (ClutterMedia *media); +gboolean clutter_media_get_can_seek (ClutterMedia *media); +gdouble clutter_media_get_buffer_fill (ClutterMedia *media); +guint clutter_media_get_duration (ClutterMedia *media); G_END_DECLS diff --git a/clutter/clutter-path.c b/clutter/clutter-path.c index 6f9340249..c459cdf9f 100644 --- a/clutter/clutter-path.c +++ b/clutter/clutter-path.c @@ -1217,11 +1217,11 @@ clutter_path_node_distance (const ClutterKnot *start, * If we are using limited precision sqrti implementation, fallback on * clib sqrt if the precission would be less than 10% */ -#if INT_MAX > CLUTTER_SQRTI_ARG_10_PERCENT +#if INT_MAX > COGL_SQRTI_ARG_10_PERCENT if (t <= COGL_SQRTI_ARG_10_PERCENT) return cogl_sqrti (t); else - return COGL_FLOAT_TO_INT (sqrt(t)); + return COGL_FLOAT_TO_INT (sqrtf(t)); #else return cogl_sqrti (t); #endif diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index c65bfb066..d6f7d11f2 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -194,6 +194,8 @@ void _clutter_backend_init_events (ClutterBackend *backend); ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend); +ClutterUnit _clutter_backend_get_units_per_em (ClutterBackend *backend); + void _clutter_feature_init (void); /* Picking code */ diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 6a4e850b8..0d5834730 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -769,7 +769,7 @@ clutter_stage_class_init (ClutterStageClass *klass) stage_signals[QUEUE_REDRAW] = g_signal_new (I_("queue-redraw"), G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_FIRST, + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterStageClass, queue_redraw), NULL, NULL, clutter_marshal_VOID__VOID, @@ -815,15 +815,15 @@ clutter_stage_init (ClutterStage *self) priv->color = default_stage_color; - priv->perspective.fovy = COGL_FIXED_60; /* 60 Degrees */ - priv->perspective.aspect = COGL_FIXED_1; - priv->perspective.z_near = COGL_FIXED_FROM_FLOAT (0.1); - priv->perspective.z_far = COGL_FIXED_FROM_FLOAT (100.0); + priv->perspective.fovy = 60.0; /* 60 Degrees */ + priv->perspective.aspect = 1.0; + priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (0.1); + priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (100.0); /* depth cueing */ - priv->fog.density = COGL_FIXED_FROM_FLOAT (0.1); - priv->fog.z_near = COGL_FIXED_FROM_FLOAT (1.0); - priv->fog.z_far = COGL_FIXED_FROM_FLOAT (2.0); + priv->fog.density = CLUTTER_FLOAT_TO_FIXED (0.1); + priv->fog.z_near = CLUTTER_FLOAT_TO_FIXED (1.0); + priv->fog.z_far = CLUTTER_FLOAT_TO_FIXED (2.0); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); clutter_stage_set_key_focus (self, NULL); @@ -979,10 +979,10 @@ clutter_stage_set_perspective (ClutterStage *stage, priv = stage->priv; - priv->perspective.fovy = COGL_FIXED_FROM_FLOAT (fovy); - priv->perspective.aspect = COGL_FIXED_FROM_FLOAT (aspect); - priv->perspective.z_near = COGL_FIXED_FROM_FLOAT (z_near); - priv->perspective.z_far = COGL_FIXED_FROM_FLOAT (z_far); + priv->perspective.fovy = CLUTTER_FLOAT_TO_FIXED (fovy); + priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED (aspect); + priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (z_near); + priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (z_far); /* this will cause the viewport to be reset; see * clutter_maybe_setup_viewport() inside clutter-main.c @@ -1018,16 +1018,16 @@ clutter_stage_get_perspective (ClutterStage *stage, priv = stage->priv; if (fovy) - *fovy = COGL_FIXED_TO_FLOAT (priv->perspective.fovy); + *fovy = CLUTTER_FIXED_TO_FLOAT (priv->perspective.fovy); if (aspect) - *aspect = COGL_FIXED_TO_FLOAT (priv->perspective.aspect); + *aspect = CLUTTER_FIXED_TO_FLOAT (priv->perspective.aspect); if (z_near) - *z_near = COGL_FIXED_TO_FLOAT (priv->perspective.z_near); + *z_near = CLUTTER_FIXED_TO_FLOAT (priv->perspective.z_near); if (z_far) - *z_far = COGL_FIXED_TO_FLOAT (priv->perspective.z_far); + *z_far = CLUTTER_FIXED_TO_FLOAT (priv->perspective.z_far); } /** @@ -1627,11 +1627,11 @@ clutter_stage_get_fog (ClutterStage *stage, priv = stage->priv; if (density) - *density = COGL_FIXED_TO_FLOAT (priv->fog.density); + *density = CLUTTER_FIXED_TO_FLOAT (priv->fog.density); if (z_near) - *z_near = COGL_FIXED_TO_FLOAT (priv->fog.z_near); + *z_near = CLUTTER_FIXED_TO_FLOAT (priv->fog.z_near); if (z_far) - *z_far = COGL_FIXED_TO_FLOAT (priv->fog.z_far); + *z_far = CLUTTER_FIXED_TO_FLOAT (priv->fog.z_far); } /** @@ -1663,9 +1663,9 @@ clutter_stage_set_fog (ClutterStage *stage, priv = stage->priv; - priv->fog.density = COGL_FIXED_FROM_FLOAT (density); - priv->fog.z_near = COGL_FIXED_FROM_FLOAT (z_near); - priv->fog.z_far = COGL_FIXED_FROM_FLOAT (z_far); + priv->fog.density = CLUTTER_FLOAT_TO_FIXED (density); + priv->fog.z_near = CLUTTER_FLOAT_TO_FIXED (z_near); + priv->fog.z_far = CLUTTER_FLOAT_TO_FIXED (z_far); if (priv->use_fog && CLUTTER_ACTOR_IS_VISIBLE (stage)) clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); @@ -1761,7 +1761,7 @@ clutter_stage_get_resolutionx (ClutterStage *stage) res = clutter_backend_get_resolution (context->backend); - return COGL_FIXED_FROM_FLOAT (res); + return CLUTTER_FLOAT_TO_FIXED (res); } /*** Perspective boxed type ******/ diff --git a/clutter/clutter-text.c b/clutter/clutter-text.c index 76721a6d2..94229694d 100644 --- a/clutter/clutter-text.c +++ b/clutter/clutter-text.c @@ -202,31 +202,16 @@ static gint offset_to_bytes (const gchar *text, gint pos) { - gchar *c = NULL; - gint i, j, len; + const gchar *ptr; if (pos < 0) return strlen (text); - c = g_utf8_next_char (text); - j = 1; - len = strlen (text); + /* Loop over each character in the string until we either reach the + end or the requested position */ + for (ptr = text; *ptr && pos-- > 0; ptr = g_utf8_next_char (ptr)); - for (i = 0; i < len; i++) - { - if (&text[i] == c) - { - if (j == pos) - break; - else - { - c = g_utf8_next_char (c); - j++; - } - } - } - - return i; + return ptr - text; } #define bytes_to_offset(t,p) (g_utf8_pointer_to_offset ((t), (t) + (p))) @@ -1017,7 +1002,9 @@ clutter_text_key_press (ClutterActor *actor, if (key_unichar == '\r') key_unichar = '\n'; - if (g_unichar_validate (key_unichar)) + if (key_unichar == '\n' || + (g_unichar_validate (key_unichar) && + !g_unichar_iscntrl (key_unichar))) { /* truncate the eventual selection so that the * Unicode character can replace it @@ -1291,7 +1278,7 @@ clutter_text_real_move_up (ClutterText *self, PangoLayoutLine *layout_line; PangoLayout *layout; gint line_no; - gint index_; + gint index_, trailing; gint x; layout = clutter_text_get_layout (self); @@ -1311,21 +1298,23 @@ clutter_text_real_move_up (ClutterText *self, if (priv->x_pos != -1) x = priv->x_pos; - else - priv->x_pos = x; layout_line = pango_layout_get_line_readonly (layout, line_no); if (!layout_line) return FALSE; - pango_layout_line_x_to_index (layout_line, x, &index_, NULL); + pango_layout_line_x_to_index (layout_line, x, &index_, &trailing); { gint pos = bytes_to_offset (priv->text, index_); - clutter_text_set_cursor_position (self, pos); + clutter_text_set_cursor_position (self, pos + trailing); } + /* Store the target x position to avoid drifting left and right when + moving the cursor up and down */ + priv->x_pos = x; + if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) clutter_text_clear_selection (self); @@ -1342,7 +1331,7 @@ clutter_text_real_move_down (ClutterText *self, PangoLayoutLine *layout_line; PangoLayout *layout; gint line_no; - gint index_; + gint index_, trailing; gint x; layout = clutter_text_get_layout (self); @@ -1358,21 +1347,23 @@ clutter_text_real_move_down (ClutterText *self, if (priv->x_pos != -1) x = priv->x_pos; - else - priv->x_pos = x; layout_line = pango_layout_get_line_readonly (layout, line_no + 1); if (!layout_line) return FALSE; - pango_layout_line_x_to_index (layout_line, x, &index_, NULL); + pango_layout_line_x_to_index (layout_line, x, &index_, &trailing); { gint pos = bytes_to_offset (priv->text, index_); - clutter_text_set_cursor_position (self, pos); + clutter_text_set_cursor_position (self, pos + trailing); } + /* Store the target x position to avoid drifting left and right when + moving the cursor up and down */ + priv->x_pos = x; + if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK))) clutter_text_clear_selection (self); @@ -3314,6 +3305,10 @@ clutter_text_set_cursor_position (ClutterText *self, else priv->position = position; + /* Forget the target x position so that it will be recalculated next + time the cursor is moved up or down */ + priv->x_pos = -1; + if (CLUTTER_ACTOR_IS_VISIBLE (self)) clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); } diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 21709aee6..d6601123c 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -101,6 +101,13 @@ struct _ClutterTexturePrivate guint repeat_y : 1; guint in_dispose : 1; guint keep_aspect_ratio : 1; + guint load_async : 1; + + GThread *load_thread; + guint load_idle; + gchar *load_filename; + CoglBitmap *load_bitmap; + GError *load_error; }; enum @@ -118,13 +125,17 @@ enum PROP_COGL_MATERIAL, #endif PROP_FILENAME, - PROP_KEEP_ASPECT_RATIO + PROP_KEEP_ASPECT_RATIO, + PROP_LOAD_ASYNC }; enum { SIZE_CHANGE, PIXBUF_CHANGE, + LOAD_SUCCESS, + LOAD_FINISHED, + LAST_SIGNAL }; @@ -264,18 +275,25 @@ clutter_texture_realize (ClutterActor *actor) if (priv->fbo_source) { + CoglTextureFlags flags = COGL_TEXTURE_NONE; + gint max_waste = -1; + /* Handle FBO's */ if (priv->fbo_texture != COGL_INVALID_HANDLE) cogl_texture_unref (priv->fbo_texture); - priv->fbo_texture - = cogl_texture_new_with_size - (priv->width, - priv->height, - priv->no_slice ? -1 : priv->max_tile_waste, - priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, - COGL_PIXEL_FORMAT_RGBA_8888); + if (!priv->no_slice) + max_waste = priv->max_tile_waste; + + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + flags |= COGL_TEXTURE_AUTO_MIPMAP; + + priv->fbo_texture = + cogl_texture_new_with_size (priv->width, + priv->height, + max_waste, flags, + COGL_PIXEL_FORMAT_RGBA_8888); cogl_texture_set_filters (priv->fbo_texture, clutter_texture_quality_to_cogl_min_filter (priv->filter_quality), @@ -349,13 +367,13 @@ clutter_texture_get_preferred_width (ClutterActor *self, /* Set the natural width so as to preserve the aspect ratio */ ClutterFixed ratio, height; - ratio = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (priv->width), - COGL_FIXED_FROM_INT (priv->height)); + ratio = CLUTTER_FIXED_DIV ((float)(priv->width), + (float)(priv->height)); height = CLUTTER_UNITS_TO_FIXED (for_height); *natural_width_p = - CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL (ratio, height)); + CLUTTER_UNITS_FROM_FIXED (CLUTTER_FIXED_MUL (ratio, height)); } } } @@ -394,13 +412,13 @@ clutter_texture_get_preferred_height (ClutterActor *self, /* Set the natural height so as to preserve the aspect ratio */ ClutterFixed ratio, width; - ratio = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (priv->height), - COGL_FIXED_FROM_INT (priv->width)); + ratio = CLUTTER_FIXED_DIV ((float)(priv->height), + (float)(priv->width)); width = CLUTTER_UNITS_TO_FIXED (for_width); *natural_height_p = - CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL (ratio, width)); + CLUTTER_UNITS_FROM_FIXED (CLUTTER_FIXED_MUL (ratio, width)); } } } @@ -469,24 +487,24 @@ clutter_texture_set_fbo_projection (ClutterActor *self) /* Convert the coordinates back to [-1,1] range */ cogl_get_viewport (viewport); - 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; + tx_min = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_min), viewport[2]) + * 2 - 1.0; + tx_max = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_max), viewport[2]) + * 2 - 1.0; + ty_min = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_min), viewport[3]) + * 2 - 1.0; + ty_max = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_max), viewport[3]) + * 2 - 1.0; /* Set up a projection matrix so that the actor will be projected as if it was drawn at its original location */ - tan_angle = cogl_angle_tan (COGL_ANGLE_FROM_DEGX (perspective.fovy / 2)); - near_size = COGL_FIXED_MUL (perspective.z_near, tan_angle); + tan_angle = tanf ((perspective.fovy / 2) * (G_PI/180.0)); + near_size = CLUTTER_FIXED_MUL (perspective.z_near, tan_angle); - 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), + cogl_frustum (CLUTTER_FIXED_MUL (tx_min, near_size), + CLUTTER_FIXED_MUL (tx_max, near_size), + CLUTTER_FIXED_MUL (-ty_min, near_size), + CLUTTER_FIXED_MUL (-ty_max, near_size), perspective.z_near, perspective.z_far); } @@ -603,16 +621,16 @@ clutter_texture_paint (ClutterActor *self) clutter_actor_get_opacity (self)); if (priv->repeat_x && priv->width > 0) - t_w = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (x_2 - x_1), - COGL_FIXED_FROM_INT (priv->width)); + t_w = CLUTTER_FIXED_DIV ((float)(x_2 - x_1), + (float)(priv->width)); else - t_w = COGL_FIXED_1; + t_w = 1.0; if (priv->repeat_y && priv->height > 0) - t_h = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (y_2 - y_1), - COGL_FIXED_FROM_INT (priv->height)); + t_h = CLUTTER_FIXED_DIV ((float)(y_2 - y_1), + (float)(priv->height)); else - t_h = COGL_FIXED_1; + t_h = 1.0; /* Paint will have translated us */ #if USE_COGL_MATERIAL @@ -623,18 +641,57 @@ clutter_texture_paint (ClutterActor *self) tex_coords[2] = t_w; tex_coords[3] = t_h; cogl_material_rectangle (0, 0, - COGL_FIXED_FROM_INT (x_2 - x_1), - COGL_FIXED_FROM_INT (y_2 - y_1), + (float)(x_2 - x_1), + (float)(y_2 - y_1), 4, tex_coords); #else cogl_texture_rectangle (priv->texture, 0, 0, - COGL_FIXED_FROM_INT (x_2 - x_1), - COGL_FIXED_FROM_INT (y_2 - y_1), - 0, 0, t_w, t_h); + (float)(x_2 - x_1), + (float)(y_2 - y_1), + 0, 0, t_w, t_h); #endif } +/* + * clutter_texture_async_load_cancel: + * @texture: a #ClutterTexture + * + * Cancels an asynchronous loading operation, whether done + * with threads enabled or just using the main loop + */ +static void +clutter_texture_async_load_cancel (ClutterTexture *texture) +{ + ClutterTexturePrivate *priv = texture->priv; + + if (priv->load_thread) + { + g_thread_join (priv->load_thread); + priv->load_thread = NULL; + } + + if (priv->load_idle) + { + g_source_remove (priv->load_idle); + priv->load_idle = 0; + } + + if (priv->load_error) + { + g_error_free (priv->load_error); + priv->load_error = NULL; + } + + if (priv->load_bitmap) + { + cogl_bitmap_free (priv->load_bitmap); + priv->load_bitmap = NULL; + } + + g_free (priv->load_filename); +} + static void clutter_texture_dispose (GObject *object) { @@ -659,7 +716,9 @@ clutter_texture_dispose (GObject *object) g_free (priv->local_data); priv->local_data = NULL; } - + + clutter_texture_async_load_cancel (texture); + G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object); } @@ -725,6 +784,9 @@ clutter_texture_set_property (GObject *object, case PROP_KEEP_ASPECT_RATIO: priv->keep_aspect_ratio = g_value_get_boolean (value); break; + case PROP_LOAD_ASYNC: + priv->load_async = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -782,6 +844,9 @@ clutter_texture_get_property (GObject *object, case PROP_KEEP_ASPECT_RATIO: g_value_set_boolean (value, priv->keep_aspect_ratio); break; + case PROP_LOAD_ASYNC: + g_value_set_boolean (value, priv->load_async); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -868,7 +933,7 @@ clutter_texture_class_init (ClutterTextureClass *klass) "smaller values less texture memory.", -1, G_MAXINT, - 64, + 63, G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE)); g_object_class_install_property @@ -918,6 +983,29 @@ clutter_texture_class_init (ClutterTextureClass *klass) FALSE, CLUTTER_PARAM_READWRITE)); + /** + * ClutterTexture:load-async: + * + * Tries to load a texture from a filename by using a local thread + * to perform the read operations. Threading is only enabled if + * g_thread_init() has been called prior to clutter_init(), otherwise + * #ClutterTexture will use the main loop to load the image. + * + * The upload of the texture data on the GL pipeline is not + * asynchronous, as it must be performed from within the same + * thread that called clutter_main(). + * + * Since: 1.0 + */ + g_object_class_install_property + (gobject_class, PROP_LOAD_ASYNC, + g_param_spec_boolean ("load-async", + "Load asynchronously", + "Load files inside a thread to avoid blocking when " + "loading images.", + FALSE, + CLUTTER_PARAM_READWRITE)); + /** * ClutterTexture::size-change: * @texture: the texture which received the signal @@ -953,6 +1041,27 @@ clutter_texture_class_init (ClutterTextureClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /** + * ClutterTexture::load-finished: + * @texture: the texture which received the signal + * @error: A set error, or %NULL + * + * The ::load-finished signal is emitted when a texture load has + * completed. If there was an error during loading, @error will + * be set, otherwise it will be %NULL + * + * Since: 1.0 + */ + texture_signals[LOAD_FINISHED] = + g_signal_new (I_("load-finished"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterTextureClass, load_finished), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); } static ClutterScriptableIface *parent_scriptable_iface = NULL; @@ -1016,7 +1125,7 @@ clutter_texture_init (ClutterTexture *self) self->priv = priv = CLUTTER_TEXTURE_GET_PRIVATE (self); - priv->max_tile_waste = 64; + priv->max_tile_waste = 63; priv->filter_quality = CLUTTER_TEXTURE_QUALITY_MEDIUM; priv->repeat_x = FALSE; priv->repeat_y = FALSE; @@ -1286,19 +1395,25 @@ clutter_texture_set_from_data (ClutterTexture *texture, gint bpp, GError **error) { - CoglHandle new_texture; - ClutterTexturePrivate *priv; + ClutterTexturePrivate *priv = texture->priv; + CoglHandle new_texture = COGL_INVALID_HANDLE; + CoglTextureFlags flags = COGL_TEXTURE_NONE; + gint max_waste = -1; - priv = texture->priv; + if (!priv->no_slice) + max_waste = priv->max_tile_waste; - if ((new_texture = cogl_texture_new_from_data - (width, height, - priv->no_slice ? -1 : priv->max_tile_waste, - priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, - source_format, - COGL_PIXEL_FORMAT_ANY, - rowstride, - data)) == COGL_INVALID_HANDLE) + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + flags |= COGL_TEXTURE_AUTO_MIPMAP; + + new_texture = cogl_texture_new_from_data (width, height, + max_waste, flags, + source_format, + COGL_PIXEL_FORMAT_ANY, + rowstride, + data); + + if (G_UNLIKELY (new_texture == COGL_INVALID_HANDLE)) { g_set_error (error, CLUTTER_TEXTURE_ERROR, CLUTTER_TEXTURE_ERROR_BAD_FORMAT, @@ -1315,6 +1430,8 @@ clutter_texture_set_from_data (ClutterTexture *texture, cogl_texture_unref (new_texture); + g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error); + return TRUE; } @@ -1409,14 +1526,14 @@ clutter_texture_set_from_rgb_data (ClutterTexture *texture, * Return value: %TRUE if the texture was successfully updated * * Since: 0.4 - **/ + */ gboolean -clutter_texture_set_from_yuv_data (ClutterTexture *texture, - const guchar *data, - gint width, - gint height, - ClutterTextureFlags flags, - GError **error) +clutter_texture_set_from_yuv_data (ClutterTexture *texture, + const guchar *data, + gint width, + gint height, + ClutterTextureFlags flags, + GError **error) { ClutterTexturePrivate *priv; @@ -1448,6 +1565,188 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture, error); } +/* + * clutter_texture_async_load_complete: + * @self: a #ClutterTexture + * @error: load error + * + * If @error is %NULL, loads the #CoglBitmap into a #CoglTexture. + * + * This function emits the ::load-finished signal on @self. + */ +static void +clutter_texture_async_load_complete (ClutterTexture *self, + const GError *error) +{ + ClutterTexturePrivate *priv = self->priv; + CoglHandle handle; + CoglTextureFlags flags = COGL_TEXTURE_NONE; + gint waste = -1; + + if (error == NULL) + { + if (priv->no_slice) + waste = priv->max_tile_waste; + + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + flags |= COGL_TEXTURE_AUTO_MIPMAP; + + handle = cogl_texture_new_from_bitmap (priv->load_bitmap, + waste, flags, + COGL_PIXEL_FORMAT_ANY); + clutter_texture_set_cogl_texture (self, handle); + cogl_texture_unref (handle); + + cogl_bitmap_free (priv->load_bitmap); + priv->load_bitmap = NULL; + } + + g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error); + + clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); +} + +static gboolean +clutter_texture_thread_cb (gpointer data) +{ + ClutterTexture *self = data; + ClutterTexturePrivate *priv = self->priv; + + priv->load_idle = 0; + + if (priv->load_thread) + { + g_thread_join (priv->load_thread); + priv->load_thread = NULL; + } + else + return FALSE; + + clutter_texture_async_load_complete (self, priv->load_error); + + if (priv->load_error) + { + g_error_free (priv->load_error); + priv->load_error = NULL; + } + + return FALSE; +} + +static gpointer +clutter_texture_thread_func (gpointer data) +{ + ClutterTexture *self = data; + ClutterTexturePrivate *priv = self->priv; + + /* Try loading with imaging backend */ + priv->load_bitmap = cogl_bitmap_new_from_file (priv->load_filename, + &priv->load_error); + g_free (priv->load_filename); + priv->load_filename = NULL; + + /* make sure we load the image in the main thread, where we + * hold the main Clutter lock + */ + priv->load_idle = + clutter_threads_add_idle (clutter_texture_thread_cb, self); + + return NULL; +} + +static gboolean +clutter_texture_idle_func (gpointer data) +{ + ClutterTexture *self = data; + ClutterTexturePrivate *priv = self->priv; + GError *internal_error; + + internal_error = NULL; + priv->load_bitmap = cogl_bitmap_new_from_file (priv->load_filename, + &internal_error); + + clutter_texture_async_load_complete (self, internal_error); + + g_free (priv->load_filename); + priv->load_filename = NULL; + + if (internal_error) + g_error_free (internal_error); + + return FALSE; +} + +/* + * clutter_texture_async_load: + * @self: a #ClutterTexture + * @error: return location for a #GError + * + * Starts an asynchronous load of the file name stored inside + * the load_filename private member. + * + * If threading is enabled we use a GThread to perform the actual + * I/O; if threading is not enabled, we use an idle GSource. + * + * The I/O is the only bit done in a thread -- uploading the + * texture data to the GL pipeline must be done from within the + * same thread that called clutter_main(). Threaded upload should + * be part of the GL implementation. + * + * This function will block until we get a size from the file + * so that we can effectively get the size the texture actor after + * clutter_texture_set_from_file(). + * + * Return value: %TRUE if the asynchronous loading was successfully + * initiated, %FALSE otherwise + */ +static gboolean +clutter_texture_async_load (ClutterTexture *self, + GError **error) +{ + ClutterTexturePrivate *priv = self->priv; + gint width, height; + gboolean res; + + g_assert (priv->load_filename != NULL); + + /* ask the file for a size; if we cannot get the size then + * there's no point in even continuing the asynchronous + * loading, so we just stop there + */ + res = cogl_bitmap_get_size_from_file (priv->load_filename, + &width, + &height); + if (!res) + { + g_set_error (error, CLUTTER_TEXTURE_ERROR, + CLUTTER_TEXTURE_ERROR_BAD_FORMAT, + "Failed to create COGL texture"); + return FALSE; + } + else + { + priv->width = width; + priv->height = height; + } + + if (g_thread_supported ()) + { + priv->load_thread = + g_thread_create ((GThreadFunc) clutter_texture_thread_func, + self, TRUE, + error); + + return priv->load_thread != NULL? TRUE : FALSE; + } + else + { + priv->load_idle = + clutter_threads_add_idle (clutter_texture_idle_func, self); + + return TRUE; + } +} + /** * clutter_texture_set_from_file: * @texture: A #ClutterTexture @@ -1457,6 +1756,12 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture, * Sets the #ClutterTexture image data from an image file. In case of * failure, %FALSE is returned and @error is set. * + * If #ClutterTexture:load-async is set to %TRUE, this function + * will return as soon as possible, and the actual image loading + * from disk will be performed asynchronously. #ClutterTexture::load-finished + * will be emitted when the image has been loaded or if an error + * occurred. + * * Return value: %TRUE if the image was successfully loaded and set * * Since: 0.8 @@ -1466,28 +1771,48 @@ clutter_texture_set_from_file (ClutterTexture *texture, const gchar *filename, GError **error) { - CoglHandle new_texture; - ClutterTexturePrivate *priv; + ClutterTexturePrivate *priv; + CoglHandle new_texture = COGL_INVALID_HANDLE; + GError *internal_error = NULL; + CoglTextureFlags flags = COGL_TEXTURE_NONE; + gint max_waste = -1; priv = texture->priv; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if ((new_texture = cogl_texture_new_from_file - (filename, - priv->no_slice ? -1 : priv->max_tile_waste, - priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, - COGL_PIXEL_FORMAT_ANY, - error)) - == COGL_INVALID_HANDLE) + if (priv->load_async) + { + clutter_texture_async_load_cancel (texture); + + priv->load_filename = g_strdup (filename); + + return clutter_texture_async_load (texture, error); + } + + if (priv->no_slice) + max_waste = priv->max_tile_waste; + + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + flags |= COGL_TEXTURE_AUTO_MIPMAP; + + new_texture = cogl_texture_new_from_file (filename, + max_waste, flags, + COGL_PIXEL_FORMAT_ANY, + &internal_error); + if (new_texture == COGL_INVALID_HANDLE) { /* If COGL didn't give an error then make one up */ - if (error && *error == NULL) + if (internal_error == NULL) { g_set_error (error, CLUTTER_TEXTURE_ERROR, CLUTTER_TEXTURE_ERROR_BAD_FORMAT, "Failed to create COGL texture"); } + else + g_propagate_error (error, internal_error); + + g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error); return FALSE; } @@ -1500,6 +1825,8 @@ clutter_texture_set_from_file (ClutterTexture *texture, cogl_texture_unref (new_texture); + g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error); + return TRUE; } @@ -1848,19 +2175,25 @@ on_fbo_source_size_change (GObject *object, if (w != priv->width || h != priv->height) { + CoglTextureFlags flags = COGL_TEXTURE_NONE; + /* tear down the FBO */ cogl_offscreen_unref (priv->fbo_handle); texture_free_gl_resources (texture); - priv->width = w; - priv->height = h; + priv->width = w; + priv->height = h; - priv->fbo_texture = cogl_texture_new_with_size (MAX (priv->width, 1), - MAX (priv->height, 1), - -1, - priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, - COGL_PIXEL_FORMAT_RGBA_8888); + if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) + flags |= COGL_TEXTURE_AUTO_MIPMAP; + + priv->fdo_texture = + cogl_texture_new_with_size (MAX (priv->width, 1), + MAX (priv->height, 1), + -1, + flags, + COGL_PIXEL_FORMAT_RGBA_8888); cogl_texture_set_filters (priv->fbo_texture, clutter_texture_quality_to_cogl_min_filter (priv->filter_quality), @@ -1876,7 +2209,7 @@ on_fbo_source_size_change (GObject *object, return; } - clutter_actor_set_size (CLUTTER_ACTOR(texture), w, h); + clutter_actor_set_size (CLUTTER_ACTOR (texture), w, h); } } @@ -2051,9 +2384,9 @@ clutter_texture_new_from_actor (ClutterActor *actor) priv->width = w; priv->height = h; - clutter_actor_set_size (CLUTTER_ACTOR(texture), priv->width, priv->height); + clutter_actor_set_size (CLUTTER_ACTOR (texture), priv->width, priv->height); - return CLUTTER_ACTOR(texture); + return CLUTTER_ACTOR (texture); } static void diff --git a/clutter/clutter-texture.h b/clutter/clutter-texture.h index 4e896c04b..aa76debf3 100644 --- a/clutter/clutter-texture.h +++ b/clutter/clutter-texture.h @@ -89,6 +89,8 @@ struct _ClutterTextureClass gint width, gint height); void (*pixbuf_change) (ClutterTexture *texture); + void (*load_finished) (ClutterTexture *texture, + GError *error); /*< private >*/ /* padding, for future expansion */ @@ -97,7 +99,6 @@ struct _ClutterTextureClass void (*_clutter_texture3) (void); void (*_clutter_texture4) (void); void (*_clutter_texture5) (void); - void (*_clutter_texture6) (void); }; /** diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c index 0841a3077..b9df23b3f 100644 --- a/clutter/clutter-timeline.c +++ b/clutter/clutter-timeline.c @@ -1347,7 +1347,7 @@ clutter_timeline_get_progress (ClutterTimeline *timeline) { g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0.); - return COGL_FIXED_TO_DOUBLE (clutter_timeline_get_progressx (timeline)); + return CLUTTER_FIXED_TO_DOUBLE (clutter_timeline_get_progressx (timeline)); } /** @@ -1370,11 +1370,11 @@ clutter_timeline_get_progressx (ClutterTimeline *timeline) priv = timeline->priv; - progress = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (priv->current_frame_num), - COGL_FIXED_FROM_INT (priv->n_frames)); + progress = CLUTTER_FIXED_DIV ((float)(priv->current_frame_num), + (float)(priv->n_frames)); if (priv->direction == CLUTTER_TIMELINE_BACKWARD) - progress = COGL_FIXED_1 - progress; + progress = 1.0 - progress; return progress; } diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h index 2e97d52ed..2e1856905 100644 --- a/clutter/clutter-types.h +++ b/clutter/clutter-types.h @@ -200,6 +200,7 @@ typedef enum { * @CLUTTER_EXPO_OUT: exponential out progress * @CLUTTER_EXPO_IN_OUT: exponential in-out progress * @CLUTTER_SMOOTH_IN_OUT: smoothstep in-out progress + * @CLUTTER_ANIMATION_LAST: last animation mode * * The animation modes used by #ClutterAlpha and #ClutterAnimation. This * enumeration can be expanded in later versions of Clutter. @@ -207,7 +208,7 @@ typedef enum { * Since: 1.0 */ typedef enum { - CLUTTER_CUSTOM_MODE, + CLUTTER_CUSTOM_MODE = 0, CLUTTER_LINEAR, CLUTTER_SINE_IN, @@ -220,6 +221,8 @@ typedef enum { CLUTTER_EXPO_OUT, CLUTTER_EXPO_IN_OUT, CLUTTER_SMOOTH_IN_OUT, + + CLUTTER_ANIMATION_LAST } ClutterAnimationMode; G_END_DECLS diff --git a/clutter/clutter-units.c b/clutter/clutter-units.c index 97dce9790..9ea6d78a0 100644 --- a/clutter/clutter-units.c +++ b/clutter/clutter-units.c @@ -101,6 +101,81 @@ #include "clutter-units.h" #include "clutter-private.h" +#define DPI_FALLBACK (96.0) + +#define FLOAT_EPSILON (1e-30) + +/** + * clutter_units_mm: + * @mm: millimeters to convert + * + * Converts a value in millimeters to #ClutterUnits at + * the current DPI. + * + * Return value: the value in units + * + * Since: 1.0 + */ +ClutterUnit +clutter_units_mm (gdouble mm) +{ + ClutterBackend *backend; + gdouble dpi; + + backend = clutter_get_default_backend (); + dpi = clutter_backend_get_resolution (backend); + if (dpi < 0) + dpi = DPI_FALLBACK; + + return mm * dpi / 25.4; +} + +/** + * clutter_units_pt: + * @pt: typographic points to convert + * + * Converts a value in typographic points to #ClutterUnits + * at the current DPI. + * + * Return value: the value in units + * + * Since: 1.0 + */ +ClutterUnit +clutter_units_pt (gdouble pt) +{ + ClutterBackend *backend; + gdouble dpi; + + backend = clutter_get_default_backend (); + dpi = clutter_backend_get_resolution (backend); + if (dpi < 0) + dpi = DPI_FALLBACK; + + return pt * dpi / 72.0; +} + +/** + * clutter_units_em: + * @em: em to convert + * + * Converts a value in em to #ClutterUnits at the + * current DPI. + * + * Return value: the value in units + * + * Since: 1.0 + */ +ClutterUnit +clutter_units_em (gdouble em) +{ + ClutterBackend *backend; + + backend = clutter_get_default_backend (); + + return em * _clutter_backend_get_units_per_em (backend); +} + static GTypeInfo _info = { 0, NULL, @@ -119,14 +194,14 @@ static GTypeFundamentalInfo _finfo = { 0, }; static void clutter_value_init_unit (GValue *value) { - value->data[0].v_int = 0; + value->data[0].v_float = 0.0; } static void clutter_value_copy_unit (const GValue *src, GValue *dest) { - dest->data[0].v_int = src->data[0].v_int; + dest->data[0].v_float = src->data[0].v_float; } static gchar * @@ -135,7 +210,7 @@ clutter_value_collect_unit (GValue *value, GTypeCValue *collect_values, guint collect_flags) { - value->data[0].v_int = collect_values[0].v_int; + value->data[0].v_float = collect_values[0].v_double; return NULL; } @@ -146,13 +221,13 @@ clutter_value_lcopy_unit (const GValue *value, GTypeCValue *collect_values, guint collect_flags) { - gint32 *units_p = collect_values[0].v_pointer; + gfloat *units_p = collect_values[0].v_pointer; if (!units_p) return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); - *units_p = value->data[0].v_int; + *units_p = value->data[0].v_float; return NULL; } @@ -161,14 +236,14 @@ static void clutter_value_transform_unit_int (const GValue *src, GValue *dest) { - dest->data[0].v_int = CLUTTER_UNITS_TO_INT (src->data[0].v_int); + dest->data[0].v_int = CLUTTER_UNITS_TO_INT (src->data[0].v_float); } static void clutter_value_transform_int_unit (const GValue *src, GValue *dest) { - dest->data[0].v_int = CLUTTER_UNITS_FROM_INT (src->data[0].v_int); + dest->data[0].v_float = CLUTTER_UNITS_FROM_INT (src->data[0].v_int); } static const GTypeValueTable _clutter_unit_value_table = { @@ -176,7 +251,7 @@ static const GTypeValueTable _clutter_unit_value_table = { NULL, clutter_value_copy_unit, NULL, - "i", + "d", clutter_value_collect_unit, "p", clutter_value_lcopy_unit @@ -219,7 +294,7 @@ clutter_value_set_unit (GValue *value, { g_return_if_fail (CLUTTER_VALUE_HOLDS_UNIT (value)); - value->data[0].v_int = units; + value->data[0].v_float = units; } /** @@ -237,7 +312,7 @@ clutter_value_get_unit (const GValue *value) { g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNIT (value), 0); - return value->data[0].v_int; + return value->data[0].v_float; } static void @@ -254,7 +329,7 @@ static void param_unit_set_default (GParamSpec *pspec, GValue *value) { - value->data[0].v_int = CLUTTER_PARAM_SPEC_UNIT (pspec)->default_value; + value->data[0].v_float = CLUTTER_PARAM_SPEC_UNIT (pspec)->default_value; } static gboolean @@ -262,26 +337,15 @@ param_unit_validate (GParamSpec *pspec, GValue *value) { ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec); - gint oval = CLUTTER_UNITS_TO_INT (value->data[0].v_int); - gint min, max, val; + gfloat oval = value->data[0].v_float; g_assert (CLUTTER_IS_PARAM_SPEC_UNIT (pspec)); - /* we compare the integer part of the value because the minimum - * and maximum values cover just that part of the representation - */ - min = uspec->minimum; - max = uspec->maximum; - val = CLUTTER_UNITS_TO_INT (value->data[0].v_int); + value->data[0].v_float = CLAMP (value->data[0].v_float, + uspec->minimum, + uspec->maximum); - val = CLAMP (val, min, max); - if (val != oval) - { - value->data[0].v_int = val; - return TRUE; - } - - return FALSE; + return value->data[0].v_float != oval; } static gint @@ -289,10 +353,12 @@ param_unit_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2) { - if (value1->data[0].v_int < value2->data[0].v_int) - return -1; + gfloat epsilon = FLOAT_EPSILON; + + if (value1->data[0].v_float < value2->data[0].v_float) + return - (value2->data[0].v_float - value1->data[0].v_float > epsilon); else - return value1->data[0].v_int > value2->data[0].v_int; + return value1->data[0].v_float - value2->data[0].v_float > epsilon; } GType diff --git a/clutter/clutter-units.h b/clutter/clutter-units.h index b85375a98..efc622e1b 100644 --- a/clutter/clutter-units.h +++ b/clutter/clutter-units.h @@ -4,9 +4,11 @@ * * An OpenGL based 'interactive canvas' library. * - * Authored By Tomas Frydrych + * Authored By: Tomas Frydrych + * Emmanuele Bassu * - * Copyright (C) 2007 OpenedHand + * Copyright (C) 2007, 2008 OpenedHand + * Copyright (C) 2009 Intel Corp. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -42,24 +44,32 @@ G_BEGIN_DECLS * * Since: 0.4 */ -typedef gint32 ClutterUnit; +typedef float ClutterUnit; -/* - * Currently CLUTTER_UNIT maps directly onto ClutterFixed. Nevertheless, the - * _FROM_FIXED and _TO_FIXED macros should always be used in case that we - * decide to change this relationship in the future. - */ +#define CLUTTER_UNITS_FROM_INT(x) ((float)(x)) +#define CLUTTER_UNITS_TO_INT(x) ((int)(x)) -#define CLUTTER_UNITS_FROM_INT(x) (COGL_FIXED_FROM_INT ((x))) -#define CLUTTER_UNITS_TO_INT(x) (COGL_FIXED_TO_INT ((x))) - -#define CLUTTER_UNITS_FROM_FLOAT(x) (COGL_FIXED_FROM_FLOAT ((x))) -#define CLUTTER_UNITS_TO_FLOAT(x) (COGL_FIXED_TO_FLOAT ((x))) +#define CLUTTER_UNITS_FROM_FLOAT(x) (x) +#define CLUTTER_UNITS_TO_FLOAT(x) (x) #define CLUTTER_UNITS_FROM_FIXED(x) (x) #define CLUTTER_UNITS_TO_FIXED(x) (x) -#define CLUTTER_UNITS_FORMAT "d" +/** + * CLUTTER_UNITS_FORMAT: + * + * Format string that should be used for scanning and printing units. + * It is a string literal, but it does not include the percent sign to + * allow precision and length modifiers between the percent sign and + * the format: + * + * |[ + * g_print ("%" CLUTTER_UNITS_FORMAT, units); + * ]| + * + * Since: 1.0 + */ +#define CLUTTER_UNITS_FORMAT "f" /** * CLUTTER_UNITS_FROM_DEVICE: @@ -81,9 +91,6 @@ typedef gint32 ClutterUnit; */ #define CLUTTER_UNITS_TO_DEVICE(x) CLUTTER_UNITS_TO_INT ((x)) -#define CLUTTER_UNITS_TMP_FROM_DEVICE(x) (x) -#define CLUTTER_UNITS_TMP_TO_DEVICE(x) (x) - /** * CLUTTER_UNITS_FROM_PANGO_UNIT: * @x: value in Pango units @@ -92,7 +99,7 @@ typedef gint32 ClutterUnit; * * Since: 0.6 */ -#define CLUTTER_UNITS_FROM_PANGO_UNIT(x) ((x) << 6) +#define CLUTTER_UNITS_FROM_PANGO_UNIT(x) ((float)((x) / 1024)) /** * CLUTTER_UNITS_TO_PANGO_UNIT: @@ -102,19 +109,7 @@ typedef gint32 ClutterUnit; * * Since: 0.6 */ -#define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((x) >> 6) - -#define CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE(x) \ - ((clutter_actor_get_widthu (clutter_stage_get_default ()) * x) / 100) - -#define CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE(x) \ - ((clutter_actor_get_heightu (clutter_stage_get_default ()) * x) / 100) - -#define CLUTTER_UNITS_FROM_PARENT_WIDTH_PERCENTAGE(a, x) \ - ((clutter_actor_get_widthu (clutter_actor_get_parent (a)) * x) / 100) - -#define CLUTTER_UNITS_FROM_PARENT_HEIGHT_PERCENTAGE(a, x) \ - ((clutter_actor_get_heightu (clutter_actor_get_parent (a)) * x) / 100) +#define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((int)((x) * 1024)) /** * CLUTTER_UNITS_FROM_MM: @@ -124,11 +119,7 @@ typedef gint32 ClutterUnit; * * Since: 0.6 */ -#define CLUTTER_UNITS_FROM_MM(x) \ - (CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 25.4))) - -#define CLUTTER_UNITS_FROM_MMX(x) \ - (CFX_DIV (CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())), 0x196666)) +#define CLUTTER_UNITS_FROM_MM(x) (clutter_units_mm (x)) /** * CLUTTER_UNITS_FROM_POINTS: @@ -138,11 +129,21 @@ typedef gint32 ClutterUnit; * * Since: 0.6 */ -#define CLUTTER_UNITS_FROM_POINTS(x) \ - CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 72.0)) +#define CLUTTER_UNITS_FROM_POINTS(x) (clutter_units_pt (x)) -#define CLUTTER_UNITS_FROM_POINTSX(x) \ - (CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())) / 72) +/** + * CLUTTER_UNITS_FROM_EM: + * @x: a value in em + * + * Converts a value in em into #ClutterUnits + * + * Since: 1.0 + */ +#define CLUTTER_UNITS_FROM_EM(x) (clutter_units_em (x)) + +ClutterUnit clutter_units_mm (gdouble mm); +ClutterUnit clutter_units_pt (gdouble pt); +ClutterUnit clutter_units_em (gdouble em); #define CLUTTER_TYPE_UNIT (clutter_unit_get_type ()) #define CLUTTER_TYPE_PARAM_UNIT (clutter_param_unit_get_type ()) @@ -156,7 +157,7 @@ typedef gint32 ClutterUnit; * * Since: 0.8 */ -#define CLUTTER_MAXUNIT (0x7fffffff) +#define CLUTTER_MAXUNIT (G_MAXFLOAT) /** * CLUTTER_MINUNIT: @@ -165,7 +166,7 @@ typedef gint32 ClutterUnit; * * Since: 0.8 */ -#define CLUTTER_MINUNIT (0x80000000) +#define CLUTTER_MINUNIT (-G_MAXFLOAT) /** * CLUTTER_VALUE_HOLDS_UNIT: diff --git a/clutter/clutter.h b/clutter/clutter.h index 817dbef6c..478d7b19f 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -30,6 +30,7 @@ #include "clutter-actor.h" #include "clutter-alpha.h" +#include "clutter-animatable.h" #include "clutter-animation.h" #include "clutter-backend.h" #include "clutter-behaviour-depth.h" @@ -46,7 +47,6 @@ #include "clutter-color.h" #include "clutter-container.h" #include "clutter-deprecated.h" -#include "clutter-effect.h" #include "clutter-event.h" #include "clutter-feature.h" #include "clutter-frame-source.h" diff --git a/clutter/cogl/cogl-color.h b/clutter/cogl/cogl-color.h index fbc49d5bb..05650d34a 100644 --- a/clutter/cogl/cogl-color.h +++ b/clutter/cogl/cogl-color.h @@ -68,22 +68,22 @@ void cogl_color_set_from_4d (CoglColor *dest, gdouble alpha); /** - * cogl_color_set_from_4x: + * cogl_color_set_from_4f: * @dest: return location for a #CoglColor - * @red: value of the red channel, between 0 and %COGL_FIXED_1 - * @green: value of the green channel, between 0 and %COGL_FIXED_1 - * @blue: value of the blue channel, between 0 and %COGL_FIXED_1 - * @alpha: value of the alpha channel, between 0 and %COGL_FIXED_1 + * @red: value of the red channel, between 0 and %1.0 + * @green: value of the green channel, between 0 and %1.0 + * @blue: value of the blue channel, between 0 and %1.0 + * @alpha: value of the alpha channel, between 0 and %1.0 * * Sets the values of the passed channels into a #CoglColor * * Since: 1.0 */ -void cogl_color_set_from_4x (CoglColor *dest, - CoglFixed red, - CoglFixed green, - CoglFixed blue, - CoglFixed alpha); +void cogl_color_set_from_4f (CoglColor *dest, + float red, + float green, + float blue, + float alpha); /** * cogl_color_get_red_byte: @@ -194,52 +194,52 @@ float cogl_color_get_alpha_float (const CoglColor *color); * @color: a #CoglColor * * Retrieves the red channel of @color as a fixed point - * value between 0 and %COGL_FIXED_1. + * value between 0 and %1.0. * * Return value: the red channel of the passed color * * Since: 1.0 */ -CoglFixed cogl_color_get_red (const CoglColor *color); +float cogl_color_get_red (const CoglColor *color); /** * cogl_color_get_green: * @color: a #CoglColor * * Retrieves the green channel of @color as a fixed point - * value between 0 and %COGL_FIXED_1. + * value between 0 and %1.0. * * Return value: the green channel of the passed color * * Since: 1.0 */ -CoglFixed cogl_color_get_green (const CoglColor *color); +float cogl_color_get_green (const CoglColor *color); /** * cogl_color_get_blue: * @color: a #CoglColor * * Retrieves the blue channel of @color as a fixed point - * value between 0 and %COGL_FIXED_1. + * value between 0 and %1.0. * * Return value: the blue channel of the passed color * * Since: 1.0 */ -CoglFixed cogl_color_get_blue (const CoglColor *color); +float cogl_color_get_blue (const CoglColor *color); /** * cogl_color_get_alpha: * @color: a #CoglColor * * Retrieves the alpha channel of @color as a fixed point - * value between 0 and %COGL_FIXED_1. + * value between 0 and %1.0. * * Return value: the alpha channel of the passed color * * Since: 1.0 */ -CoglFixed cogl_color_get_alpha (const CoglColor *color); +float cogl_color_get_alpha (const CoglColor *color); /** * cogl_set_source_color: @@ -248,7 +248,7 @@ CoglFixed cogl_color_get_alpha (const CoglColor *color); * Sets the source color using normalized values for each component. * This color will be used for any subsequent drawing operation. * - * See also cogl_set_source_color4ub() and cogl_set_source_color4x() + * See also cogl_set_source_color4ub() and cogl_set_source_color4f() * if you already have the color components. * * Since: 1.0 @@ -276,25 +276,25 @@ void cogl_set_source_color4ub (guint8 red, guint8 alpha); /** - * cogl_set_source_color4x: - * @red: value of the red channel, between 0 and %COGL_FIXED_1 - * @green: value of the green channel, between 0 and %COGL_FIXED_1 - * @blue: value of the blue channel, between 0 and %COGL_FIXED_1 - * @alpha: value of the alpha channel, between 0 and %COGL_FIXED_1 + * cogl_set_source_color4f: + * @red: value of the red channel, between 0 and %1.0 + * @green: value of the green channel, between 0 and %1.0 + * @blue: value of the blue channel, between 0 and %1.0 + * @alpha: value of the alpha channel, between 0 and %1.0 * * Sets the source color using normalized values for each component. * This color will be used for any subsequent drawing operation. * * The value for each component is a fixed point number in the range - * between 0 and %COGL_FIXED_1. If the values passed in are outside that + * between 0 and %1.0. If the values passed in are outside that * range, they will be clamped. * * Since: 1.0 */ -void cogl_set_source_color4x (CoglFixed red, - CoglFixed green, - CoglFixed blue, - CoglFixed alpha); +void cogl_set_source_color4f (float red, + float green, + float blue, + float alpha); G_END_DECLS diff --git a/clutter/cogl/cogl-fixed.h b/clutter/cogl/cogl-fixed.h index a52107421..8d7c9e96a 100644 --- a/clutter/cogl/cogl-fixed.h +++ b/clutter/cogl/cogl-fixed.h @@ -455,6 +455,18 @@ G_BEGIN_DECLS */ CoglFixed cogl_fixed_sin (CoglFixed angle); +/** + * cogl_fixed_tan: + * @angle: a #CoglFixed number + * + * Computes the tangent of @angle. + * + * Return value: the tangent of the passed angle, in fixed point notation + * + * Since: 1.0 + */ +CoglFixed cogl_fixed_tan (CoglFixed angle); + /** * cogl_fixed_cos: * @angle: a #CoglFixed number diff --git a/clutter/cogl/cogl-path.h b/clutter/cogl/cogl-path.h index 20632da37..aa378647a 100644 --- a/clutter/cogl/cogl-path.h +++ b/clutter/cogl/cogl-path.h @@ -60,24 +60,10 @@ G_BEGIN_DECLS * Fills a rectangle at the given coordinates with the current * drawing color in a highly optimizied fashion. **/ -void cogl_rectangle (gint x, - gint y, - guint width, - guint height); - -/** - * cogl_rectanglex: - * @x: X coordinate of the top-left corner - * @y: Y coordinate of the top-left corner - * @width: Width of the rectangle - * @height: Height of the rectangle - * - * A fixed-point version of cogl_fast_fill_rectangle. - **/ -void cogl_rectanglex (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height); +void cogl_rectangle (float x, + float y, + float width, + float height); /** * cogl_path_fill: @@ -136,8 +122,8 @@ void cogl_path_new (void); * Moves the pen to the given location. If there is an existing path * this will start a new disjoint subpath. **/ -void cogl_path_move_to (CoglFixed x, - CoglFixed y); +void cogl_path_move_to (float x, + float y); /** @@ -149,8 +135,8 @@ void cogl_path_move_to (CoglFixed x, * location. If there is an existing path this will start a new * disjoint subpath. **/ -void cogl_path_rel_move_to (CoglFixed x, - CoglFixed y); +void cogl_path_rel_move_to (float x, + float y); /** * cogl_path_line_to: @@ -160,8 +146,8 @@ void cogl_path_rel_move_to (CoglFixed x, * Adds a straight line segment to the current path that ends at the * given coordinates. **/ -void cogl_path_line_to (CoglFixed x, - CoglFixed y); +void cogl_path_line_to (float x, + float y); /** * cogl_path_rel_line_to: @@ -171,8 +157,8 @@ void cogl_path_line_to (CoglFixed x, * Adds a straight line segment to the current path that ends at the * given coordinates relative to the current pen location. **/ -void cogl_path_rel_line_to (CoglFixed x, - CoglFixed y); +void cogl_path_rel_line_to (float x, + float y); /** @@ -189,12 +175,12 @@ void cogl_path_rel_line_to (CoglFixed x, * of the arc. If you perform a move_to to the arcs start just before * drawing it you create a free standing arc. **/ -void cogl_path_arc (CoglFixed center_x, - CoglFixed center_y, - CoglFixed radius_x, - CoglFixed radius_y, - CoglAngle angle_1, - CoglAngle angle_2); +void cogl_path_arc (float center_x, + float center_y, + float radius_x, + float radius_y, + float angle_1, + float angle_2); @@ -211,12 +197,12 @@ void cogl_path_arc (CoglFixed center_x, * second, third and fourth control points and using current pen location * as the first control point. **/ -void cogl_path_curve_to (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed x3, - CoglFixed y3); +void cogl_path_curve_to (float x1, + float y1, + float x2, + float y2, + float x3, + float y3); /** * cogl_path_rel_curve_to: @@ -232,12 +218,12 @@ void cogl_path_curve_to (CoglFixed x1, * as the first control point. The given coordinates are relative to the * current pen location. */ -void cogl_path_rel_curve_to (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed x3, - CoglFixed y3); +void cogl_path_rel_curve_to (float x1, + float y1, + float x2, + float y2, + float x3, + float y3); /** * cogl_path_close: @@ -258,10 +244,10 @@ void cogl_path_close (void); * coordinates. If there is an existing path this will start a new * disjoint sub-path. **/ -void cogl_path_line (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2); +void cogl_path_line (float x1, + float y1, + float x2, + float y2); /** * cogl_path_polyline: @@ -281,7 +267,7 @@ void cogl_path_line (CoglFixed x1, * fashion for the rest of the vertices. (num_points - 1) segments will * be constructed. **/ -void cogl_path_polyline (CoglFixed *coords, +void cogl_path_polyline (float *coords, gint num_points); @@ -299,7 +285,7 @@ void cogl_path_polyline (CoglFixed *coords, * represents the Y coordinate of the first vertex, continuing in the same * fashion for the rest of the vertices. **/ -void cogl_path_polygon (CoglFixed *coords, +void cogl_path_polygon (float *coords, gint num_points); @@ -313,10 +299,10 @@ void cogl_path_polygon (CoglFixed *coords, * Constructs a rectangular shape at the given coordinates. If there * is an existing path this will start a new disjoint sub-path. **/ -void cogl_path_rectangle (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height); +void cogl_path_rectangle (float x, + float y, + float width, + float height); /** * cogl_path_ellipse: @@ -328,10 +314,10 @@ void cogl_path_rectangle (CoglFixed x, * Constructs an ellipse shape. If there is an existing path this will * start a new disjoint sub-path. **/ -void cogl_path_ellipse (CoglFixed center_x, - CoglFixed center_y, - CoglFixed radius_x, - CoglFixed radius_y); +void cogl_path_ellipse (float center_x, + float center_y, + float radius_x, + float radius_y); /** * cogl_path_round_rectangle: @@ -346,12 +332,12 @@ void cogl_path_ellipse (CoglFixed center_x, * Constructs a rectangular shape with rounded corners. If there is an * existing path this will start a new disjoint sub-path. **/ -void cogl_path_round_rectangle (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height, - CoglFixed radius, - CoglAngle arc_step); +void cogl_path_round_rectangle (float x, + float y, + float width, + float height, + float radius, + float arc_step); G_END_DECLS diff --git a/clutter/cogl/cogl-texture.h b/clutter/cogl/cogl-texture.h index 0b09f71c6..d21265304 100644 --- a/clutter/cogl/cogl-texture.h +++ b/clutter/cogl/cogl-texture.h @@ -41,73 +41,77 @@ G_BEGIN_DECLS * cogl_texture_new_with_size: * @width: width of texture in pixels. * @height: height of texture in pixels. - * @max_waste: maximum extra horizontal and|or vertical margin pixels to make - * texture fit GPU limitations. - * @auto_mipmap: enable or disable automatic generation of mipmap pyramid - * from the base level image whenever it is updated. + * @max_waste: maximum extra horizontal and|or vertical margin pixels + * to make the texture fit GPU limitations + * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture. + * texture. * - * Create a new texture with specified dimensions and pixel format. + * Creates a new COGL texture with the specified dimensions and pixel format. * - * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE - * if texture creation failed. + * Return value: a #CoglHandle to the newly created texture or + * %COGL_INVALID_HANDLE on failure + * + * Since: 0.8 */ -CoglHandle cogl_texture_new_with_size (guint width, - guint height, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format); +CoglHandle cogl_texture_new_with_size (guint width, + guint height, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format); /** * cogl_texture_new_from_file: * @filename: the file to load - * @max_waste: maximum extra horizontal and|or vertical margin pixels to make - * texture fit GPU limitations. - * @auto_mipmap: enable or disable automatic generation of mipmap pyramid - * from the base level image whenever it is updated. + * @max_waste: maximum extra horizontal and|or vertical margin pixels + * to make the texture fit GPU limitations + * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture. - * @error: a #GError or NULL. + * texture + * @error: return location for a #GError or %NULL * - * Load an image file from disk. + * Creates a COGL texture from an image file. * - * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE - * if creating the texture failed. + * Return value: a #CoglHandle to the newly created texture or + * %COGL_INVALID_HANDLE on failure + * + * Since: 0.8 */ -CoglHandle cogl_texture_new_from_file (const gchar *filename, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format, - GError **error); +CoglHandle cogl_texture_new_from_file (const gchar *filename, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format, + GError **error); /** * cogl_texture_new_from_data: - * @width: width of texture in pixels. - * @height: height of texture in pixels. - * @max_waste: maximum extra horizontal and|or vertical margin pixels to make - * @auto_mipmap: enable or disable automatic generation of mipmap pyramid - * from the base level image whenever it is updated. + * @width: width of texture in pixels + * @height: height of texture in pixels + * @max_waste: maximum extra horizontal and|or vertical margin pixels + * to make the texture fit GPU limitations + * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @internal_format: the #CoglPixelFormat that will be used for storing the - * buffer on the GPU. - * @rowstride: the memory offset in bytes between the starts of scanlines in - * @data. - * @data: pointer the memory region where the source buffer resides. + * @internal_format: the #CoglPixelFormat that will be used for storing + * the buffer on the GPU + * @rowstride: the memory offset in bytes between the starts of + * scanlines in @data + * @data: pointer the memory region where the source buffer resides * - * Create a new cogl texture based on data residing in memory. + * Creates a new COGL texture based on data residing in memory. * - * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE - * if creating the texture failed. + * Return value: a #CoglHandle to the newly created texture or + * %COGL_INVALID_HANDLE on failure + * + * Since: 0.8 */ -CoglHandle cogl_texture_new_from_data (guint width, - guint height, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat format, - CoglPixelFormat internal_format, - guint rowstride, - const guchar *data); +CoglHandle cogl_texture_new_from_data (guint width, + guint height, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat format, + CoglPixelFormat internal_format, + guint rowstride, + const guchar *data); /** * cogl_texture_new_from_foreign: @@ -119,12 +123,14 @@ CoglHandle cogl_texture_new_from_data (guint width, * @y_pot_waste: maximum vertical waste. * @format: format of the foreign texture. * - * Create a cogl texture based on an existing OpenGL texture, the width, height - * and format are passed along since it is not possible to query this from a - * handle with GLES 1.0. + * Creates a COGL texture based on an existing OpenGL texture; the + * width, height and format are passed along since it is not possible + * to query this from a handle with GLES 1.0. * - * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE - * if creating the texture failed. + * Return value: a #CoglHandle to the newly created texture or + * %COGL_INVALID_HANDLE on failure + * + * Since: 0.8 */ CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLenum gl_target, @@ -134,6 +140,27 @@ CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLuint y_pot_waste, CoglPixelFormat format); +/** + * cogl_texture_new_from_bitmap: + * @bitmap: a #CoglBitmap + * @max_waste: maximum extra horizontal and|or vertical margin pixels + * to make the texture fit GPU limitations + * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE + * @internal_format: the #CoglPixelFormat to use for the GPU storage of the + * texture + * + * Creates a COGL texture from a #CoglBitmap. + * + * Return value: a #CoglHandle to the newly created texture or + * %COGL_INVALID_HANDLE on failure + * + * Since: 1.0 + */ +CoglHandle cogl_texture_new_from_bitmap (CoglBitmap *bitmap, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format); + /** * cogl_is_texture: * @handle: A CoglHandle @@ -348,14 +375,14 @@ void cogl_texture_unref (CoglHandle handle); * texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0. */ void cogl_texture_rectangle (CoglHandle handle, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2); + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2); /** * cogl_texture_polygon: @@ -416,6 +443,45 @@ void cogl_material_rectangle (CoglFixed x1, gint tex_coords_len, const CoglFixed *tex_coords); +/** + * cogl_bitmap_new_from_file: + * @filename: the file to load. + * @error: a #GError or %NULL. + * + * Load an image file from disk. This function can be safely called from + * within a thread. + * + * Returns: A #CoglBitmap to the new loaded image data, or %NULL if loading + * the image failed. + * + * Since: 1.0 + */ +CoglBitmap * cogl_bitmap_new_from_file (const gchar *filename, + GError **error); + +/** + * cogl_bitmap_get_size_from_file: + * @filename: the file to check + * @width: return location for the bitmap width + * @height: return location for the bitmap height + * + * Parses an image file enough to extract the width and height + * of the bitmap. + * + * Since: 1.0 + */ +gboolean cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height); + +/** + * cogl_bitmap_free: + * @bmp: a #CoglBitmap. + * + * Frees a #CoglBitmap. + */ +void cogl_bitmap_free (CoglBitmap *bmp); + /** * cogl_texture_multiple_rectangles: * @handle: a @CoglHandle. @@ -427,16 +493,16 @@ void cogl_material_rectangle (CoglFixed x1, * significant performance boost to use this function rather than * calling cogl_texture_rectangle() separately for each rectangle. * - * @verts should point to an array of #CoglFixeds with + * @verts should point to an array of #floats with * @n_rects * 8 elements. Each group of 8 values corresponds to the * parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same * meaning as in cogl_texture_rectangle(). * - * Since: 1.0 + * Since: 0.8.6 */ void cogl_texture_multiple_rectangles (CoglHandle handle, - const CoglFixed *verts, + const float *verts, guint n_rects); G_END_DECLS diff --git a/clutter/cogl/cogl-types.h b/clutter/cogl/cogl-types.h index 3ae0d9caa..74b912318 100644 --- a/clutter/cogl/cogl-types.h +++ b/clutter/cogl/cogl-types.h @@ -28,6 +28,13 @@ G_BEGIN_DECLS +/** + * CoglBitmap: + * + * Type used for storing image data. + */ +typedef struct _CoglBitmap CoglBitmap; + /** * CoglHandle: * @@ -257,11 +264,26 @@ struct _CoglColor */ struct _CoglTextureVertex { - CoglFixed x, y, z; - CoglFixed tx, ty; + float x, y, z; + float tx, ty; CoglColor color; }; +/** + * CoglTextureFlags: + * @COGL_TEXTURE_NONE: No flags specified + * @COGL_TEXTURE_AUTO_MIPMAP: Enables the automatic generation of the + * mipmap pyramid from the base level image whenever it is updated + * + * Flags to pass to the cogl_texture_new_* family of functions. + * + * Since: 1.0 + */ +typedef enum { + COGL_TEXTURE_NONE = 0, + COGL_TEXTURE_AUTO_MIPMAP = 1 << 0 +} CoglTextureFlags; + G_END_DECLS #endif /* __COGL_TYPES_H__ */ diff --git a/clutter/cogl/cogl-mesh.h b/clutter/cogl/cogl-vertex-buffer.h similarity index 52% rename from clutter/cogl/cogl-mesh.h rename to clutter/cogl/cogl-vertex-buffer.h index e0c8f00c2..73b51e84d 100644 --- a/clutter/cogl/cogl-mesh.h +++ b/clutter/cogl/cogl-vertex-buffer.h @@ -1,9 +1,13 @@ -/* cogl-mesh.h: Handle extensible arrays of vertex attributes - * This file is part of Clutter +/* + * Cogl. + * + * An OpenGL/GLES Abstraction/Utility Layer + * + * Vertex Buffer API: Handle extensible arrays of vertex attributes * * Copyright (C) 2008 Intel Corporation. * - * Authored by: Robert Bragg + * Authored by: Robert Bragg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,8 +27,8 @@ #error "Only can be included directly." #endif -#ifndef __COGL_MESH_H__ -#define __COGL_MESH_H__ +#ifndef __COGL_VERTEX_BUFFER_H__ +#define __COGL_VERTEX_BUFFER_H__ #include #include @@ -32,42 +36,42 @@ G_BEGIN_DECLS /** - * SECTION:cogl-mesh + * SECTION:cogl-vertex-buffer * @short_description: An API for submitting extensible arrays of vertex * attributes to OpenGL in a way that aims to minimise * copying or reformatting of the original data. * - * The Mesh API is designed to be a fairly raw mechanism for developers - * to be able to submit geometry to Cogl in a format that can be directly - * consumed by an OpenGL driver and with awareness of the specific hardware - * being used then costly format conversion can also be avoided. + * The Attributes Buffer API is designed to be a fairly raw mechanism for + * developers to be able to submit geometry to Cogl in a format that can be + * directly consumed by an OpenGL driver and with awareness of the specific + * hardware being used then costly format conversion can also be avoided. * * They are designed to work on top of buffer objects and developers should - * understand that mesh objects are not cheap to create but once they - * have been submitted they are stored in GPU addressable memory and can + * understand that attribute buffers are not that cheap to create but once they + * have been submitted they can be stored in GPU addressable memory and can * be quickly reused. * - * Although this API does allow you to modify mesh objects after they have - * been submitted to the GPU you must note that modification is still - * not cheap, so if at all possible think of tricks that let you reuse - * a static buffer. To help with this, it is possible to enable and disable - * individual attributes cheaply. + * Although this API does allow you to modify attribute buffers after they have + * been submitted to the GPU you must note that modification is also not that + * cheap, so if at all possible think of tricks that let you reuse a static + * buffer. To help with this, it is possible to enable and disable individual + * attributes cheaply. * - * Take for example a mesh representing an elipse. If you were to submit - * a mesh with color attributes, texture coordinates and normals, then - * you would be able to draw an elipses in the following different ways - * without creating a new mesh: + * Take for example attributes representing an elipse. If you were to submit + * color attributes, texture coordinates and normals, then you would be able + * to draw an elipses in the following different ways without modifying + * the vertex buffer, only by changing your source material. * * Flat colored elipse * Textured elipse * Smoothly lit textured elipse blended with the color. * - * - * Another trick that can be used is submitting a highly detailed mesh - * and then using cogl_mesh_draw_range_elements to sample lower resolution - * geometry out from a fixed mesh. * - * The API doesn't currently give you any control over the actual buffer + * Another trick that can be used is submitting highly detailed vertices and + * then using cogl_vertex_buffer_draw_range_elements to sample sub-sets of + * the geometry or lower resolution geometry out from a fixed buffer. + * + * The API doesn't currently give you any control over the actual OpenGL buffer * objects that are created, but you can expect that when you first submit * your attributes they start off in one or more GL_STATIC_DRAW buffers. * If you then update some of your attributes; then these attributes will @@ -75,18 +79,18 @@ G_BEGIN_DECLS */ /** - * cogl_mesh_new: - * @n_vertices: The number of vertices that will make up your mesh. + * cogl_vertex_buffer_new: + * @n_vertices: The number of vertices that your attributes will correspond to. * - * This creates a Cogl handle for a new mesh that you can then start to add - * attributes too. + * This creates a Cogl handle for a new vertex buffer that you can then start + * to add attributes too. */ CoglHandle -cogl_mesh_new (guint n_vertices); +cogl_vertex_buffer_new (guint n_vertices); /** - * cogl_mesh_add_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_add: + * @handle: A vertex buffer handle * @attribute_name: The name of your attribute. It should be a valid GLSL * variable name and standard attribute types must use one * of following built-in names: (Note: they correspond to the @@ -115,90 +119,106 @@ cogl_mesh_new (guint n_vertices); * stride for both attributes is 6. The special value 0 means the * values are stored sequentially in memory. * @pointer: This addresses the first attribute in the vertex array. (This - * must remain valid until you call cogl_mesh_submit) + * must remain valid until you call cogl_vertex_buffer_submit) * - * This function lets you add an attribute to a mesh. You either use one + * This function lets you add an attribute to a buffer. You either use one * of the built-in names to add standard attributes, like positions, colors * and normals or you can add custom attributes for use in shaders. * - * Note: The number of vertices declared when creating the mesh is used to - * determine how many attribute values will be read from the supplied pointer. + * Note: The number of vertices declared when first creating the vertex + * buffer is used to determine how many attribute values will be read from the + * supplied pointer. * * Note: the data supplied here isn't copied anywhere until you call - * cogl_mesh_submit, so the supplied pointer must remain valid until then. - * (This is an important optimisation since we can't create a buffer - * object until we know about all the attributes, and repeatedly copying - * large buffers of vertex data may be very costly) If you add attributes - * after submitting then you will need to re-call cogl_mesh_submit to - * commit the changes to the GPU. (Be carefull to minimize the number of - * calls to cogl_mesh_submit though) + * cogl_vertex_buffer_submit, so the supplied pointer must remain valid + * until then. + * (This is an important optimisation since we can't create the underlying + * OpenGL buffer object until we know about all the attributes, and repeatedly + * copying large buffers of vertex data may be very costly) If you add + * attributes after submitting then you will need to re-call + * cogl_vertex_buffer_submit to commit the changes to the GPU. (Be carefull + * to minimize the number of calls to cogl_vertex_buffer_submit though) * * Note: If you are interleving attributes it is assumed that that each - * interleaved attribute starts no farther than +- stride bytes from - * the other attributes it is interleved with. I.e. this is ok: + * interleaved attribute starts no farther than +- stride bytes from the other + * attributes it is interleved with. I.e. this is ok: * |-0-0-0-0-0-0-0-0-0-0| * This is not ok: * |- - - - -0-0-0-0-0-0 0 0 0 0| * (Though you can have multiple groups of interleved attributes) */ void -cogl_mesh_add_attribute (CoglHandle handle, - const char *attribute_name, - guint8 n_components, - GLenum gl_type, - gboolean normalized, - guint16 stride, - const void *pointer); +cogl_vertex_buffer_add (CoglHandle handle, + const char *attribute_name, + guint8 n_components, + GLenum gl_type, + gboolean normalized, + guint16 stride, + const void *pointer); /** - * cogl_mesh_delete_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_delete: + * @handle: A vertex buffer handle * @attribute_name: The name of a previously added attribute * - * This function deletes an attribute from a mesh. You will need to - * call cogl_mesh_submit to commit this change to the GPU. + * This function deletes an attribute from a buffer. You will need to + * call cogl_vertex_buffer_submit to commit this change to the GPU. */ void -cogl_mesh_delete_attribute (CoglHandle handle, - const char *attribute_name); +cogl_vertex_buffer_delete (CoglHandle handle, + const char *attribute_name); /** - * cogl_mesh_enable_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_enable: + * @handle: A vertex buffer handle * @attribute_name: The name of the attribute you want to enable * * This function enables a previosuly added attribute * - * Since it is costly to create new mesh objects, then to make individual mesh - * objects more reuseable it is possible to enable and disable attributes - * before using a mesh for drawing. + * Since it can be costly to add and remove new attributes to buffers; to make + * individual buffers more reuseable it is possible to enable and disable + * attributes before using a buffer for drawing. * - * Note: You don't need to call cogl_mesh_submit after using this function + * Note: You don't need to call cogl_vertex_buffer_submit after using this + * function */ void -cogl_mesh_enable_attribute (CoglHandle handle, - const char *attribute_name); +cogl_vertex_buffer_enable (CoglHandle handle, + const char *attribute_name); /** - * cogl_mesh_disable_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_submit: + * @handle: A vertex buffer handle + * + * This function copies all the user added attributes into buffer objects + * managed by the OpenGL driver. + * + * You should aim to minimize calls to this function. + */ +void +cogl_vertex_buffer_submit (CoglHandle handle); + +/** + * cogl_vertex_buffer_disable: + * @handle: A vertex buffer handle * @attribute_name: The name of the attribute you want to disable * * This function disables a previosuly added attribute * - * Since it is costly to create new mesh objects, then to make individual mesh - * objects more reuseable it is possible to enable and disable attributes - * before using a mesh for drawing. + * Since it can be costly to add and remove new attributes to buffers; to make + * individual buffers more reuseable it is possible to enable and disable + * attributes before using a buffer for drawing. * - * Note: You don't need to call cogl_mesh_submit after using this function + * Note: You don't need to call cogl_vertex_buffer_submit after using this + * function */ void -cogl_mesh_disable_attribute (CoglHandle handle, - const char *attribute_name); +cogl_vertex_buffer_disable (CoglHandle handle, + const char *attribute_name); /** - * cogl_mesh_draw_arrays: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_draw: + * @handle: A vertex buffer handle * @mode: Specifies how the vertices should be interpreted, and should be * a valid GL primitive type: * @@ -215,17 +235,17 @@ cogl_mesh_disable_attribute (CoglHandle handle, * @count: Specifies the number of vertices you want to draw. * * This function lets you draw geometry using all or a subset of the - * vertices in a mesh object. + * vertices in a vertex buffer. */ void -cogl_mesh_draw_arrays (CoglHandle handle, - GLenum mode, - GLint first, - GLsizei count); +cogl_vertex_buffer_draw (CoglHandle handle, + GLenum mode, + GLint first, + GLsizei count); /** - * cogl_mesh_draw_range_elements: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_draw_range_elements: + * @handle: A vertex buffer handle * @mode: Specifies how the vertices should be interpreted, and should be * a valid GL primitive type: * @@ -238,11 +258,11 @@ cogl_mesh_draw_arrays (CoglHandle handle, * GL_TRIANGLES * * (Note: only types available in GLES are listed) - * @start: Specifies the minimum vertex index contained in indices - * @end: Specifies the maximum vertex index contained in indices + * @min_index: Specifies the minimum vertex index contained in indices + * @max_index: Specifies the maximum vertex index contained in indices * @count: Specifies the number of vertices you want to draw. - * @type: Specifies the data type used for the indices, and must be - * one of: + * @indices_type: Specifies the data type used for the indices, and must be + * one of: * * GL_UNSIGNED_BYTE * GL_UNSIGNED_SHORT @@ -251,49 +271,38 @@ cogl_mesh_draw_arrays (CoglHandle handle, * @indices: Specifies the address of your array of indices * * This function lets you use an array of indices to specify the vertices - * within your mesh pbject that you want to draw. + * within your vertex buffer that you want to draw. */ void -cogl_mesh_draw_range_elements (CoglHandle handle, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices); +cogl_vertex_buffer_draw_range_elements (CoglHandle handle, + GLenum mode, + GLuint min_index, + GLuint max_index, + GLsizei count, + GLenum indices_type, + const GLvoid *indices); /** - * cogl_mesh_submit: - * @handle: A Cogl mesh handle - * - * This function copies all the user added attributes into a buffer object - * managed by the OpenGL driver. - * - * After the attributes have been submitted, then you may no longer add or - * remove attributes from a mesh, though you can enable or disable them. - */ -void -cogl_mesh_submit (CoglHandle handle); - -/** - * cogl_mesh_ref: + * cogl_vertex_buffer_ref: * @handle: a @CoglHandle. * - * Increment the reference count for a cogl mesh. + * Increment the reference count for a vertex buffer * * Returns: the @handle. */ -CoglHandle cogl_mesh_ref (CoglHandle handle); +CoglHandle +cogl_vertex_buffer_ref (CoglHandle handle); /** - * cogl_mesh_unref: + * cogl_vertex_buffer_unref: * @handle: a @CoglHandle. * - * Deccrement the reference count for a cogl mesh. + * Decrement the reference count for a vertex buffer */ -void cogl_mesh_unref (CoglHandle handle); +void +cogl_vertex_buffer_unref (CoglHandle handle); G_END_DECLS -#endif /* __COGL_MESH_H__ */ +#endif /* __COGL_VERTEX_BUFFER_H__ */ diff --git a/clutter/cogl/cogl.h.in b/clutter/cogl/cogl.h.in index 091770227..18612aacc 100644 --- a/clutter/cogl/cogl.h.in +++ b/clutter/cogl/cogl.h.in @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -145,10 +146,10 @@ void cogl_get_bitmasks (gint *red, * Replaces the current projection matrix with a perspective matrix * based on the provided values. */ -void cogl_perspective (CoglFixed fovy, - CoglFixed aspect, - CoglFixed z_near, - CoglFixed z_far); +void cogl_perspective (float fovy, + float aspect, + float z_near, + float z_far); /** * cogl_frustum: @@ -164,12 +165,12 @@ void cogl_perspective (CoglFixed fovy, * * Since: 0.8.2 */ -void cogl_frustum (CoglFixed left, - CoglFixed right, - CoglFixed bottom, - CoglFixed top, - CoglFixed z_near, - CoglFixed z_far); +void cogl_frustum (float left, + float right, + float bottom, + float top, + float z_near, + float z_far); /** * cogl_setup_viewport: @@ -189,10 +190,10 @@ void cogl_frustum (CoglFixed left, */ void cogl_setup_viewport (guint width, guint height, - CoglFixed fovy, - CoglFixed aspect, - CoglFixed z_near, - CoglFixed z_far); + float fovy, + float aspect, + float z_near, + float z_far); /** * cogl_viewport: @@ -229,21 +230,8 @@ void cogl_pop_matrix (void); * Multiplies the current model-view matrix by one that scales the x * and y axes by the given values. */ -void cogl_scale (CoglFixed x, - CoglFixed y); - -/** - * cogl_translatex: - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current model-view matrix by one that translates the - * model along all three axes according to the given values. - */ -void cogl_translatex (CoglFixed x, - CoglFixed y, - CoglFixed z); +void cogl_scale (float x, + float y); /** * cogl_translate: @@ -251,16 +239,15 @@ void cogl_translatex (CoglFixed x, * @y: Distance to translate along the y-axis * @z: Distance to translate along the z-axis * - * Integer version of cogl_translatex(). Multiplies the current - * model-view matrix by one that translates the model along all three - * axes according to the given values. + * Multiplies the current model-view matrix by one that translates the + * model along all three axes according to the given values. */ -void cogl_translate (gint x, - gint y, - gint z); +void cogl_translate (float x, + float y, + float z); /** - * cogl_rotatex: + * cogl_rotate: * @angle: Angle in degrees to rotate. * @x: X-component of vertex to rotate around. * @y: Y-component of vertex to rotate around. @@ -272,55 +259,39 @@ void cogl_translate (gint x, * degrees about the vertex (0, 0, 1) causes a small counter-clockwise * rotation. */ -void cogl_rotatex (CoglFixed angle, - gint x, - gint y, - gint z); - -/** - * cogl_rotate: - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Integer version of cogl_rotatex(). Multiplies the current - * model-view matrix by one that rotates the model around the vertex - * specified by @x, @y and @z. - */ -void cogl_rotate (gint angle, - gint x, - gint y, - gint z); +void cogl_rotate (float angle, + float x, + float y, + float z); /** * cogl_get_modelview_matrix: - * @m: pointer to a 4x4 array of #CoglFixeds to receive the matrix + * @m: pointer to a 4x4 array of #floats to receive the matrix * * Stores the current model-view matrix in @m. The matrix is in * column-major order. */ -void cogl_get_modelview_matrix (CoglFixed m[16]); +void cogl_get_modelview_matrix (float m[16]); /** * cogl_get_projection_matrix: - * @m: pointer to a 4x4 array of #CoglFixeds to receive the matrix + * @m: pointer to a 4x4 array of #floats to receive the matrix * * Stores the current projection matrix in @m. The matrix is in * column-major order. */ -void cogl_get_projection_matrix (CoglFixed m[16]); +void cogl_get_projection_matrix (float m[16]); /** * cogl_get_viewport: - * @v: pointer to a 4 element array of #CoglFixeds to + * @v: pointer to a 4 element array of #floats to * receive the viewport dimensions. * * Stores the current viewport in @v. @v[0] and @v[1] get the x and y * position of the viewport and @v[2] and @v[3] get the width and * height. */ -void cogl_get_viewport (CoglFixed v[4]); +void cogl_get_viewport (float v[4]); /** * cogl_clip_set: @@ -338,10 +309,10 @@ void cogl_get_viewport (CoglFixed v[4]); * The rectangle is intersected with the current clip region. To undo * the effect of this function, call cogl_clip_unset(). */ -void cogl_clip_set (CoglFixed x_offset, - CoglFixed y_offset, - CoglFixed width, - CoglFixed height); +void cogl_clip_set (float x_offset, + float y_offset, + float width, + float height); /** * cogl_clip_set_from_path: @@ -444,8 +415,8 @@ void cogl_enable_backface_culling (gboolean setting); * comparing with the value in @ref. The default function is CGL_ALWAYS the * initial reference value is 1.0. */ -void cogl_alpha_func (COGLenum func, - CoglFixed ref); +void cogl_alpha_func (COGLenum func, + float ref); /** * cogl_fog_set: @@ -462,9 +433,9 @@ void cogl_alpha_func (COGLenum func, * cogl_paint_init(). */ void cogl_fog_set (const CoglColor *fog_color, - CoglFixed density, - CoglFixed z_near, - CoglFixed z_far); + float density, + float z_near, + float z_far); /** * cogl_paint_init: diff --git a/clutter/cogl/common/Makefile.am b/clutter/cogl/common/Makefile.am index c87f42a5d..39a3a5385 100644 --- a/clutter/cogl/common/Makefile.am +++ b/clutter/cogl/common/Makefile.am @@ -30,6 +30,7 @@ libclutter_cogl_common_la_SOURCES = \ cogl-clip-stack.c \ cogl-fixed.c \ cogl-color.c \ - cogl-mesh.c \ + cogl-vertex-buffer-private.h \ + cogl-vertex-buffer.c \ cogl-matrix.c \ cogl-material.c diff --git a/clutter/cogl/common/cogl-bitmap-pixbuf.c b/clutter/cogl/common/cogl-bitmap-pixbuf.c index 77316dff5..8d86d94e4 100644 --- a/clutter/cogl/common/cogl-bitmap-pixbuf.c +++ b/clutter/cogl/common/cogl-bitmap-pixbuf.c @@ -84,6 +84,20 @@ cogl_bitmap_error_quark (void) return g_quark_from_static_string ("cogl-bitmap-error-quark"); } +gboolean +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + if (width) + *width = 0; + + if (height) + *height = 0; + + return TRUE; +} + /* the error does not contain the filename as the caller already has it */ gboolean _cogl_bitmap_from_file (CoglBitmap *bmp, @@ -177,9 +191,22 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, #elif defined(USE_GDKPIXBUF) gboolean -_cogl_bitmap_from_file (CoglBitmap *bmp, - const gchar *filename, - GError **error) +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + g_return_val_if_fail (filename != NULL, FALSE); + + if (gdk_pixbuf_get_file_info (filename, width, height) != NULL) + return TRUE; + + return FALSE; +} + +gboolean +_cogl_bitmap_from_file (CoglBitmap *bmp, + const gchar *filename, + GError **error) { GdkPixbuf *pixbuf; gboolean has_alpha; @@ -198,11 +225,13 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (bmp == NULL) return FALSE; - + if (bmp == NULL) + return FALSE; + /* Load from file using GdkPixbuf */ pixbuf = gdk_pixbuf_new_from_file (filename, error); - if (pixbuf == NULL) return FALSE; + if (pixbuf == NULL) + return FALSE; /* Get pixbuf properties */ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); @@ -278,6 +307,20 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, #include "stb_image.c" +gboolean +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + if (width) + *width = 0; + + if (height) + *height = 0; + + return TRUE; +} + gboolean _cogl_bitmap_from_file (CoglBitmap *bmp, const gchar *filename, @@ -290,11 +333,15 @@ _cogl_bitmap_from_file (CoglBitmap *bmp, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (bmp == NULL) return FALSE; + if (bmp == NULL) + return FALSE; /* Load from file using stb */ - pixels = stbi_load (filename, &width, &height, &stb_pixel_format, STBI_rgb_alpha); - if (pixels == NULL) return FALSE; + pixels = stbi_load (filename, + &width, &height, &stb_pixel_format, + STBI_rgb_alpha); + if (pixels == NULL) + return FALSE; /* Store bitmap info */ bmp->data = g_memdup (pixels, height * width * 4); diff --git a/clutter/cogl/common/cogl-bitmap.c b/clutter/cogl/common/cogl-bitmap.c index 39341e0b0..b0a3b7138 100644 --- a/clutter/cogl/common/cogl-bitmap.c +++ b/clutter/cogl/common/cogl-bitmap.c @@ -148,3 +148,42 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, dstdata += dst->rowstride; } } + +gboolean +cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height) +{ + return _cogl_bitmap_get_size_from_file (filename, width, height); +} + +CoglBitmap * +cogl_bitmap_new_from_file (const gchar *filename, + GError **error) +{ + CoglBitmap bmp; + + g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); + + /* Try loading with imaging backend */ + if (!_cogl_bitmap_from_file (&bmp, filename, error)) + { + /* Try fallback */ + if (!_cogl_bitmap_fallback_from_file (&bmp, filename)) + return NULL; + else if (error && *error) + { + g_error_free (*error); + *error = NULL; + } + } + + return (CoglBitmap *) g_memdup (&bmp, sizeof (CoglBitmap)); +} + +void +cogl_bitmap_free (CoglBitmap *bmp) +{ + g_free (bmp->data); + g_free (bmp); +} diff --git a/clutter/cogl/common/cogl-bitmap.h b/clutter/cogl/common/cogl-bitmap.h index ca9f8a9c3..953ac5a32 100644 --- a/clutter/cogl/common/cogl-bitmap.h +++ b/clutter/cogl/common/cogl-bitmap.h @@ -28,8 +28,6 @@ #include -typedef struct _CoglBitmap CoglBitmap; - struct _CoglBitmap { guchar *data; @@ -92,4 +90,9 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, gint width, gint height); +gboolean +_cogl_bitmap_get_size_from_file (const gchar *filename, + gint *width, + gint *height); + #endif /* __COGL_BITMAP_H */ diff --git a/clutter/cogl/common/cogl-clip-stack.c b/clutter/cogl/common/cogl-clip-stack.c index c533b0b4c..9d8a623e9 100644 --- a/clutter/cogl/common/cogl-clip-stack.c +++ b/clutter/cogl/common/cogl-clip-stack.c @@ -35,24 +35,24 @@ /* These are defined in the particular backend (float in GL vs fixed in GL ES) */ -void _cogl_set_clip_planes (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height); -void _cogl_add_stencil_clip (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height, +void _cogl_set_clip_planes (float x, + float y, + float width, + float height); +void _cogl_add_stencil_clip (float x, + float y, + float width, + float height, gboolean first); -void _cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, - CoglFixedVec2 nodes_max, +void _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min, + floatVec2 nodes_max, guint path_size, CoglPathNode *path, gboolean merge); void _cogl_enable_clip_planes (void); void _cogl_disable_clip_planes (void); void _cogl_disable_stencil_buffer (void); -void _cogl_set_matrix (const CoglFixed *matrix); +void _cogl_set_matrix (const float *matrix); typedef struct _CoglClipStack CoglClipStack; @@ -75,13 +75,13 @@ struct _CoglClipStackEntryRect CoglClipStackEntryType type; /* The rectangle for this clip */ - CoglFixed x_offset; - CoglFixed y_offset; - CoglFixed width; - CoglFixed height; + float x_offset; + float y_offset; + float width; + float height; /* The matrix that was current when the clip was set */ - CoglFixed matrix[16]; + float matrix[16]; }; struct _CoglClipStackEntryPath @@ -89,20 +89,20 @@ struct _CoglClipStackEntryPath CoglClipStackEntryType type; /* The matrix that was current when the clip was set */ - CoglFixed matrix[16]; + float matrix[16]; - CoglFixedVec2 path_nodes_min; - CoglFixedVec2 path_nodes_max; + floatVec2 path_nodes_min; + floatVec2 path_nodes_max; guint path_size; CoglPathNode path[1]; }; void -cogl_clip_set (CoglFixed x_offset, - CoglFixed y_offset, - CoglFixed width, - CoglFixed height) +cogl_clip_set (float x_offset, + float y_offset, + float width, + float height) { CoglClipStackEntryRect *entry; CoglClipStack *stack; diff --git a/clutter/cogl/common/cogl-color.c b/clutter/cogl/common/cogl-color.c index a248b95c9..e4b74c6b0 100644 --- a/clutter/cogl/common/cogl-color.c +++ b/clutter/cogl/common/cogl-color.c @@ -58,18 +58,18 @@ cogl_color_set_from_4d (CoglColor *dest, } void -cogl_color_set_from_4x (CoglColor *dest, - CoglFixed red, - CoglFixed green, - CoglFixed blue, - CoglFixed alpha) +cogl_color_set_from_4f (CoglColor *dest, + float red, + float green, + float blue, + float alpha) { g_return_if_fail (dest != NULL); - dest->red = COGL_FIXED_TO_INT (red * 255); - dest->green = COGL_FIXED_TO_INT (green * 255); - dest->blue = COGL_FIXED_TO_INT (blue * 255); - dest->alpha = COGL_FIXED_TO_INT (alpha * 255); + dest->red = (red * 255); + dest->green = (green * 255); + dest->blue = (blue * 255); + dest->alpha = (alpha * 255); } unsigned char @@ -84,10 +84,10 @@ cogl_color_get_red_float (const CoglColor *color) return (float) color->red / 255.0; } -CoglFixed +float cogl_color_get_red (const CoglColor *color) { - return COGL_FIXED_FROM_FLOAT ((float) color->red / 255.0); + return ((float) color->red / 255.0); } unsigned char @@ -102,10 +102,10 @@ cogl_color_get_green_float (const CoglColor *color) return (float) color->green / 255.0; } -CoglFixed +float cogl_color_get_green (const CoglColor *color) { - return COGL_FIXED_FROM_FLOAT ((float) color->green / 255.0); + return ((float) color->green / 255.0); } unsigned char @@ -120,10 +120,10 @@ cogl_color_get_blue_float (const CoglColor *color) return (float) color->blue / 255.0; } -CoglFixed +float cogl_color_get_blue (const CoglColor *color) { - return COGL_FIXED_FROM_FLOAT ((float) color->blue / 255.0); + return ((float) color->blue / 255.0); } unsigned char @@ -138,10 +138,10 @@ cogl_color_get_alpha_float (const CoglColor *color) return (float) color->alpha / 255.0; } -CoglFixed +float cogl_color_get_alpha (const CoglColor *color) { - return COGL_FIXED_FROM_FLOAT ((float) color->alpha / 255.0); + return ((float) color->alpha / 255.0); } void @@ -157,13 +157,13 @@ cogl_set_source_color4ub (guint8 red, } void -cogl_set_source_color4x (CoglFixed red, - CoglFixed green, - CoglFixed blue, - CoglFixed alpha) +cogl_set_source_color4f (float red, + float green, + float blue, + float alpha) { CoglColor c = { 0, }; - cogl_color_set_from_4x (&c, red, green, blue, alpha); + cogl_color_set_from_4f (&c, red, green, blue, alpha); cogl_set_source_color (&c); } diff --git a/clutter/cogl/common/cogl-fixed.c b/clutter/cogl/common/cogl-fixed.c index 348d2ce28..846ede800 100644 --- a/clutter/cogl/common/cogl-fixed.c +++ b/clutter/cogl/common/cogl-fixed.c @@ -10,10 +10,12 @@ * * Currently contains 257 entries. * - * The current error (compared to system sin) is about - * 0.5% for values near the start of the table where the - * curve is steep, but improving rapidly. If this precision - * is not enough, we can increase the size of the table + * The current maximum absolute error is about 1.9e-0.5 + * and is greatest around pi/2 where the second derivative + * of sin(x) is greatest. If greater accuracy is needed, + * modestly increasing the table size, or maybe using + * quadratic interpolation would drop the interpolation + * error below the precision limits of CoglFixed. */ static const CoglFixed sin_tbl[] = { @@ -270,7 +272,7 @@ static const CoglFixed sqrt_tbl[] = /* the difference of the angle for two adjacent values in the * sin_tbl table, expressed as CoglFixed number */ -#define COGL_SIN_STEP 0x00000192 +static const gint sin_tbl_size = G_N_ELEMENTS (sin_tbl) - 1; static const double _magic = 68719476736.0 * 1.5; @@ -363,7 +365,9 @@ CoglFixed cogl_fixed_sin (CoglFixed angle) { int sign = 1, indx1, indx2; - CoglFixed low, high, d1, d2; + CoglFixed low, high; + CoglFixed p1, p2; + CoglFixed d1, d2; /* convert negative angle to positive + sign */ if ((int) angle < 0) @@ -401,14 +405,17 @@ cogl_fixed_sin (CoglFixed angle) } /* Calculate indices of the two nearest values in our table - * and return weighted average + * and return weighted average. + * + * We multiple first than divide to preserve precision. Since + * angle is in the first quadrant, angle * SIN_TBL_SIZE (=256) + * can't overflow. * * Handle the end of the table gracefully */ - indx1 = COGL_FIXED_DIV (angle, COGL_SIN_STEP); - indx1 = COGL_FIXED_TO_INT (indx1); + indx1 = (angle * sin_tbl_size) / COGL_FIXED_PI_2; - if (indx1 == (G_N_ELEMENTS (sin_tbl) - 1)) + if (indx1 == sin_tbl_size) { indx2 = indx1; indx1 = indx2 - 1; @@ -421,10 +428,13 @@ cogl_fixed_sin (CoglFixed angle) low = sin_tbl[indx1]; high = sin_tbl[indx2]; - d1 = angle - indx1 * COGL_SIN_STEP; - d2 = indx2 * COGL_SIN_STEP - angle; + /* Again multiply the divide; no danger of overflow */ + p1 = (indx1 * COGL_FIXED_PI_2) / sin_tbl_size; + p2 = (indx2 * COGL_FIXED_PI_2) / sin_tbl_size; + d1 = angle - p1; + d2 = p2 - angle; - angle = ((low * d2 + high * d1) / (COGL_SIN_STEP)); + angle = ((low * d2 + high * d1) / (p2 - p1)); if (sign < 0) angle = -angle; @@ -481,6 +491,12 @@ cogl_angle_sin (CoglAngle angle) return result; } +CoglFixed +cogl_fixed_tan (CoglFixed angle) +{ + return cogl_angle_tan (COGL_ANGLE_FROM_DEGX (angle)); +} + CoglFixed cogl_angle_tan (CoglAngle angle) { diff --git a/clutter/cogl/common/cogl-mesh-private.h b/clutter/cogl/common/cogl-mesh-private.h deleted file mode 100644 index db014c3bd..000000000 --- a/clutter/cogl/common/cogl-mesh-private.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Clutter COGL - * - * A basic GL/GLES Abstraction/Utility Layer - * - * Authored By Robert Bragg - * - * Copyright (C) 2008 Intel - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __COGL_MESH_H -#define __COGL_MESH_H - -/* Note we put quite a bit into the flags here to help keep - * the down size of the CoglMeshAttribute struct below. */ -typedef enum _CoglMeshAttributeFlags -{ - /* Types */ - /* NB: update the _TYPE_MASK below if these are changed */ - COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY = 1<<0, - COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY = 1<<1, - COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY = 1<<2, - COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY = 1<<3, - COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY = 1<<4, - COGL_MESH_ATTRIBUTE_FLAG_INVALID = 1<<5, - - COGL_MESH_ATTRIBUTE_FLAG_NORMALIZED = 1<<6, - COGL_MESH_ATTRIBUTE_FLAG_ENABLED = 1<<7, - - /* Usage hints */ - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_MESH_ATTRIBUTE_FLAG_INFREQUENT_RESUBMIT = 1<<8, - COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT = 1<<9, - - /* GL Data types */ - /* NB: Update the _GL_TYPE_MASK below if these are changed */ - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE = 1<<10, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE = 1<<11, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT = 1<<12, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT = 1<<14, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT = 1<<15, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT = 1<<16, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE = 1<<17, - - COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED = 1<<18, - COGL_MESH_ATTRIBUTE_FLAG_UNUSED = 1<<19 - - /* XXX NB: If we need > 24 bits then look at changing the layout - * of struct _CoglMeshAttribute below */ -} CoglMeshAttributeFlags; - -#define COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK \ - (COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_INVALID) - -#define COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_MASK \ - (COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE) - - -typedef struct _CoglMeshAttribute -{ - /* TODO: look at breaking up the flags into seperate - * bitfields and seperate enums */ - CoglMeshAttributeFlags flags:24; - guint8 id; - GQuark name; - union _u - { - const void *pointer; - gsize vbo_offset; - } u; - gsize span_bytes; - guint16 stride; - guint8 n_components; - guint8 texture_unit; - -} CoglMeshAttribute; - -typedef enum _CoglMeshVBOFlags -{ - COGL_MESH_VBO_FLAG_UNSTRIDED = 1<<0, - COGL_MESH_VBO_FLAG_STRIDED = 1<<1, - COGL_MESH_VBO_FLAG_MULTIPACK = 1<<2, - - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT = 1<<3, - COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT = 1<<4, - - COGL_MESH_VBO_FLAG_SUBMITTED = 1<<5 -} CoglMeshVBOFlags; - -/* - * A CoglMeshVBO represents one or more attributes in a single buffer object - */ -typedef struct _CoglMeshVBO -{ - CoglMeshVBOFlags flags; - GLuint vbo_name; /*!< The name of the corresponding buffer object */ - gsize vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */ - GList *attributes; -} CoglMeshVBO; - - -typedef struct _CoglMesh -{ - guint ref_count; - guint n_vertices; /*!< The number of vertices in the mesh */ - GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ - - /* Note: new_attributes is normally NULL and only valid while - * modifying a mesh object. */ - GList *new_attributes; /*!< attributes pending submission */ -} CoglMesh; - -#endif /* __COGL_MESH_H */ - diff --git a/clutter/cogl/common/cogl-primitives.c b/clutter/cogl/common/cogl-primitives.c index a063331f2..7e9b1b94e 100644 --- a/clutter/cogl/common/cogl-primitives.c +++ b/clutter/cogl/common/cogl-primitives.c @@ -33,46 +33,31 @@ #include #include +#include #define _COGL_MAX_BEZ_RECURSE_DEPTH 16 /* these are defined in the particular backend(float in gl vs fixed in gles)*/ void _cogl_path_add_node (gboolean new_sub_path, - CoglFixed x, - CoglFixed y); + float x, + float y); void _cogl_path_fill_nodes (); void _cogl_path_stroke_nodes (); -void _cogl_rectangle (gint x, - gint y, - guint width, - guint height); -void _cogl_rectanglex (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height); +void _cogl_rectangle (float x, + float y, + float width, + float height); void -cogl_rectangle (gint x, - gint y, - guint width, - guint height) +cogl_rectangle (float x, + float y, + float width, + float height) { cogl_clip_ensure (); _cogl_rectangle (x, y, width, height); } -void -cogl_rectanglex (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height) -{ - cogl_clip_ensure (); - - _cogl_rectanglex (x, y, width, height); -} - - void cogl_path_fill (void) { @@ -116,8 +101,8 @@ cogl_path_stroke_preserve (void) } void -cogl_path_move_to (CoglFixed x, - CoglFixed y) +cogl_path_move_to (float x, + float y) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -132,8 +117,8 @@ cogl_path_move_to (CoglFixed x, } void -cogl_path_rel_move_to (CoglFixed x, - CoglFixed y) +cogl_path_rel_move_to (float x, + float y) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -142,8 +127,8 @@ cogl_path_rel_move_to (CoglFixed x, } void -cogl_path_line_to (CoglFixed x, - CoglFixed y) +cogl_path_line_to (float x, + float y) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -154,8 +139,8 @@ cogl_path_line_to (CoglFixed x, } void -cogl_path_rel_line_to (CoglFixed x, - CoglFixed y) +cogl_path_rel_line_to (float x, + float y) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -181,17 +166,17 @@ cogl_path_new (void) } void -cogl_path_line (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2) +cogl_path_line (float x1, + float y1, + float x2, + float y2) { cogl_path_move_to (x1, y1); cogl_path_line_to (x2, y2); } void -cogl_path_polyline (CoglFixed *coords, +cogl_path_polyline (float *coords, gint num_points) { gint c = 0; @@ -203,7 +188,7 @@ cogl_path_polyline (CoglFixed *coords, } void -cogl_path_polygon (CoglFixed *coords, +cogl_path_polygon (float *coords, gint num_points) { cogl_path_polyline (coords, num_points); @@ -211,10 +196,10 @@ cogl_path_polygon (CoglFixed *coords, } void -cogl_path_rectangle (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height) +cogl_path_rectangle (float x, + float y, + float width, + float height) { cogl_path_move_to (x, y); cogl_path_line_to (x + width, y); @@ -224,20 +209,20 @@ cogl_path_rectangle (CoglFixed x, } static void -_cogl_path_arc (CoglFixed center_x, - CoglFixed center_y, - CoglFixed radius_x, - CoglFixed radius_y, - CoglAngle angle_1, - CoglAngle angle_2, - CoglAngle angle_step, +_cogl_path_arc (float center_x, + float center_y, + float radius_x, + float radius_y, + float angle_1, + float angle_2, + float angle_step, guint move_first) { - CoglAngle a = 0x0; - CoglFixed cosa = 0x0; - CoglFixed sina = 0x0; - CoglFixed px = 0x0; - CoglFixed py = 0x0; + float a = 0x0; + float cosa = 0x0; + float sina = 0x0; + float px = 0x0; + float py = 0x0; /* Fix invalid angles */ @@ -252,11 +237,11 @@ _cogl_path_arc (CoglFixed center_x, a = angle_1; while (a != angle_2) { - cosa = cogl_angle_cos (a); - sina = cogl_angle_sin (a); + cosa = cosf (a * (G_PI/180.0)); + sina = sinf (a * (G_PI/180.0)); - px = center_x + COGL_FIXED_MUL (cosa, radius_x); - py = center_y + COGL_FIXED_MUL (sina, radius_y); + px = center_x + (cosa * radius_x); + py = center_y + (sina * radius_y); if (a == angle_1 && move_first) cogl_path_move_to (px, py); @@ -279,24 +264,24 @@ _cogl_path_arc (CoglFixed center_x, /* Make sure the final point is drawn */ - cosa = cogl_angle_cos (angle_2); - sina = cogl_angle_sin (angle_2); + cosa = cosf (angle_2 * (G_PI/180.0)); + sina = sinf (angle_2 * (G_PI/180.0)); - px = center_x + COGL_FIXED_MUL (cosa, radius_x); - py = center_y + COGL_FIXED_MUL (sina, radius_y); + px = center_x + (cosa * radius_x); + py = center_y + (sina * radius_y); cogl_path_line_to (px, py); } void -cogl_path_arc (CoglFixed center_x, - CoglFixed center_y, - CoglFixed radius_x, - CoglFixed radius_y, - CoglAngle angle_1, - CoglAngle angle_2) +cogl_path_arc (float center_x, + float center_y, + float radius_x, + float radius_y, + float angle_1, + float angle_2) { - CoglAngle angle_step = 10; + float angle_step = 10; /* it is documented that a move to is needed to create a freestanding * arc */ @@ -308,13 +293,13 @@ cogl_path_arc (CoglFixed center_x, void -cogl_path_arc_rel (CoglFixed center_x, - CoglFixed center_y, - CoglFixed radius_x, - CoglFixed radius_y, - CoglAngle angle_1, - CoglAngle angle_2, - CoglAngle angle_step) +cogl_path_arc_rel (float center_x, + float center_y, + float radius_x, + float radius_y, + float angle_1, + float angle_2, + float angle_step) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -326,50 +311,50 @@ cogl_path_arc_rel (CoglFixed center_x, } void -cogl_path_ellipse (CoglFixed center_x, - CoglFixed center_y, - CoglFixed radius_x, - CoglFixed radius_y) +cogl_path_ellipse (float center_x, + float center_y, + float radius_x, + float radius_y) { - CoglAngle angle_step = 10; + float angle_step = 10; /* FIXME: if shows to be slow might be optimized * by mirroring just a quarter of it */ _cogl_path_arc (center_x, center_y, radius_x, radius_y, - 0, COGL_ANGLE_FROM_DEG (360), + 0, 360, angle_step, 1 /* move first */); cogl_path_close(); } void -cogl_path_round_rectangle (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height, - CoglFixed radius, - CoglAngle arc_step) +cogl_path_round_rectangle (float x, + float y, + float width, + float height, + float radius, + float arc_step) { - CoglFixed inner_width = width - (radius << 1); - CoglFixed inner_height = height - (radius << 1); + float inner_width = width - (radius * 2); + float inner_height = height - (radius * 2); _COGL_GET_CONTEXT (ctx, NO_RETVAL); cogl_path_move_to (x, y + radius); cogl_path_arc_rel (radius, 0, radius, radius, - COGL_ANGLE_FROM_DEG (180), - COGL_ANGLE_FROM_DEG (270), + 180, + 270, arc_step); cogl_path_line_to (ctx->path_pen.x + inner_width, ctx->path_pen.y); cogl_path_arc_rel (0, radius, radius, radius, - COGL_ANGLE_FROM_DEG (-90), - COGL_ANGLE_FROM_DEG (0), + -90, + 0, arc_step); cogl_path_line_to (ctx->path_pen.x, @@ -377,16 +362,16 @@ cogl_path_round_rectangle (CoglFixed x, cogl_path_arc_rel (-radius, 0, radius, radius, - COGL_ANGLE_FROM_DEG (0), - COGL_ANGLE_FROM_DEG (90), + 0, + 90, arc_step); cogl_path_line_to (ctx->path_pen.x - inner_width, ctx->path_pen.y); cogl_path_arc_rel (0, -radius, radius, radius, - COGL_ANGLE_FROM_DEG (90), - COGL_ANGLE_FROM_DEG (180), + 90, + 180, arc_step); cogl_path_close (); @@ -400,14 +385,14 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic) CoglBezCubic *cleft; CoglBezCubic *cright; CoglBezCubic *c; - CoglFixedVec2 dif1; - CoglFixedVec2 dif2; - CoglFixedVec2 mm; - CoglFixedVec2 c1; - CoglFixedVec2 c2; - CoglFixedVec2 c3; - CoglFixedVec2 c4; - CoglFixedVec2 c5; + floatVec2 dif1; + floatVec2 dif2; + floatVec2 mm; + floatVec2 c1; + floatVec2 c2; + floatVec2 c3; + floatVec2 c4; + floatVec2 c5; gint cindex; /* Put first curve on stack */ @@ -418,16 +403,13 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic) { c = &cubics[cindex]; -#define CFX_MUL2(x) ((x) << 1) -#define CFX_MUL3(x) (((x) << 1) + (x)) -#define CFX_SQ(x) COGL_FIXED_MUL (x, x) /* Calculate distance of control points from their * counterparts on the line between end points */ - dif1.x = CFX_MUL3 (c->p2.x) - CFX_MUL2 (c->p1.x) - c->p4.x; - dif1.y = CFX_MUL3 (c->p2.y) - CFX_MUL2 (c->p1.y) - c->p4.y; - dif2.x = CFX_MUL3 (c->p3.x) - CFX_MUL2 (c->p4.x) - c->p1.x; - dif2.y = CFX_MUL3 (c->p3.y) - CFX_MUL2 (c->p4.y) - c->p1.y; + dif1.x = (c->p2.x * 3) - (c->p1.x * 2) - c->p4.x; + dif1.y = (c->p2.y * 3) - (c->p1.y * 2) - c->p4.y; + dif2.x = (c->p3.x * 3) - (c->p4.x * 2) - c->p1.x; + dif2.y = (c->p3.y * 3) - (c->p4.y * 2) - c->p1.y; if (dif1.x < 0) dif1.x = -dif1.x; @@ -438,16 +420,13 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic) if (dif2.y < 0) dif2.y = -dif2.y; -#undef CFX_MUL2 -#undef CFX_MUL3 -#undef CFX_SQ /* Pick the greatest of two distances */ if (dif1.x < dif2.x) dif1.x = dif2.x; if (dif1.y < dif2.y) dif1.y = dif2.y; /* Cancel if the curve is flat enough */ - if (dif1.x + dif1.y <= COGL_FIXED_1 || + if (dif1.x + dif1.y <= 1.0 || cindex == _COGL_MAX_BEZ_RECURSE_DEPTH-1) { /* Add subdivision point (skip last) */ @@ -465,20 +444,20 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic) cright = c; cleft = &cubics[++cindex]; /* Subdivide into 2 sub-curves */ - c1.x = ((c->p1.x + c->p2.x) >> 1); - c1.y = ((c->p1.y + c->p2.y) >> 1); - mm.x = ((c->p2.x + c->p3.x) >> 1); - mm.y = ((c->p2.y + c->p3.y) >> 1); - c5.x = ((c->p3.x + c->p4.x) >> 1); - c5.y = ((c->p3.y + c->p4.y) >> 1); + c1.x = ((c->p1.x + c->p2.x) / 2); + c1.y = ((c->p1.y + c->p2.y) / 2); + mm.x = ((c->p2.x + c->p3.x) / 2); + mm.y = ((c->p2.y + c->p3.y) / 2); + c5.x = ((c->p3.x + c->p4.x) / 2); + c5.y = ((c->p3.y + c->p4.y) / 2); - c2.x = ((c1.x + mm.x) >> 1); - c2.y = ((c1.y + mm.y) >> 1); - c4.x = ((mm.x + c5.x) >> 1); - c4.y = ((mm.y + c5.y) >> 1); + c2.x = ((c1.x + mm.x) / 2); + c2.y = ((c1.y + mm.y) / 2); + c4.x = ((mm.x + c5.x) / 2); + c4.y = ((mm.y + c5.y) / 2); - c3.x = ((c2.x + c4.x) >> 1); - c3.y = ((c2.y + c4.y) >> 1); + c3.x = ((c2.x + c4.x) / 2); + c3.y = ((c2.y + c4.y) / 2); /* Add left recursion to stack */ cleft->p1 = c->p1; @@ -495,12 +474,12 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic) } void -cogl_path_curve_to (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed x3, - CoglFixed y3) +cogl_path_curve_to (float x1, + float y1, + float x2, + float y2, + float x3, + float y3) { CoglBezCubic cubic; @@ -524,12 +503,12 @@ cogl_path_curve_to (CoglFixed x1, } void -cogl_path_rel_curve_to (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed x3, - CoglFixed y3) +cogl_path_rel_curve_to (float x1, + float y1, + float x2, + float y2, + float x3, + float y3) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -554,11 +533,11 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad) CoglBezQuad *qleft; CoglBezQuad *qright; CoglBezQuad *q; - CoglFixedVec2 mid; - CoglFixedVec2 dif; - CoglFixedVec2 c1; - CoglFixedVec2 c2; - CoglFixedVec2 c3; + floatVec2 mid; + floatVec2 dif; + floatVec2 c1; + floatVec2 c2; + floatVec2 c3; gint qindex; /* Put first curve on stack */ @@ -573,15 +552,15 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad) /* Calculate distance of control point from its * counterpart on the line between end points */ - mid.x = ((q->p1.x + q->p3.x) >> 1); - mid.y = ((q->p1.y + q->p3.y) >> 1); + mid.x = ((q->p1.x + q->p3.x) / 2); + mid.y = ((q->p1.y + q->p3.y) / 2); dif.x = (q->p2.x - mid.x); dif.y = (q->p2.y - mid.y); if (dif.x < 0) dif.x = -dif.x; if (dif.y < 0) dif.y = -dif.y; /* Cancel if the curve is flat enough */ - if (dif.x + dif.y <= COGL_FIXED_1 || + if (dif.x + dif.y <= 1.0 || qindex == _COGL_MAX_BEZ_RECURSE_DEPTH - 1) { /* Add subdivision point (skip last) */ @@ -594,12 +573,12 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad) qright = q; qleft = &quads[++qindex]; /* Subdivide into 2 sub-curves */ - c1.x = ((q->p1.x + q->p2.x) >> 1); - c1.y = ((q->p1.y + q->p2.y) >> 1); - c3.x = ((q->p2.x + q->p3.x) >> 1); - c3.y = ((q->p2.y + q->p3.y) >> 1); - c2.x = ((c1.x + c3.x) >> 1); - c2.y = ((c1.y + c3.y) >> 1); + c1.x = ((q->p1.x + q->p2.x) / 2); + c1.y = ((q->p1.y + q->p2.y) / 2); + c3.x = ((q->p2.x + q->p3.x) / 2); + c3.y = ((q->p2.y + q->p3.y) / 2); + c2.x = ((c1.x + c3.x) / 2); + c2.y = ((c1.y + c3.y) / 2); /* Add left recursion onto stack */ qleft->p1 = q->p1; @@ -614,10 +593,10 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad) } void -cogl_path_curve2_to (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2) +cogl_path_curve2_to (float x1, + float y1, + float x2, + float y2) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -639,10 +618,10 @@ cogl_path_curve2_to (CoglFixed x1, } void -cogl_rel_curve2_to (CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2) +cogl_rel_curve2_to (float x1, + float y1, + float x2, + float y2) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); diff --git a/clutter/cogl/common/cogl-primitives.h b/clutter/cogl/common/cogl-primitives.h index 01905d611..0a54ec145 100644 --- a/clutter/cogl/common/cogl-primitives.h +++ b/clutter/cogl/common/cogl-primitives.h @@ -26,15 +26,15 @@ #ifndef __COGL_PRIMITIVES_H #define __COGL_PRIMITIVES_H -typedef struct _CoglFixedVec2 CoglFixedVec2; +typedef struct _floatVec2 floatVec2; typedef struct _CoglBezQuad CoglBezQuad; typedef struct _CoglBezCubic CoglBezCubic; typedef struct _CoglPathNode CoglPathNode; -struct _CoglFixedVec2 +struct _floatVec2 { - CoglFixed x; - CoglFixed y; + float x; + float y; }; #ifdef CLUTTER_COGL_HAS_GL @@ -67,17 +67,17 @@ struct _CoglPathNode struct _CoglBezQuad { - CoglFixedVec2 p1; - CoglFixedVec2 p2; - CoglFixedVec2 p3; + floatVec2 p1; + floatVec2 p2; + floatVec2 p3; }; struct _CoglBezCubic { - CoglFixedVec2 p1; - CoglFixedVec2 p2; - CoglFixedVec2 p3; - CoglFixedVec2 p4; + floatVec2 p1; + floatVec2 p2; + floatVec2 p3; + floatVec2 p4; }; #endif /* __COGL_PRIMITIVES_H */ diff --git a/clutter/cogl/common/cogl-vertex-buffer-private.h b/clutter/cogl/common/cogl-vertex-buffer-private.h new file mode 100644 index 000000000..fc285a6a9 --- /dev/null +++ b/clutter/cogl/common/cogl-vertex-buffer-private.h @@ -0,0 +1,142 @@ +/* + * Cogl. + * + * An OpenGL/GLES Abstraction/Utility Layer + * + * Copyright (C) 2008 Intel Corporation. + * + * Authored By: Robert Bragg + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __COGL_VERTEX_BUFFER_H +#define __COGL_VERTEX_BUFFER_H + +/* Note we put quite a bit into the flags here to help keep + * the down size of the CoglVertexBufferAttrib struct below. */ +typedef enum _CoglVertexBufferAttribFlags +{ + /* Types */ + /* NB: update the _TYPE_MASK below if these are changed */ + COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY = 1<<0, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY = 1<<1, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY = 1<<2, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY = 1<<3, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY = 1<<4, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID = 1<<5, + + COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED = 1<<6, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED = 1<<7, + + /* Usage hints */ + /* FIXME - flatten into one flag, since its used as a boolean */ + COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT = 1<<8, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT = 1<<9, + + /* GL Data types */ + /* NB: Update the _GL_TYPE_MASK below if these are changed */ + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE = 1<<10, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE = 1<<11, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT = 1<<12, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT = 1<<14, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT = 1<<15, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT = 1<<16, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE = 1<<17, + + COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED = 1<<18, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED = 1<<19 + + /* XXX NB: If we need > 24 bits then look at changing the layout + * of struct _CoglVertexBufferAttrib below */ +} CoglVertexBufferAttribFlags; + +#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK \ + (COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) + +#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK \ + (COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE) + + +typedef struct _CoglVertexBufferAttrib +{ + /* TODO: look at breaking up the flags into seperate + * bitfields and seperate enums */ + CoglVertexBufferAttribFlags flags:24; + guint8 id; + GQuark name; + union _u + { + const void *pointer; + gsize vbo_offset; + } u; + gsize span_bytes; + guint16 stride; + guint8 n_components; + guint8 texture_unit; + +} CoglVertexBufferAttrib; + +typedef enum _CoglVertexBufferVBOFlags +{ + COGL_VERTEX_BUFFER_VBO_FLAG_UNSTRIDED = 1<<0, + COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED = 1<<1, + COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK = 1<<2, + + /* FIXME - flatten into one flag, since its used as a boolean */ + COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT = 1<<3, + COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT = 1<<4, + + COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED = 1<<5 +} CoglVertexBufferVBOFlags; + +/* + * A CoglVertexBufferVBO represents one or more attributes in a single + * buffer object + */ +typedef struct _CoglVertexBufferVBO +{ + CoglVertexBufferVBOFlags flags; + GLuint vbo_name; /*!< The name of the corresponding buffer object */ + gsize vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */ + GList *attributes; +} CoglVertexBufferVBO; + + +typedef struct _CoglVertexBuffer +{ + guint ref_count; + guint n_vertices; /*!< The number of vertices in the buffer */ + GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ + + /* Note: new_attributes is normally NULL and only valid while + * modifying a buffer. */ + GList *new_attributes; /*!< attributes pending submission */ +} CoglVertexBuffer; + +#endif /* __COGL_VERTEX_BUFFER_H */ + diff --git a/clutter/cogl/common/cogl-mesh.c b/clutter/cogl/common/cogl-vertex-buffer.c similarity index 63% rename from clutter/cogl/common/cogl-mesh.c rename to clutter/cogl/common/cogl-vertex-buffer.c index f7287f953..45833cdd6 100644 --- a/clutter/cogl/common/cogl-mesh.c +++ b/clutter/cogl/common/cogl-vertex-buffer.c @@ -1,8 +1,13 @@ -/* Mesh API: Handle extensible arrays of vertex attributes +/* + * Cogl. + * + * An OpenGL/GLES Abstraction/Utility Layer + * + * Vertex Buffer API: Handle extensible arrays of vertex attributes * * Copyright (C) 2008 Intel Corporation. * - * Authored by: Robert Bragg + * Authored by: Robert Bragg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,14 +24,14 @@ */ /* XXX: For an overview of the functionality implemented here, please - * see cogl.h.in, which contains the gtk-doc section overview for the - * Mesh API. + * see cogl-vertex-buffer.h, which contains the gtk-doc section overview + * for the Vertex Buffers API. */ -/* +/* * TODO: We need to do a better job of minimizing when we call glVertexPointer - * and pals in enable_state_for_drawing_mesh - * + * and pals in enable_state_for_drawing_attributes_buffer + * * We should have an internal 2-tuple cache of (VBO, offset) for each of them * so we can avoid some GL calls. We could have cogl wrappers for the * gl*Pointer funcs that look like this: @@ -38,9 +43,9 @@ * arrays. * * TODO: - * Actually hook this up to the cogl shaders infrastructure. The mesh API has - * been designed to allow adding of arbitrary attributes for use with shaders, - * but this has yet to be actually plumbed together and tested. + * Actually hook this up to the cogl shaders infrastructure. The vertex + * buffer API has been designed to allow adding of arbitrary attributes for use + * with shaders, but this has yet to be actually plumbed together and tested. * The bits we are missing: * - cogl_program_use doesn't currently record within ctx-> which program * is currently in use so a.t.m only Clutter knows the current shader. @@ -48,19 +53,19 @@ * (using glGetAttribLocation) so that we can call glEnableVertexAttribArray * with those indices. * (currently we just make up consecutive indices) - * - some dirty flag meshanims to know when the shader program has changed - * so we don't need to re-query it each time we draw a mesh. - * + * - some dirty flag mechanims to know when the shader program has changed + * so we don't need to re-query it each time we draw a buffer. + * * TODO: - * There is currently no API for querying back info about a mesh, E.g.: - * cogl_mesh_get_n_vertices (mesh_handle); - * cogl_mesh_attribute_get_n_components (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_get_stride (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_get_normalized (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_map (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_unmap (mesh_handle, "attrib_name"); - * (Realistically I wouldn't expect anyone to use such an API examine the - * contents of a mesh for modification, since you'd need to handle too many + * There is currently no API for querying back info about a buffer, E.g.: + * cogl_vertex_buffer_get_n_vertices (buffer_handle); + * cogl_vertex_buffer_get_n_components (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_get_stride (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_get_normalized (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_map (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_unmap (buffer_handle, "attrib_name"); + * (Realistically I wouldn't expect anyone to use such an API to examine the + * contents of a buffer for modification, since you'd need to handle too many * possibilities, but never the less there might be other value in these.) * TODO: @@ -74,47 +79,45 @@ * cogl_vbo_set_usage_hint (COGL_VBO_FLAG_DYNAMIC); * * TODO: - * Experiment with wider use of the mesh API internally to Cogl. + * Experiment with wider use of the vertex buffers API internally to Cogl. * - There is potential, I think, for this API to become a work-horse API * within COGL for submitting geometry to the GPU, and could unify some of * the GL/GLES code paths. * E.g.: - * - Try creating a per-context mesh cache for cogl_texture_rectangle to sit - * on top of. - * - Try saving the tesselation of paths/polygons into mesh objects internally. + * - Try creating a per-context vertex buffer cache for cogl_texture_rectangle + * to sit on top of. + * - Try saving the tesselation of paths/polygons into vertex buffers + * internally. * * TODO - * Expose API that lets developers get back a mesh handle for a particular + * Expose API that lets developers get back a buffer handle for a particular * polygon so they may add custom attributes to them. - * - It should be possible to query/modify a mesh efficiently, in place, + * - It should be possible to query/modify attributes efficiently, in place, * avoiding copies. It would not be acceptable to simply require that - * developers must query back the n_vertices of a mesh and then the - * n_components, type and stride etc of each component since there + * developers must query back the n_vertices of a buffer and then the + * n_components, type and stride etc of each attribute since there * would be too many combinations to realistically handle. - * + * * - In practice, some cases might be best solved with a higher level * EditableMesh API, (see futher below) but for many cases I think an * API like this might be appropriate: * - * cogl_mesh_foreach_vertex (mesh_handle, (MeshIteratorFunc)callback, - * "gl_Vertex", "gl_Color", NULL); - * void callback (CoglMeshVertex *vert) + * cogl_vertex_buffer_foreach_vertex (buffer_handle, + * (AttributesBufferIteratorFunc)callback, + * "gl_Vertex", "gl_Color", NULL); + * static void callback (CoglVertexBufferVertex *vert) * { * GLfloat *pos = vert->attrib[0]; * GLubyte *color = vert->attrib[1]; * GLfloat *new_attrib = buf[vert->index]; - * + * * new_attrib = pos*color; * } * * TODO - * Think about a higher level EditableMesh API for building/modifying mesh - * objects. - * - E.g. look at Blender for inspiration here. They can build a mesh - * from "MVert", "MFace" and "MEdge" primitives. - * - It would be possible to bake an EditableMesh into a regular Mesh, and - * vica versa - * + * Think about a higher level Mesh API for building/modifying attribute buffers + * - E.g. look at Blender for inspiration here. They can build a mesh from + * "MVert", "MFace" and "MEdge" primitives. */ #ifdef HAVE_CONFIG_H @@ -130,13 +133,13 @@ #include "cogl-util.h" #include "cogl-context.h" #include "cogl-handle.h" -#include "cogl-mesh-private.h" +#include "cogl-vertex-buffer-private.h" #define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \ (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1))) -/* +/* * GL/GLES compatability defines for VBO thingies: */ @@ -166,7 +169,7 @@ #endif -/* +/* * GL/GLES compatability defines for shader things: */ @@ -199,34 +202,27 @@ #endif /* HAVE_COGL_GL */ -static void _cogl_mesh_free (CoglMesh *mesh); +static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer); -COGL_HANDLE_DEFINE (Mesh, mesh, mesh_handles); +COGL_HANDLE_DEFINE (VertexBuffer, + vertex_buffer, + vertex_buffer_handles); -/** - * cogl_mesh_new: - * @n_vertices: The number of vertices that will make up your mesh. - * - * This creates a Cogl handle for a new mesh that you can then start to add - * attributes too. - * - * Return value: a new #CoglHandle - */ CoglHandle -cogl_mesh_new (guint n_vertices) +cogl_vertex_buffer_new (guint n_vertices) { - CoglMesh *mesh = g_slice_alloc (sizeof (CoglMesh)); + CoglVertexBuffer *buffer = g_slice_alloc (sizeof (CoglVertexBuffer)); - mesh->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (mesh, mesh); - - mesh->n_vertices = n_vertices; - - mesh->submitted_vbos = NULL; - mesh->new_attributes = NULL; + buffer->ref_count = 1; + COGL_HANDLE_DEBUG_NEW (CoglVertexBuffer, buffer); + + buffer->n_vertices = n_vertices; + + buffer->submitted_vbos = NULL; + buffer->new_attributes = NULL; /* return COGL_INVALID_HANDLE; */ - return _cogl_mesh_handle_new (mesh); + return _cogl_vertex_buffer_handle_new (buffer); } /* There are a number of standard OpenGL attributes that we deal with @@ -234,12 +230,12 @@ cogl_mesh_new (guint n_vertices) * so we should catch any typos instead of silently adding a custom * attribute. */ -static CoglMeshAttributeFlags +static CoglVertexBufferAttribFlags validate_gl_attribute (const char *gl_attribute, guint8 *n_components, guint8 *texture_unit) { - CoglMeshAttributeFlags type; + CoglVertexBufferAttribFlags type; char *detail_seperator = NULL; int name_len; @@ -251,18 +247,18 @@ validate_gl_attribute (const char *gl_attribute, if (strncmp (gl_attribute, "Vertex", name_len) == 0) { - type = COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY; } else if (strncmp (gl_attribute, "Color", name_len) == 0) { - type = COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY; } else if (strncmp (gl_attribute, "MultiTexCoord", strlen ("MultiTexCoord")) == 0) { unsigned int unit; - + if (sscanf (gl_attribute, "MultiTexCoord%u", &unit) != 1) { g_warning ("gl_MultiTexCoord attributes should include a\n" @@ -271,17 +267,17 @@ validate_gl_attribute (const char *gl_attribute, } /* FIXME: validate any '::' delimiter for this case */ *texture_unit = unit; - type = COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY; } else if (strncmp (gl_attribute, "Normal", name_len) == 0) { *n_components = 1; - type = COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY; } else { g_warning ("Unknown gl_* attribute name gl_%s\n", gl_attribute); - type = COGL_MESH_ATTRIBUTE_FLAG_INVALID; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID; } return type; @@ -290,7 +286,7 @@ validate_gl_attribute (const char *gl_attribute, /* This validates that a custom attribute name is a valid GLSL variable name * * NB: attribute names may have a detail component delimited using '::' E.g. - * custom_attrib::foo or custom_atrib::bar + * custom_attrib::foo or custom_attrib::bar * * maybe I should hang a compiled regex somewhere to handle this */ @@ -311,7 +307,7 @@ validate_custom_attribute_name (const char *attribute_name) || !g_ascii_isalpha (attribute_name[0]) || attribute_name[0] != '_') return FALSE; - + for (i = 1; i < name_len; i++) if (!g_ascii_isalnum (attribute_name[i]) || attribute_name[i] != '_') return FALSE; @@ -319,26 +315,27 @@ validate_custom_attribute_name (const char *attribute_name) return TRUE; } -/* Iterates the the CoglMeshVBOs of a mesh and create a flat list of all the - * submitted attributes +/* Iterates the CoglVertexBufferVBOs of a buffer and creates a flat list + * of all the submitted attributes * - * Note: The CoglMeshAttribute structs are deep copied. + * Note: The CoglVertexBufferAttrib structs are deep copied. */ static GList * -copy_submitted_attributes_list (CoglMesh *mesh) +copy_submitted_attributes_list (CoglVertexBuffer *buffer) { GList *tmp; GList *submitted_attributes = NULL; - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; - + for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; - CoglMeshAttribute *copy = g_slice_alloc (sizeof (CoglMeshAttribute)); + CoglVertexBufferAttrib *attribute = tmp2->data; + CoglVertexBufferAttrib *copy = + g_slice_alloc (sizeof (CoglVertexBufferAttrib)); *copy = *attribute; submitted_attributes = g_list_prepend (submitted_attributes, copy); } @@ -346,59 +343,60 @@ copy_submitted_attributes_list (CoglMesh *mesh) return submitted_attributes; } -static CoglMeshAttributeFlags +static CoglVertexBufferAttribFlags get_attribute_gl_type_flag_from_gl_type (GLenum gl_type) { switch (gl_type) { case GL_BYTE: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE; case GL_UNSIGNED_BYTE: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE; case GL_SHORT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT; case GL_UNSIGNED_SHORT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT; case GL_FLOAT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT; #if HAVE_COGL_GL case GL_INT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT; case GL_UNSIGNED_INT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT; case GL_DOUBLE: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE; #endif default: - g_warning ("Mesh API: Unrecognised OpenGL type enum 0x%08x\n", gl_type); + g_warning ("Attribute Buffers API: " + "Unrecognised OpenGL type enum 0x%08x\n", gl_type); return 0; } } static gsize -get_gl_type_size (CoglMeshAttributeFlags flags) +get_gl_type_size (CoglVertexBufferAttribFlags flags) { - CoglMeshAttributeFlags gl_type = - flags & COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_MASK; + CoglVertexBufferAttribFlags gl_type = + flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK; switch (gl_type) { - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE: return sizeof (GLbyte); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE: return sizeof (GLubyte); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT: return sizeof (GLshort); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT: return sizeof (GLushort); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT: return sizeof (GLfloat); #if HAVE_COGL_GL - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT: return sizeof (GLint); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT: return sizeof (GLuint); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE: return sizeof (GLdouble); #endif default: @@ -408,39 +406,39 @@ get_gl_type_size (CoglMeshAttributeFlags flags) } void -cogl_mesh_add_attribute (CoglHandle handle, - const char *attribute_name, - guint8 n_components, - GLenum gl_type, - gboolean normalized, - guint16 stride, - const void *pointer) +cogl_vertex_buffer_add (CoglHandle handle, + const char *attribute_name, + guint8 n_components, + GLenum gl_type, + gboolean normalized, + guint16 stride, + const void *pointer) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GQuark name_quark = g_quark_from_string (attribute_name); gboolean modifying_an_attrib = FALSE; - CoglMeshAttribute *attribute; - CoglMeshAttributeFlags flags = 0; + CoglVertexBufferAttrib *attribute; + CoglVertexBufferAttribFlags flags = 0; guint8 texture_unit = 0; GList *tmp; - if (!cogl_is_mesh (handle)) + if (!cogl_is_vertex_buffer (handle)) return; - mesh = _cogl_mesh_pointer_from_handle (handle); + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); /* The submit function works by diffing between submitted_attributes * and new_attributes to minimize the upload bandwidth + cost of * allocating new VBOs, so if there isn't already a list of new_attributes * we create one: */ - if (!mesh->new_attributes) - mesh->new_attributes = copy_submitted_attributes_list (mesh); - + if (!buffer->new_attributes) + buffer->new_attributes = copy_submitted_attributes_list (buffer); + /* Note: we first look for an existing attribute that we are modifying * so we may skip needing to validate the name */ - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *submitted_attribute = tmp->data; + CoglVertexBufferAttrib *submitted_attribute = tmp->data; if (submitted_attribute->name == name_quark) { modifying_an_attrib = TRUE; @@ -449,7 +447,8 @@ cogl_mesh_add_attribute (CoglHandle handle, /* since we will skip validate_gl_attribute in this case, we need * to pluck out the attribute type before overwriting the flags: */ - flags |= attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK; + flags |= + attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; break; } } @@ -462,81 +461,81 @@ cogl_mesh_add_attribute (CoglHandle handle, flags |= validate_gl_attribute (attribute_name + 3, &n_components, &texture_unit); - if (flags & COGL_MESH_ATTRIBUTE_FLAG_INVALID) + if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) return; } else { - flags |= COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY; if (validate_custom_attribute_name (attribute_name)) return; } - attribute = g_slice_alloc (sizeof (CoglMeshAttribute)); + attribute = g_slice_alloc (sizeof (CoglVertexBufferAttrib)); } attribute->name = g_quark_from_string (attribute_name); attribute->n_components = n_components; - attribute->stride = mesh->n_vertices > 1 ? stride : 0; + attribute->stride = buffer->n_vertices > 1 ? stride : 0; attribute->u.pointer = pointer; attribute->texture_unit = texture_unit; flags |= get_attribute_gl_type_flag_from_gl_type (gl_type); - flags |= COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; /* Note: We currently just assume, if an attribute is *ever* updated * then it should be taged as frequently changing. */ if (modifying_an_attrib) - flags |= COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT; else - flags |= COGL_MESH_ATTRIBUTE_FLAG_INFREQUENT_RESUBMIT; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT; if (normalized) - flags |= COGL_MESH_ATTRIBUTE_FLAG_NORMALIZED; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED; attribute->flags = flags; - + /* NB: get_gl_type_size must be called after setting the type * flags, above. */ if (attribute->stride) - attribute->span_bytes = mesh->n_vertices * attribute->stride; + attribute->span_bytes = buffer->n_vertices * attribute->stride; else - attribute->span_bytes = mesh->n_vertices + attribute->span_bytes = buffer->n_vertices * attribute->n_components * get_gl_type_size (attribute->flags); if (!modifying_an_attrib) - mesh->new_attributes = - g_list_prepend (mesh->new_attributes, attribute); + buffer->new_attributes = + g_list_prepend (buffer->new_attributes, attribute); } void -cogl_mesh_delete_attribute (CoglHandle handle, - const char *attribute_name) +cogl_vertex_buffer_delete (CoglHandle handle, + const char *attribute_name) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GQuark name = g_quark_from_string (attribute_name); GList *tmp; - if (!cogl_is_mesh (handle)) + if (!cogl_is_vertex_buffer (handle)) return; - mesh = _cogl_mesh_pointer_from_handle (handle); + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); /* The submit function works by diffing between submitted_attributes * and new_attributes to minimize the upload bandwidth + cost of * allocating new VBOs, so if there isn't already a list of new_attributes * we create one: */ - if (!mesh->new_attributes) - mesh->new_attributes = copy_submitted_attributes_list (mesh); - - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + if (!buffer->new_attributes) + buffer->new_attributes = copy_submitted_attributes_list (buffer); + + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *submitted_attribute = tmp->data; + CoglVertexBufferAttrib *submitted_attribute = tmp->data; if (submitted_attribute->name == name) { - mesh->new_attributes = - g_list_delete_link (mesh->new_attributes, tmp); - g_slice_free (CoglMeshAttribute, submitted_attribute); + buffer->new_attributes = + g_list_delete_link (buffer->new_attributes, tmp); + g_slice_free (CoglVertexBufferAttrib, submitted_attribute); return; } } @@ -550,46 +549,46 @@ set_attribute_enable (CoglHandle handle, const char *attribute_name, gboolean state) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GQuark name_quark = g_quark_from_string (attribute_name); GList *tmp; - if (!cogl_is_mesh (handle)) + if (!cogl_is_vertex_buffer (handle)) return; - mesh = _cogl_mesh_pointer_from_handle (handle); - - /* NB: If a mesh is currently being edited, then there can be two seperate - * lists of attributes; those that are currently submitted and a new - * list yet to be submitted, we need to modify both. */ + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + /* NB: If a buffer is currently being edited, then there can be two seperate + * lists of attributes; those that are currently submitted and a new list yet + * to be submitted, we need to modify both. */ + + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; if (attribute->name == name_quark) { if (state) - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; else - attribute->flags &= ~COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; break; } } - - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; + CoglVertexBufferAttrib *attribute = tmp2->data; if (attribute->name == name_quark) { if (state) - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; else - attribute->flags &= ~COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; return; } } @@ -601,23 +600,23 @@ set_attribute_enable (CoglHandle handle, } void -cogl_mesh_enable_attribute (CoglHandle handle, - const char *attribute_name) +cogl_vertex_buffer_enable (CoglHandle handle, + const char *attribute_name) { set_attribute_enable (handle, attribute_name, TRUE); } void -cogl_mesh_disable_attribute (CoglHandle handle, - const char *attribute_name) +cogl_vertex_buffer_disable (CoglHandle handle, + const char *attribute_name) { set_attribute_enable (handle, attribute_name, FALSE); } static void -free_mesh_attribute (CoglMeshAttribute *attribute) +cogl_vertex_buffer_attribute_free (CoglVertexBufferAttrib *attribute) { - g_slice_free (CoglMeshAttribute, attribute); + g_slice_free (CoglVertexBufferAttrib, attribute); } /* Given an attribute that we know has already been submitted before, this @@ -627,7 +626,7 @@ free_mesh_attribute (CoglMeshAttribute *attribute) * VBO has been found. */ static void -filter_already_submitted_attribute (CoglMeshAttribute *attribute, +filter_already_submitted_attribute (CoglVertexBufferAttrib *attribute, GList **reuse_vbos, GList **submitted_vbos) { @@ -637,38 +636,41 @@ filter_already_submitted_attribute (CoglMeshAttribute *attribute, * are more likley to get a match here */ for (tmp = *reuse_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; if (vbo_attribute->name == attribute->name) { - vbo_attribute->flags &= ~COGL_MESH_ATTRIBUTE_FLAG_UNUSED; + vbo_attribute->flags &= + ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in cogl_mesh_submit */ + * will be freed after all filtering in + * cogl_vertex_buffer_submit */ return; } } } - + for (tmp = *submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; - CoglMeshAttribute *reuse_attribute = NULL; + CoglVertexBufferVBO *cogl_vbo = tmp->data; + CoglVertexBufferAttrib *reuse_attribute = NULL; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; if (vbo_attribute->name == attribute->name) { reuse_attribute = vbo_attribute; /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in cogl_mesh_submit */ - + * will be freed after all filtering in + * cogl_vertex_buffer_submit */ + *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp); tmp->next = *reuse_vbos; *reuse_vbos = tmp; @@ -678,15 +680,15 @@ filter_already_submitted_attribute (CoglMeshAttribute *attribute, if (!reuse_attribute) continue; - + /* Mark all but the matched attribute as UNUSED, so that when we * finish filtering all our attributes any attrributes still * marked as UNUSED can be removed from the their cogl_vbo */ for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; - if (vbo_attribute != reuse_attribute) - vbo_attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_UNUSED; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; + if (vbo_attribute != reuse_attribute) + vbo_attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; } return; @@ -696,56 +698,56 @@ filter_already_submitted_attribute (CoglMeshAttribute *attribute, "attribute that had apparently already been submitted!"); } -/* When we first mark a CoglMeshVBO to be reused, we mark the attributes - * as unsed, so that when filtering of attributes into VBOs is done +/* When we first mark a CoglVertexBufferVBO to be reused, we mark the + * attributes as unsed, so that when filtering of attributes into VBOs is done * we can then prune the now unsed attributes. */ static void -remove_unused_attributes (CoglMeshVBO *cogl_vbo) +remove_unused_attributes (CoglVertexBufferVBO *cogl_vbo) { GList *tmp; GList *next; for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; next = tmp->next; - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_UNUSED) + if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED) { cogl_vbo->attributes = g_list_delete_link (cogl_vbo->attributes, tmp); - g_slice_free (CoglMeshAttribute, attribute); + g_slice_free (CoglVertexBufferAttrib, attribute); } } } /* Give a newly added, strided, attribute, this function looks for a - * CoglMeshVBO that the attribute is interleved with. If it can't find - * one then a new CoglMeshVBO is allocated and added to the list of - * new_strided_vbos + * CoglVertexBufferVBO that the attribute is interleved with. If it can't + * find one then a new CoglVertexBufferVBO is allocated and added to the + * list of new_strided_vbos. */ static void -filter_strided_attribute (CoglMeshAttribute *attribute, +filter_strided_attribute (CoglVertexBufferAttrib *attribute, GList **new_vbos) { GList *tmp; - CoglMeshVBO *new_cogl_vbo; + CoglVertexBufferVBO *new_cogl_vbo; for (tmp = *new_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; - - if (!cogl_vbo->flags & COGL_MESH_VBO_FLAG_STRIDED) + + if (!cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED) continue; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; const char *attribute_start = attribute->u.pointer; const char *vbo_attribute_start = vbo_attribute->u.pointer; - /* NB: All attributes have mesh->n_vertices values which + /* NB: All attributes have buffer->n_vertices values which * simplifies determining which attributes are interleved * since we assume they will start no farther than +- a * stride away from each other: @@ -758,27 +760,30 @@ filter_strided_attribute (CoglMeshAttribute *attribute, cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes, attribute); - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT) + if (attribute->flags & + COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) { - cogl_vbo->flags &= ~COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT; - cogl_vbo->flags |= COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT; + cogl_vbo->flags &= + ~COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; + cogl_vbo->flags |= + COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; } return; } } - new_cogl_vbo = g_slice_alloc (sizeof (CoglMeshVBO)); + new_cogl_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); new_cogl_vbo->vbo_name = 0; new_cogl_vbo->attributes = NULL; new_cogl_vbo->attributes = g_list_prepend (new_cogl_vbo->attributes, attribute); /* Any one of the interleved attributes will have the same span_bytes */ new_cogl_vbo->vbo_bytes = attribute->span_bytes; - new_cogl_vbo->flags = COGL_MESH_VBO_FLAG_STRIDED; - - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_INFREQUENT_RESUBMIT) - new_cogl_vbo->flags |= COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT; + new_cogl_vbo->flags = COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED; + + if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT) + new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; else - new_cogl_vbo->flags |= COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT; + new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; *new_vbos = g_list_prepend (*new_vbos, new_cogl_vbo); return; @@ -788,21 +793,21 @@ filter_strided_attribute (CoglMeshAttribute *attribute, * contains attribute. If found the list *link* is removed and returned */ static GList * unlink_submitted_vbo_containing_attribute (GList **submitted_vbos, - CoglMeshAttribute *attribute) + CoglVertexBufferAttrib *attribute) { GList *tmp; GList *next = NULL; for (tmp = *submitted_vbos; tmp != NULL; tmp = next) { - CoglMeshVBO *submitted_vbo = tmp->data; + CoglVertexBufferVBO *submitted_vbo = tmp->data; GList *tmp2; next = tmp->next; for (tmp2 = submitted_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *submitted_attribute = tmp2->data; + CoglVertexBufferAttrib *submitted_attribute = tmp2->data; if (submitted_attribute->name == attribute->name) { @@ -818,7 +823,8 @@ unlink_submitted_vbo_containing_attribute (GList **submitted_vbos, /* Unlinks all the submitted VBOs that conflict with the new cogl_vbo and * returns them as a list. */ static GList * -get_submitted_vbo_conflicts (GList **submitted_vbos, CoglMeshVBO *cogl_vbo) +get_submitted_vbo_conflicts (GList **submitted_vbos, + CoglVertexBufferVBO *cogl_vbo) { GList *tmp; GList *conflicts = NULL; @@ -840,25 +846,25 @@ get_submitted_vbo_conflicts (GList **submitted_vbos, CoglMeshVBO *cogl_vbo) /* Any attributes in cogl_vbo gets removed from conflict_vbo */ static void -disassociate_conflicting_attributes (CoglMeshVBO *conflict_vbo, - CoglMeshVBO *cogl_vbo) +disassociate_conflicting_attributes (CoglVertexBufferVBO *conflict_vbo, + CoglVertexBufferVBO *cogl_vbo) { GList *tmp; - + /* NB: The attributes list in conflict_vbo will be shrinking so * we iterate those in the inner loop. */ for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; GList *tmp2; for (tmp2 = conflict_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *conflict_attribute = tmp2->data; + CoglVertexBufferAttrib *conflict_attribute = tmp2->data; if (conflict_attribute->name == attribute->name) { - free_mesh_attribute (conflict_attribute); + cogl_vertex_buffer_attribute_free (conflict_attribute); conflict_vbo->attributes = g_list_delete_link (conflict_vbo->attributes, tmp2); break; @@ -868,7 +874,8 @@ disassociate_conflicting_attributes (CoglMeshVBO *conflict_vbo, } static void -free_cogl_mesh_vbo (CoglMeshVBO *cogl_vbo, gboolean delete_gl_vbo) +cogl_vertex_buffer_vbo_free (CoglVertexBufferVBO *cogl_vbo, + gboolean delete_gl_vbo) { GList *tmp; @@ -876,14 +883,15 @@ free_cogl_mesh_vbo (CoglMeshVBO *cogl_vbo, gboolean delete_gl_vbo) for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - free_mesh_attribute (tmp->data); + cogl_vertex_buffer_attribute_free (tmp->data); } g_list_free (cogl_vbo->attributes); - if (delete_gl_vbo && cogl_vbo->flags & COGL_MESH_VBO_FLAG_SUBMITTED) + if (delete_gl_vbo && cogl_vbo->flags & + COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED) GE (glDeleteBuffers (1, &cogl_vbo->vbo_name)); - g_slice_free (CoglMeshVBO, cogl_vbo); + g_slice_free (CoglVertexBufferVBO, cogl_vbo); } /* This figures out the lowest attribute client pointer. (This pointer is used @@ -893,33 +901,33 @@ free_cogl_mesh_vbo (CoglMeshVBO *cogl_vbo, gboolean delete_gl_vbo) * offset, and marks the attribute as submitted. */ static const void * -prep_strided_vbo_for_upload (CoglMeshVBO *cogl_vbo) +prep_strided_vbo_for_upload (CoglVertexBufferVBO *cogl_vbo) { GList *tmp; const char *lowest_pointer = NULL; for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; const char *client_pointer = attribute->u.pointer; if (!lowest_pointer || client_pointer < lowest_pointer) lowest_pointer = client_pointer; } - + for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; const char *client_pointer = attribute->u.pointer; attribute->u.vbo_offset = client_pointer - lowest_pointer; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; } return lowest_pointer; } static gboolean -upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) +upload_multipack_vbo_via_map_buffer (CoglVertexBufferVBO *cogl_vbo) { #if HAVE_COGL_GL GList *tmp; @@ -935,7 +943,7 @@ upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; gsize attribute_size = attribute->span_bytes; gsize gl_type_size = get_gl_type_size (attribute->flags); @@ -944,7 +952,7 @@ upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) memcpy (buf + offset, attribute->u.pointer, attribute_size); attribute->u.vbo_offset = offset; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; offset += attribute_size; } glUnmapBuffer (GL_ARRAY_BUFFER); @@ -956,7 +964,7 @@ upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) } static void -upload_multipack_vbo_via_buffer_sub_data (CoglMeshVBO *cogl_vbo) +upload_multipack_vbo_via_buffer_sub_data (CoglVertexBufferVBO *cogl_vbo) { GList *tmp; guint offset = 0; @@ -965,7 +973,7 @@ upload_multipack_vbo_via_buffer_sub_data (CoglMeshVBO *cogl_vbo) for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; gsize attribute_size = attribute->span_bytes; gsize gl_type_size = get_gl_type_size (attribute->flags); @@ -976,13 +984,13 @@ upload_multipack_vbo_via_buffer_sub_data (CoglMeshVBO *cogl_vbo) attribute_size, attribute->u.pointer)); attribute->u.vbo_offset = offset; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; offset += attribute_size; } } static void -upload_gl_vbo (CoglMeshVBO *cogl_vbo) +upload_gl_vbo (CoglVertexBufferVBO *cogl_vbo) { GLenum usage; @@ -990,14 +998,14 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) g_return_if_fail (cogl_vbo->vbo_name != 0); - if (cogl_vbo->flags & COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT) + if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT) usage = GL_DYNAMIC_DRAW; else usage = GL_STATIC_DRAW; GE (glBindBuffer (GL_ARRAY_BUFFER, cogl_vbo->vbo_name)); - - if (cogl_vbo->flags & COGL_MESH_VBO_FLAG_STRIDED) + + if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED) { const void *pointer = prep_strided_vbo_for_upload (cogl_vbo); @@ -1006,7 +1014,7 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) pointer, usage)); } - else if (cogl_vbo->flags & COGL_MESH_VBO_FLAG_MULTIPACK) + else if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK) { /* First we make it obvious to the driver that we want to update the * whole buffer (without this, the driver is more likley to block @@ -1015,9 +1023,9 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) cogl_vbo->vbo_bytes, NULL, usage)); - - /* I think it might depend on the specific driver/HW whether its better to - * use glMapBuffer here or glBufferSubData here. There is even a good + + /* I think it might depend on the specific driver/HW whether its better + * to use glMapBuffer here or glBufferSubData here. There is even a good * thread about this topic here: * http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg35004.html * For now I have gone with glMapBuffer, but the jury is still out. @@ -1028,7 +1036,7 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) } else { - CoglMeshAttribute *attribute = cogl_vbo->attributes->data; + CoglVertexBufferAttrib *attribute = cogl_vbo->attributes->data; GE (glBufferData (GL_ARRAY_BUFFER, cogl_vbo->vbo_bytes, attribute->u.pointer, @@ -1036,21 +1044,21 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) /* We forget this pointer now since the client will be free * to re-use this memory */ attribute->u.pointer = NULL; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; } - cogl_vbo->flags |= COGL_MESH_VBO_FLAG_SUBMITTED; + cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED; GE (glBindBuffer (GL_ARRAY_BUFFER, 0)); } -/* Note: although there ends up being quite a few inner loops involved - * with resolving buffers, the number of attributes will be low so I - * don't expect them to cause a problem. */ +/* Note: although there ends up being quite a few inner loops involved with + * resolving buffers, the number of attributes will be low so I don't expect + * them to cause a problem. */ static void -resolve_new_cogl_mesh_vbo (CoglMesh *mesh, - CoglMeshVBO *new_cogl_vbo, - GList **final_vbos) +cogl_vertex_buffer_vbo_resolve (CoglVertexBuffer *buffer, + CoglVertexBufferVBO *new_cogl_vbo, + GList **final_vbos) { GList *conflicts; GList *tmp; @@ -1058,16 +1066,16 @@ resolve_new_cogl_mesh_vbo (CoglMesh *mesh, gboolean found_target_vbo = FALSE; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - + conflicts = - get_submitted_vbo_conflicts (&mesh->submitted_vbos, new_cogl_vbo); + get_submitted_vbo_conflicts (&buffer->submitted_vbos, new_cogl_vbo); for (tmp = conflicts; tmp != NULL; tmp = next) { - CoglMeshVBO *conflict_vbo = tmp->data; + CoglVertexBufferVBO *conflict_vbo = tmp->data; next = tmp->next; - + disassociate_conflicting_attributes (conflict_vbo, new_cogl_vbo); if (!conflict_vbo->attributes) @@ -1079,22 +1087,22 @@ resolve_new_cogl_mesh_vbo (CoglMesh *mesh, { found_target_vbo = TRUE; new_cogl_vbo->vbo_name = conflict_vbo->vbo_name; - free_cogl_mesh_vbo (conflict_vbo, FALSE); - + cogl_vertex_buffer_vbo_free (conflict_vbo, FALSE); + upload_gl_vbo (new_cogl_vbo); *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); } else - free_cogl_mesh_vbo (conflict_vbo, TRUE); + cogl_vertex_buffer_vbo_free (conflict_vbo, TRUE); } else { - /* Relink the VBO back into mesh->submitted_vbos since it may + /* Relink the VBO back into buffer->submitted_vbos since it may * be involved in other conflicts later */ - tmp->next = mesh->submitted_vbos; + tmp->next = buffer->submitted_vbos; tmp->prev = NULL; - mesh->submitted_vbos = tmp; + buffer->submitted_vbos = tmp; } } @@ -1103,35 +1111,35 @@ resolve_new_cogl_mesh_vbo (CoglMesh *mesh, GE (glGenBuffers (1, &new_cogl_vbo->vbo_name)); /* FIXME: debug */ g_assert (glGetError() == GL_NO_ERROR); - + upload_gl_vbo (new_cogl_vbo); *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); } } void -cogl_mesh_submit (CoglHandle handle) +cogl_vertex_buffer_submit (CoglHandle handle) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GList *tmp; - CoglMeshVBO *new_multipack_vbo; + CoglVertexBufferVBO *new_multipack_vbo; GList *new_multipack_vbo_link; GList *new_vbos = NULL; GList *reuse_vbos = NULL; GList *final_vbos = NULL; - - if (!cogl_is_mesh (handle)) + + if (!cogl_is_vertex_buffer (handle)) return; - - mesh = _cogl_mesh_pointer_from_handle (handle); - + + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); + /* The objective now is to copy the attribute data supplied by the client - * into buffer objects, but it's important to minimize the amount of memory - * bandwidth we waste here. + * into buffer objects, but it's important to minimize the number of + * redundant data uploads. * - * We need to group together the attributes that are interleved so that the - * driver can use a single continguous memcpy for these. All BOs for - * interleved data are created as STATIC_DRAW_ARB. + * We obviously aim to group together the attributes that are interleved so + * that they can be delivered in one go to the driver. + * All BOs for interleved data are created as STATIC_DRAW_ARB. * * Non interleved attributes tagged as INFREQUENT_RESUBMIT will be grouped * together back to back in a single BO created as STATIC_DRAW_ARB @@ -1139,23 +1147,23 @@ cogl_mesh_submit (CoglHandle handle) * Non interleved attributes tagged as FREQUENT_RESUBMIT will be copied into * individual buffer objects, and the BO itself created DYNAMIC_DRAW_ARB * - * If we are modifying an submitted mesh object then we are carefull not - * to needlesly delete submitted buffer objects and replace with new ones, - * instead we upload new data to the submitted buffers. + * If we are modifying a previously submitted CoglVertexBuffer then we are + * carefull not to needlesly delete OpenGL buffer objects and replace with + * new ones, instead we upload new data to the existing buffers. */ - + /* NB: We must forget attribute->pointer after submitting since the user * is free to re-use that memory for other purposes now. */ /* Pseudo code: - * + * * Broadly speaking we start with a list of unsorted attributes, and filter - * those into 'new' and 're-use' CoglMeshVBO (CBO) lists. We then take the - * list of new CBO structs and compare with the CBOs that have already been - * submitted to the GPU (but ignoring those we already know will be re-used) - * to determine what other CBOs can be re-used, due to being superseded, - * and what new GL VBOs need to be created. - * + * those into 'new' and 're-use' CoglVertexBufferVBO (CBO) lists. We then + * take the list of new CBO structs and compare with the CBOs that have + * already been submitted to the GPU (but ignoring those we already know will + * be re-used) to determine what other CBOs can be re-used, due to being + * superseded, and what new GL VBOs need to be created. + * * We have three kinds of CBOs: * - Unstrided CBOs * These contain a single tightly packed attribute @@ -1193,7 +1201,7 @@ cogl_mesh_submit (CoglHandle handle) * else * add to the new-multipack-CBO * free list of unsorted-attribs - * + * * Next compare the new list of CBOs with the submitted set and try to * minimize the memory bandwidth required to upload the attributes and the * overhead of creating new GL-BOs. @@ -1207,7 +1215,7 @@ cogl_mesh_submit (CoglHandle handle) * (I.e. ones currently submitted to the GPU) * - The "final" CBOs * (The result of resolving the differences between the above sets) - * + * * The re-use CBOs are dealt with first, and we simply delete any remaining * attributes in these that are still marked as UNUSED, and move them * to the list of final CBOs. @@ -1220,11 +1228,11 @@ cogl_mesh_submit (CoglHandle handle) * based on the matches). If the CBO node is superseded it is freed, * if it is modified but may be needed for more descisions later it is * relinked back into the submitted list and if it's identical to a new - * CBO it will be linked into the final list. + * CBO it will be linked into the final list. * * At the end the list of submitted CBOs represents the attributes that were - * deleted from the mesh. - * + * deleted from the buffer. + * * Iterate re-use-CBOs: * Iterate attribs for each: * if attrib UNUSED: @@ -1260,11 +1268,12 @@ cogl_mesh_submit (CoglHandle handle) * delete the submitted GL-BO * free the submitted CBO struct */ - - new_multipack_vbo = g_slice_alloc (sizeof (CoglMeshVBO)); + + new_multipack_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); new_multipack_vbo->vbo_name = 0; - new_multipack_vbo->flags = COGL_MESH_VBO_FLAG_MULTIPACK - | COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT; + new_multipack_vbo->flags = + COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK + | COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; new_multipack_vbo->vbo_bytes = 0; new_multipack_vbo->attributes = NULL; new_vbos = g_list_prepend (new_vbos, new_multipack_vbo); @@ -1275,11 +1284,11 @@ cogl_mesh_submit (CoglHandle handle) /* Start with a list of unsorted attributes, and filter those into * potential new Cogl BO structs */ - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; - - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED) + CoglVertexBufferAttrib *attribute = tmp->data; + + if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED) { /* If the attribute is already marked as submitted, then we need * to find the existing VBO that contains it so we dont delete it. @@ -1289,26 +1298,30 @@ cogl_mesh_submit (CoglHandle handle) */ filter_already_submitted_attribute (attribute, &reuse_vbos, - &mesh->submitted_vbos); + &buffer->submitted_vbos); } else if (attribute->stride) { - /* look for a CoglMeshVBO that the attribute is interleved with. If - * one can't be found then a new CoglMeshVBO is allocated and added - * to the list of new_vbos: */ + /* look for a CoglVertexBufferVBO that the attribute is + * interleved with. If one can't be found then a new + * CoglVertexBufferVBO is allocated and added to the list of + * new_vbos: */ filter_strided_attribute (attribute, &new_vbos); } - else if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT) + else if (attribute->flags & + COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) { - CoglMeshVBO *cogl_vbo = g_slice_alloc (sizeof (CoglMeshVBO)); - + CoglVertexBufferVBO *cogl_vbo = + g_slice_alloc (sizeof (CoglVertexBufferVBO)); + /* attributes we expect will be frequently resubmitted are placed * in their own VBO so that updates don't impact other attributes */ cogl_vbo->vbo_name = 0; - cogl_vbo->flags = COGL_MESH_VBO_FLAG_UNSTRIDED - | COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT; + cogl_vbo->flags = + COGL_VERTEX_BUFFER_VBO_FLAG_UNSTRIDED + | COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; cogl_vbo->attributes = NULL; cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes, attribute); @@ -1340,16 +1353,16 @@ cogl_mesh_submit (CoglHandle handle) } } - /* At this point all mesh->new_attributes have been filtered into - * CoglMeshVBOs... */ - g_list_free (mesh->new_attributes); - mesh->new_attributes = NULL; - + /* At this point all buffer->new_attributes have been filtered into + * CoglVertexBufferVBOs... */ + g_list_free (buffer->new_attributes); + buffer->new_attributes = NULL; + /* If the multipack vbo wasn't needed: */ if (new_multipack_vbo->attributes == NULL) { new_vbos = g_list_delete_link (new_vbos, new_multipack_vbo_link); - g_slice_free (CoglMeshVBO, new_multipack_vbo); + g_slice_free (CoglVertexBufferVBO, new_multipack_vbo); } for (tmp = reuse_vbos; tmp != NULL; tmp = tmp->next) @@ -1357,40 +1370,40 @@ cogl_mesh_submit (CoglHandle handle) final_vbos = g_list_concat (final_vbos, reuse_vbos); for (tmp = new_vbos; tmp != NULL; tmp = tmp->next) - resolve_new_cogl_mesh_vbo (mesh, tmp->data, &final_vbos); - - /* Anything left corresponds to deleted attributes: */ - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) - free_cogl_mesh_vbo (tmp->data, TRUE); - g_list_free (mesh->submitted_vbos); + cogl_vertex_buffer_vbo_resolve (buffer, tmp->data, &final_vbos); - mesh->submitted_vbos = final_vbos; + /* Anything left corresponds to deleted attributes: */ + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) + cogl_vertex_buffer_vbo_free (tmp->data, TRUE); + g_list_free (buffer->submitted_vbos); + + buffer->submitted_vbos = final_vbos; } static GLenum -get_gl_type_from_attribute_flags (CoglMeshAttributeFlags flags) +get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags) { - CoglMeshAttributeFlags gl_type = - flags & COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_MASK; + CoglVertexBufferAttribFlags gl_type = + flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK; switch (gl_type) { - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE: return GL_BYTE; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE: return GL_UNSIGNED_BYTE; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT: return GL_SHORT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT: return GL_UNSIGNED_SHORT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT: return GL_FLOAT; #if HAVE_COGL_GL - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT: return GL_INT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT: return GL_UNSIGNED_INT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE: return GL_DOUBLE; #endif default: @@ -1401,7 +1414,7 @@ get_gl_type_from_attribute_flags (CoglMeshAttributeFlags flags) } static void -enable_state_for_drawing_mesh (CoglMesh *mesh) +enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer) { GList *tmp; GLenum gl_type; @@ -1412,26 +1425,26 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) _COGL_GET_CONTEXT (ctx, NO_RETVAL); - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; GE (glBindBuffer (GL_ARRAY_BUFFER, cogl_vbo->vbo_name)); for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; - CoglMeshAttributeFlags type = - attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK; - - if (!(attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_ENABLED)) + CoglVertexBufferAttrib *attribute = tmp2->data; + CoglVertexBufferAttribFlags type = + attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; + + if (!(attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED)) continue; - + gl_type = get_gl_type_from_attribute_flags (attribute->flags); switch (type) { - case COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY: /* FIXME: go through cogl cache to enable color array */ GE (glEnableClientState (GL_COLOR_ARRAY)); GE (glColorPointer (attribute->n_components, @@ -1439,14 +1452,14 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY: /* FIXME: go through cogl cache to enable normal array */ GE (glEnableClientState (GL_NORMAL_ARRAY)); GE (glNormalPointer (gl_type, attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY: /* FIXME: set the active texture unit */ /* NB: Cogl currently manages unit 0 */ enable_flags |= (COGL_ENABLE_TEXCOORD_ARRAY @@ -1459,7 +1472,7 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: enable_flags |= COGL_ENABLE_VERTEX_ARRAY; /* GE (glEnableClientState (GL_VERTEX_ARRAY)); */ GE (glVertexPointer (attribute->n_components, @@ -1467,15 +1480,16 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY: { #ifdef MAY_HAVE_PROGRAMABLE_GL GLboolean normalized = GL_FALSE; - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_NORMALIZED) + if (attribute->flags & + COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED) normalized = GL_TRUE; /* FIXME: go through cogl cache to enable generic array */ GE (glEnableVertexAttribArray (generic_index++)); - GE (glVertexAttribPointer (generic_index, + GE (glVertexAttribPointer (generic_index, attribute->n_components, gl_type, normalized, @@ -1490,13 +1504,13 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) } } } - + cogl_enable (enable_flags); } static void -disable_state_for_drawing_mesh (CoglMesh *mesh) +disable_state_for_drawing_buffer (CoglVertexBuffer *buffer) { GList *tmp; GLenum gl_type; @@ -1510,40 +1524,40 @@ disable_state_for_drawing_mesh (CoglMesh *mesh) GE (glBindBuffer (GL_ARRAY_BUFFER, 0)); generic_index = 0; - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; - CoglMeshAttributeFlags type = - attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK; + CoglVertexBufferAttrib *attribute = tmp2->data; + CoglVertexBufferAttribFlags type = + attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; - if (!(attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_ENABLED)) + if (!(attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED)) continue; gl_type = get_gl_type_from_attribute_flags(attribute->flags); switch (type) { - case COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY: /* FIXME: go through cogl cache to enable color array */ GE (glDisableClientState (GL_COLOR_ARRAY)); break; - case COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY: /* FIXME: go through cogl cache to enable normal array */ GE (glDisableClientState (GL_NORMAL_ARRAY)); break; - case COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY: /* FIXME: set the active texture unit */ /* NB: Cogl currently manages unit 0 */ /* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ break; - case COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: /* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ break; - case COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY: #ifdef MAY_HAVE_PROGRAMABLE_GL /* FIXME: go through cogl cache to enable generic array */ GE (glDisableVertexAttribArray (generic_index++)); @@ -1557,62 +1571,63 @@ disable_state_for_drawing_mesh (CoglMesh *mesh) } void -cogl_mesh_draw_arrays (CoglHandle handle, - GLenum mode, - GLint first, - GLsizei count) +cogl_vertex_buffer_draw (CoglHandle handle, + GLenum mode, + GLint first, + GLsizei count) { - CoglMesh *mesh; - - if (!cogl_is_mesh (handle)) + CoglVertexBuffer *buffer; + + if (!cogl_is_vertex_buffer (handle)) return; - - mesh = _cogl_mesh_pointer_from_handle (handle); - - enable_state_for_drawing_mesh (mesh); + + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); + + enable_state_for_drawing_attributes_buffer (buffer); /* FIXME: flush cogl cache */ GE (glDrawArrays (mode, first, count)); - - disable_state_for_drawing_mesh (mesh); + + disable_state_for_drawing_buffer (buffer); } void -cogl_mesh_draw_range_elements (CoglHandle handle, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices) +cogl_vertex_buffer_draw_elements (CoglHandle handle, + GLenum mode, + GLuint min_index, + GLuint max_index, + GLsizei count, + GLenum indices_type, + const GLvoid *indices) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_mesh (handle)) + + if (!cogl_is_vertex_buffer (handle)) return; - - mesh = _cogl_mesh_pointer_from_handle (handle); - - enable_state_for_drawing_mesh (mesh); + + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); + + enable_state_for_drawing_attributes_buffer (buffer); /* FIXME: flush cogl cache */ - GE (glDrawRangeElements (mode, start, end, count, type, indices)); + GE (glDrawRangeElements (mode, min_index, max_index, + count, indices_type, indices)); - disable_state_for_drawing_mesh (mesh); + disable_state_for_drawing_buffer (buffer); } static void -_cogl_mesh_free (CoglMesh *mesh) +_cogl_vertex_buffer_free (CoglVertexBuffer *buffer) { GList *tmp; - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) - free_cogl_mesh_vbo (tmp->data, TRUE); - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) - free_mesh_attribute (tmp->data); + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) + cogl_vertex_buffer_vbo_free (tmp->data, TRUE); + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) + cogl_vertex_buffer_attribute_free (tmp->data); - g_slice_free (CoglMesh, mesh); + g_slice_free (CoglVertexBuffer, buffer); } diff --git a/clutter/cogl/gl/Makefile.am b/clutter/cogl/gl/Makefile.am index d95dd95cb..b3ef874fa 100644 --- a/clutter/cogl/gl/Makefile.am +++ b/clutter/cogl/gl/Makefile.am @@ -10,7 +10,7 @@ libclutterinclude_HEADERS = \ $(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-types.h \ - $(top_builddir)/clutter/cogl/cogl-mesh.h \ + $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \ $(top_builddir)/clutter/cogl/cogl-material.h \ $(top_builddir)/clutter/cogl/cogl-matrix.h diff --git a/clutter/cogl/gl/cogl-context.c b/clutter/cogl/gl/cogl-context.c index 362c1f154..cd89fcf9a 100644 --- a/clutter/cogl/gl/cogl-context.c +++ b/clutter/cogl/gl/cogl-context.c @@ -76,7 +76,7 @@ cogl_create_context () _context->program_handles = NULL; - _context->mesh_handles = NULL; + _context->vertex_buffer_handles = NULL; _context->pf_glGenRenderbuffersEXT = NULL; _context->pf_glBindRenderbufferEXT = NULL; diff --git a/clutter/cogl/gl/cogl-context.h b/clutter/cogl/gl/cogl-context.h index 1a48572a8..ae1b80c85 100644 --- a/clutter/cogl/gl/cogl-context.h +++ b/clutter/cogl/gl/cogl-context.h @@ -51,12 +51,12 @@ typedef struct gboolean enable_backface_culling; /* Primitives */ - CoglFixedVec2 path_start; - CoglFixedVec2 path_pen; + floatVec2 path_start; + floatVec2 path_pen; GArray *path_nodes; guint last_path; - CoglFixedVec2 path_nodes_min; - CoglFixedVec2 path_nodes_max; + floatVec2 path_nodes_min; + floatVec2 path_nodes_max; /* Cache of inverse projection matrix */ GLfloat inverse_projection[16]; @@ -91,8 +91,8 @@ typedef struct /* Clip stack */ CoglClipStackState clip; - /* Mesh */ - GArray *mesh_handles; + /* Vertex buffers */ + GArray *vertex_buffer_handles; /* Relying on glext.h to define these */ COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT; diff --git a/clutter/cogl/gl/cogl-primitives.c b/clutter/cogl/gl/cogl-primitives.c index ca46d85ac..e44565780 100644 --- a/clutter/cogl/gl/cogl-primitives.c +++ b/clutter/cogl/gl/cogl-primitives.c @@ -34,52 +34,35 @@ #include #include +#include #define _COGL_MAX_BEZ_RECURSE_DEPTH 16 void -_cogl_rectangle (gint x, - gint y, - guint width, - guint height) +_cogl_rectangle (float x, + float y, + float width, + float height) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); cogl_enable (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0); - GE( glRecti (x, y, x + width, y + height) ); -} - - -void -_cogl_rectanglex (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_enable (ctx->color_alpha < 255 - ? COGL_ENABLE_BLEND : 0); - - GE( glRectf (COGL_FIXED_TO_FLOAT (x), - COGL_FIXED_TO_FLOAT (y), - COGL_FIXED_TO_FLOAT (x + width), - COGL_FIXED_TO_FLOAT (y + height)) ); + GE( glRectf (x, y, x + width, y + height) ); } void _cogl_path_add_node (gboolean new_sub_path, - CoglFixed x, - CoglFixed y) + float x, + float y) { CoglPathNode new_node; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - new_node.x = COGL_FIXED_TO_FLOAT (x); - new_node.y = COGL_FIXED_TO_FLOAT (y); + new_node.x = (x); + new_node.y = (y); new_node.path_size = 0; if (new_sub_path || ctx->path_nodes->len == 0) @@ -129,34 +112,32 @@ _cogl_path_stroke_nodes () } static void -_cogl_path_get_bounds (CoglFixedVec2 nodes_min, - CoglFixedVec2 nodes_max, - gint *bounds_x, - gint *bounds_y, - guint *bounds_w, - guint *bounds_h) +_cogl_path_get_bounds (floatVec2 nodes_min, + floatVec2 nodes_max, + float *bounds_x, + float *bounds_y, + float *bounds_w, + float *bounds_h) { - *bounds_x = COGL_FIXED_FLOOR (nodes_min.x); - *bounds_y = COGL_FIXED_FLOOR (nodes_min.y); - *bounds_w = COGL_FIXED_CEIL (nodes_max.x - - COGL_FIXED_FROM_INT (*bounds_x)); - *bounds_h = COGL_FIXED_CEIL (nodes_max.y - - COGL_FIXED_FROM_INT (*bounds_y)); + *bounds_x = nodes_min.x; + *bounds_y = nodes_min.y; + *bounds_w = nodes_max.x - *bounds_x; + *bounds_h = nodes_max.y - *bounds_y; } void -_cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, - CoglFixedVec2 nodes_max, +_cogl_add_path_to_stencil_buffer (floatVec2 nodes_min, + floatVec2 nodes_max, guint path_size, CoglPathNode *path, gboolean merge) { guint path_start = 0; guint sub_path_num = 0; - gint bounds_x; - gint bounds_y; - guint bounds_w; - guint bounds_h; + float bounds_x; + float bounds_y; + float bounds_w; + float bounds_h; _cogl_path_get_bounds (nodes_min, nodes_max, &bounds_x, &bounds_y, &bounds_w, &bounds_h); @@ -238,10 +219,10 @@ _cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, void _cogl_path_fill_nodes () { - gint bounds_x; - gint bounds_y; - guint bounds_w; - guint bounds_h; + float bounds_x; + float bounds_y; + float bounds_w; + float bounds_h; _COGL_GET_CONTEXT (ctx, NO_RETVAL); diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c index 3dc3f66d5..df85e9bf1 100644 --- a/clutter/cogl/gl/cogl-texture.c +++ b/clutter/cogl/gl/cogl-texture.c @@ -38,6 +38,7 @@ #include #include +#include /* #define COGL_DEBUG 1 @@ -59,15 +60,15 @@ struct _CoglSpanIter gint index; GArray *array; CoglTexSliceSpan *span; - CoglFixed pos; - CoglFixed next_pos; - CoglFixed origin; - CoglFixed cover_start; - CoglFixed cover_end; - CoglFixed intersect_start; - CoglFixed intersect_end; - CoglFixed intersect_start_local; - CoglFixed intersect_end_local; + float pos; + float next_pos; + float origin; + float cover_start; + float cover_end; + float intersect_start; + float intersect_end; + float intersect_start_local; + float intersect_end_local; gboolean intersects; }; @@ -102,7 +103,7 @@ _cogl_span_iter_update (CoglSpanIter *iter) /* Offset next position by span size */ iter->next_pos = iter->pos + - COGL_FIXED_FROM_INT (iter->span->size - iter->span->waste); + (float)(iter->span->size - iter->span->waste); /* Check if span intersects the area to cover */ if (iter->next_pos <= iter->cover_start || @@ -131,9 +132,9 @@ _cogl_span_iter_update (CoglSpanIter *iter) static void _cogl_span_iter_begin (CoglSpanIter *iter, GArray *array, - CoglFixed origin, - CoglFixed cover_start, - CoglFixed cover_end) + float origin, + float cover_start, + float cover_end) { /* Copy info */ iter->index = 0; @@ -471,8 +472,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, /* Iterate vertical spans */ for (source_y = src_y, _cogl_span_iter_begin (&y_iter, tex->slice_y_spans, - 0, COGL_FIXED_FROM_INT (dst_y), - COGL_FIXED_FROM_INT (dst_y + height)); + 0, (float)(dst_y), + (float)(dst_y + height)); !_cogl_span_iter_end (&y_iter); @@ -492,8 +493,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, /* Iterate horizontal spans */ for (source_x = src_x, _cogl_span_iter_begin (&x_iter, tex->slice_x_spans, - 0, COGL_FIXED_FROM_INT (dst_x), - COGL_FIXED_FROM_INT (dst_x + width)); + 0, (float)(dst_x), + (float)(dst_x + width)); !_cogl_span_iter_end (&x_iter); @@ -511,15 +512,15 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, x_iter.index); /* Pick intersection width and height */ - inter_w = COGL_FIXED_TO_INT (x_iter.intersect_end - + inter_w = (x_iter.intersect_end - x_iter.intersect_start); - inter_h = COGL_FIXED_TO_INT (y_iter.intersect_end - + inter_h = (y_iter.intersect_end - y_iter.intersect_start); /* Localize intersection top-left corner to slice*/ - local_x = COGL_FIXED_TO_INT (x_iter.intersect_start - + local_x = (x_iter.intersect_start - x_iter.pos); - local_y = COGL_FIXED_TO_INT (y_iter.intersect_start - + local_y = (y_iter.intersect_start - y_iter.pos); /* Pick slice GL handle */ @@ -555,7 +556,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, guint wx, wy; src = source_bmp->data - + (src_y + COGL_FIXED_TO_INT (y_iter.intersect_start) + + (src_y + ((int)y_iter.intersect_start) - dst_y) * source_bmp->rowstride + (src_x + x_span->start + x_span->size - x_span->waste @@ -600,7 +601,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, guint copy_width; src = source_bmp->data - + (src_x + COGL_FIXED_TO_INT (x_iter.intersect_start) + + (src_x + ((int)x_iter.intersect_start) - dst_x) * bpp + (src_y + y_span->start + y_span->size - y_span->waste @@ -1188,11 +1189,11 @@ _cogl_texture_free (CoglTexture *tex) } CoglHandle -cogl_texture_new_with_size (guint width, - guint height, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format) +cogl_texture_new_with_size (guint width, + guint height, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format) { CoglTexture *tex; gint bpp; @@ -1213,7 +1214,7 @@ cogl_texture_new_with_size (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; - tex->auto_mipmap = auto_mipmap; + tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->bitmap.width = width; tex->bitmap.height = height; @@ -1248,14 +1249,14 @@ cogl_texture_new_with_size (guint width, } CoglHandle -cogl_texture_new_from_data (guint width, - guint height, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat format, - CoglPixelFormat internal_format, - guint rowstride, - const guchar *data) +cogl_texture_new_from_data (guint width, + guint height, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat format, + CoglPixelFormat internal_format, + guint rowstride, + const guchar *data) { CoglTexture *tex; gint bpp; @@ -1277,7 +1278,7 @@ cogl_texture_new_from_data (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; - tex->auto_mipmap = auto_mipmap; + tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->bitmap.width = width; tex->bitmap.height = height; @@ -1323,30 +1324,13 @@ cogl_texture_new_from_data (guint width, } CoglHandle -cogl_texture_new_from_file (const gchar *filename, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format, - GError **error) +cogl_texture_new_from_bitmap (CoglBitmap *bmp, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format) { - CoglBitmap bmp; CoglTexture *tex; - g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); - - /* Try loading with imaging backend */ - if (!_cogl_bitmap_from_file (&bmp, filename, error)) - { - /* Try fallback */ - if (!_cogl_bitmap_fallback_from_file (&bmp, filename)) - return COGL_INVALID_HANDLE; - else if (error && *error) - { - g_error_free (*error); - *error = NULL; - } - } - /* Create new texture and fill with loaded data */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); @@ -1354,10 +1338,11 @@ cogl_texture_new_from_file (const gchar *filename, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; - tex->auto_mipmap = auto_mipmap; + tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); - tex->bitmap = bmp; + tex->bitmap = *bmp; tex->bitmap_owner = TRUE; + bmp->data = NULL; tex->slice_x_spans = NULL; tex->slice_y_spans = NULL; @@ -1398,6 +1383,30 @@ cogl_texture_new_from_file (const gchar *filename, return _cogl_texture_handle_new (tex); } +CoglHandle +cogl_texture_new_from_file (const gchar *filename, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format, + GError **error) +{ + CoglBitmap *bmp; + CoglHandle handle; + + g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); + + if (!(bmp = cogl_bitmap_new_from_file (filename, error))) + return COGL_INVALID_HANDLE; + + handle = cogl_texture_new_from_bitmap (bmp, + max_waste, + flags, + internal_format); + cogl_bitmap_free (bmp); + + return handle; +} + CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLenum gl_target, @@ -2002,24 +2011,24 @@ _cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1, static void _cogl_texture_quad_sw (CoglTexture *tex, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2) + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { CoglSpanIter iter_x , iter_y; - CoglFixed tw , th; - CoglFixed tqx , tqy; - CoglFixed first_tx , first_ty; - CoglFixed first_qx , first_qy; - CoglFixed slice_tx1 , slice_ty1; - CoglFixed slice_tx2 , slice_ty2; - CoglFixed slice_qx1 , slice_qy1; - CoglFixed slice_qx2 , slice_qy2; + float tw , th; + float tqx , tqy; + float first_tx , first_ty; + float first_qx , first_qy; + float slice_tx1 , slice_ty1; + float slice_tx2 , slice_ty2; + float slice_qx1 , slice_qy1; + float slice_qx2 , slice_qy2; GLuint gl_handle; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -2042,7 +2051,7 @@ _cogl_texture_quad_sw (CoglTexture *tex, slices */ if (tx2 < tx1) { - CoglFixed temp = x1; + float temp = x1; x1 = x2; x2 = temp; temp = tx1; @@ -2051,7 +2060,7 @@ _cogl_texture_quad_sw (CoglTexture *tex, } if (ty2 < ty1) { - CoglFixed temp = y1; + float temp = y1; y1 = y2; y2 = temp; temp = ty1; @@ -2060,27 +2069,27 @@ _cogl_texture_quad_sw (CoglTexture *tex, } /* Scale ratio from texture to quad widths */ - tw = COGL_FIXED_FROM_INT (tex->bitmap.width); - th = COGL_FIXED_FROM_INT (tex->bitmap.height); + tw = (float)(tex->bitmap.width); + th = (float)(tex->bitmap.height); - tqx = COGL_FIXED_DIV (x2 - x1, COGL_FIXED_MUL (tw, (tx2 - tx1))); - tqy = COGL_FIXED_DIV (y2 - y1, COGL_FIXED_MUL (th, (ty2 - ty1))); + tqx = (x2 - x1) / (tw * (tx2 - tx1)); + tqy = (y2 - y1) / (th * (ty2 - ty1)); /* Integral texture coordinate for first tile */ - first_tx = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (tx1)); - first_ty = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (ty1)); + first_tx = (float)(floorf (tx1)); + first_ty = (float)(floorf (ty1)); /* Denormalize texture coordinates */ - first_tx = COGL_FIXED_MUL (first_tx, tw); - first_ty = COGL_FIXED_MUL (first_ty, th); - tx1 = COGL_FIXED_MUL (tx1, tw); - ty1 = COGL_FIXED_MUL (ty1, th); - tx2 = COGL_FIXED_MUL (tx2, tw); - ty2 = COGL_FIXED_MUL (ty2, th); + first_tx = (first_tx * tw); + first_ty = (first_ty * th); + tx1 = (tx1 * tw); + ty1 = (ty1 * th); + tx2 = (tx2 * tw); + ty2 = (ty2 * th); /* Quad coordinate of the first tile */ - first_qx = x1 - COGL_FIXED_MUL (tx1 - first_tx, tqx); - first_qy = y1 - COGL_FIXED_MUL (ty1 - first_ty, tqy); + first_qx = x1 - (tx1 - first_tx) * tqx; + first_qy = y1 - (ty1 - first_ty) * tqy; /* Iterate until whole quad height covered */ @@ -2093,11 +2102,9 @@ _cogl_texture_quad_sw (CoglTexture *tex, if (!iter_y.intersects) continue; /* Span-quad intersection in quad coordinates */ - slice_qy1 = first_qy + - COGL_FIXED_MUL (iter_y.intersect_start - first_ty, tqy); + slice_qy1 = first_qy + (iter_y.intersect_start - first_ty) * tqy; - slice_qy2 = first_qy + - COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy); + slice_qy2 = first_qy + (iter_y.intersect_end - first_ty) * tqy; /* Localize slice texture coordinates */ slice_ty1 = iter_y.intersect_start - iter_y.pos; @@ -2121,11 +2128,9 @@ _cogl_texture_quad_sw (CoglTexture *tex, if (!iter_x.intersects) continue; /* Span-quad intersection in quad coordinates */ - slice_qx1 = first_qx + - COGL_FIXED_MUL (iter_x.intersect_start - first_tx, tqx); + slice_qx1 = first_qx + (iter_x.intersect_start - first_tx) * tqx; - slice_qx2 = first_qx + - COGL_FIXED_MUL (iter_x.intersect_end - first_tx, tqx); + slice_qx2 = first_qx + (iter_x.intersect_end - first_tx) * tqx; /* Localize slice texture coordinates */ slice_tx1 = iter_x.intersect_start - iter_x.pos; @@ -2141,14 +2146,14 @@ _cogl_texture_quad_sw (CoglTexture *tex, #if COGL_DEBUG printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); - printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); - printf("qy1: %f\n", COGL_FIXED_TO_FLOAT (slice_qy1)); - printf("qx2: %f\n", COGL_FIXED_TO_FLOAT (slice_qx2)); - printf("qy2: %f\n", COGL_FIXED_TO_FLOAT (slice_qy2)); - printf("tx1: %f\n", COGL_FIXED_TO_FLOAT (slice_tx1)); - printf("ty1: %f\n", COGL_FIXED_TO_FLOAT (slice_ty1)); - printf("tx2: %f\n", COGL_FIXED_TO_FLOAT (slice_tx2)); - printf("ty2: %f\n", COGL_FIXED_TO_FLOAT (slice_ty2)); + printf("qx1: %f\n", (slice_qx1)); + printf("qy1: %f\n", (slice_qy1)); + printf("qx2: %f\n", (slice_qx2)); + printf("qy2: %f\n", (slice_qy2)); + printf("tx1: %f\n", (slice_tx1)); + printf("ty1: %f\n", (slice_ty1)); + printf("tx2: %f\n", (slice_tx2)); + printf("ty2: %f\n", (slice_ty2)); #endif /* Pick and bind opengl texture object */ @@ -2164,28 +2169,28 @@ _cogl_texture_quad_sw (CoglTexture *tex, ctx->texture_target = tex->gl_target; ctx->texture_current = gl_handle; - _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1), - COGL_FIXED_TO_FLOAT (slice_qy1), - COGL_FIXED_TO_FLOAT (slice_qx2), - COGL_FIXED_TO_FLOAT (slice_qy2), - COGL_FIXED_TO_FLOAT (slice_tx1), - COGL_FIXED_TO_FLOAT (slice_ty1), - COGL_FIXED_TO_FLOAT (slice_tx2), - COGL_FIXED_TO_FLOAT (slice_ty2)); + _cogl_texture_add_quad_vertices ( (slice_qx1), + (slice_qy1), + (slice_qx2), + (slice_qy2), + (slice_tx1), + (slice_ty1), + (slice_tx2), + (slice_ty2)); } } } static void _cogl_texture_quad_hw (CoglTexture *tex, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2) + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { GLuint gl_handle; CoglTexSliceSpan *x_span; @@ -2201,10 +2206,10 @@ _cogl_texture_quad_hw (CoglTexture *tex, /* If the texture coords are all in the range [0,1] then we want to clamp the coords to the edge otherwise it can pull in edge pixels from the wrong side when scaled */ - if (tx1 >= 0 && tx1 <= COGL_FIXED_1 - && tx2 >= 0 && tx2 <= COGL_FIXED_1 - && ty1 >= 0 && ty1 <= COGL_FIXED_1 - && ty2 >= 0 && ty2 <= COGL_FIXED_1) + if (tx1 >= 0 && tx1 <= 1.0 + && tx2 >= 0 && tx2 <= 1.0 + && ty1 >= 0 && ty1 <= 1.0 + && ty2 >= 0 && ty2 <= 1.0) wrap_mode = GL_CLAMP_TO_EDGE; else wrap_mode = GL_REPEAT; @@ -2243,19 +2248,19 @@ _cogl_texture_quad_hw (CoglTexture *tex, ty2 *= y_span->size; } - _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1), - COGL_FIXED_TO_FLOAT (y1), - COGL_FIXED_TO_FLOAT (x2), - COGL_FIXED_TO_FLOAT (y2), - COGL_FIXED_TO_FLOAT (tx1), - COGL_FIXED_TO_FLOAT (ty1), - COGL_FIXED_TO_FLOAT (tx2), - COGL_FIXED_TO_FLOAT (ty2)); + _cogl_texture_add_quad_vertices ( (x1), + (y1), + (x2), + (y2), + (tx1), + (ty1), + (tx2), + (ty2)); } void cogl_texture_multiple_rectangles (CoglHandle handle, - const CoglFixed *verts, + const float *verts, guint n_rects) { CoglTexture *tex; @@ -2306,10 +2311,10 @@ cogl_texture_multiple_rectangles (CoglHandle handle, if (tex->slice_gl_handles->len == 1 && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && tex->gl_target == GL_TEXTURE_2D) - || (verts[4] >= 0 && verts[4] <= COGL_FIXED_1 - && verts[6] >= 0 && verts[6] <= COGL_FIXED_1 - && verts[5] >= 0 && verts[5] <= COGL_FIXED_1 - && verts[7] >= 0 && verts[7] <= COGL_FIXED_1))) + || (verts[4] >= 0 && verts[4] <= 1.0 + && verts[6] >= 0 && verts[6] <= 1.0 + && verts[5] >= 0 && verts[5] <= 1.0 + && verts[7] >= 0 && verts[7] <= 1.0))) _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3], verts[4],verts[5], verts[6],verts[7]); else @@ -2325,16 +2330,16 @@ cogl_texture_multiple_rectangles (CoglHandle handle, void cogl_texture_rectangle (CoglHandle handle, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2) + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { - CoglFixed verts[8]; + float verts[8]; verts[0] = x1; verts[1] = y1; @@ -2447,16 +2452,16 @@ cogl_texture_polygon (CoglHandle handle, OpenGL */ for (i = 0; i < n_vertices; i++, p++) { - CoglFixed tx, ty; + float tx, ty; -#define CFX_F COGL_FIXED_TO_FLOAT +#define CFX_F tx = ((vertices[i].tx - - (COGL_FIXED_FROM_INT (x_span->start) + - ((float)(x_span->start) / tex->bitmap.width)) * tex->bitmap.width / x_span->size); ty = ((vertices[i].ty - - (COGL_FIXED_FROM_INT (y_span->start) + - ((float)(y_span->start) / tex->bitmap.height)) * tex->bitmap.height / y_span->size); diff --git a/clutter/cogl/gl/cogl.c b/clutter/cogl/gl/cogl.c index 411cd8adc..78b2a908c 100644 --- a/clutter/cogl/gl/cogl.c +++ b/clutter/cogl/gl/cogl.c @@ -209,40 +209,23 @@ cogl_pop_matrix (void) } void -cogl_scale (CoglFixed x, CoglFixed y) +cogl_scale (float x, float y) { - glScaled (COGL_FIXED_TO_DOUBLE (x), - COGL_FIXED_TO_DOUBLE (y), + glScalef ((float)(x), + (float)(y), 1.0); } void -cogl_translatex (CoglFixed x, CoglFixed y, CoglFixed z) +cogl_translate (float x, float y, float z) { - glTranslated (COGL_FIXED_TO_DOUBLE (x), - COGL_FIXED_TO_DOUBLE (y), - COGL_FIXED_TO_DOUBLE (z)); + glTranslatef (x, y, z); } void -cogl_translate (gint x, gint y, gint z) +cogl_rotate (float angle, float x, float y, float z) { - glTranslatef ((float)x, (float)y, (float)z); -} - -void -cogl_rotatex (CoglFixed angle, gint x, gint y, gint z) -{ - glRotated (COGL_FIXED_TO_DOUBLE (angle), - COGL_FIXED_TO_DOUBLE (x), - COGL_FIXED_TO_DOUBLE (y), - COGL_FIXED_TO_DOUBLE (z)); -} - -void -cogl_rotate (gint angle, gint x, gint y, gint z) -{ - glRotatef ((float)angle, (float)x, (float)y, (float)z); + glRotatef (angle, x, y, z); } static inline gboolean @@ -466,24 +449,24 @@ set_clip_plane (GLint plane_num, } void -_cogl_set_clip_planes (CoglFixed x_offset, - CoglFixed y_offset, - CoglFixed width, - CoglFixed height) +_cogl_set_clip_planes (float x_offset, + float y_offset, + float width, + float height) { GLfloat modelview[16], projection[16]; - GLfloat vertex_tl[4] = { COGL_FIXED_TO_FLOAT (x_offset), - COGL_FIXED_TO_FLOAT (y_offset), + GLfloat vertex_tl[4] = { (x_offset), + (y_offset), 0.0f, 1.0f }; - GLfloat vertex_tr[4] = { COGL_FIXED_TO_FLOAT (x_offset + width), - COGL_FIXED_TO_FLOAT (y_offset), + GLfloat vertex_tr[4] = { (x_offset + width), + (y_offset), 0.0f, 1.0f }; - GLfloat vertex_bl[4] = { COGL_FIXED_TO_FLOAT (x_offset), - COGL_FIXED_TO_FLOAT (y_offset + height), + GLfloat vertex_bl[4] = { (x_offset), + (y_offset + height), 0.0f, 1.0f }; - GLfloat vertex_br[4] = { COGL_FIXED_TO_FLOAT (x_offset + width), - COGL_FIXED_TO_FLOAT (y_offset + height), + GLfloat vertex_br[4] = { (x_offset + width), + (y_offset + height), 0.0f, 1.0f }; GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) ); @@ -518,10 +501,10 @@ _cogl_set_clip_planes (CoglFixed x_offset, } void -_cogl_add_stencil_clip (CoglFixed x_offset, - CoglFixed y_offset, - CoglFixed width, - CoglFixed height, +_cogl_add_stencil_clip (float x_offset, + float y_offset, + float width, + float height, gboolean first) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -537,10 +520,10 @@ _cogl_add_stencil_clip (CoglFixed x_offset, /* Punch out a hole to allow the rectangle */ GE( glStencilFunc (GL_NEVER, 0x1, 0x1) ); GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) ); - GE( glRectf (COGL_FIXED_TO_FLOAT (x_offset), - COGL_FIXED_TO_FLOAT (y_offset), - COGL_FIXED_TO_FLOAT (x_offset + width), - COGL_FIXED_TO_FLOAT (y_offset + height)) ); + GE( glRectf ( (x_offset), + (y_offset), + (x_offset + width), + (y_offset + height)) ); } else { @@ -548,10 +531,10 @@ _cogl_add_stencil_clip (CoglFixed x_offset, rectangle */ GE( glStencilFunc (GL_NEVER, 0x1, 0x3) ); GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); - GE( glRectf (COGL_FIXED_TO_FLOAT (x_offset), - COGL_FIXED_TO_FLOAT (y_offset), - COGL_FIXED_TO_FLOAT (x_offset + width), - COGL_FIXED_TO_FLOAT (y_offset + height)) ); + GE( glRectf ( (x_offset), + (y_offset), + (x_offset + width), + (y_offset + height)) ); /* Subtract one from all pixels in the stencil buffer so that only pixels where both the original stencil buffer and the @@ -574,13 +557,13 @@ _cogl_add_stencil_clip (CoglFixed x_offset, } void -_cogl_set_matrix (const CoglFixed *matrix) +_cogl_set_matrix (const float *matrix) { float float_matrix[16]; int i; for (i = 0; i < 16; i++) - float_matrix[i] = COGL_FIXED_TO_FLOAT (matrix[i]); + float_matrix[i] = (matrix[i]); GE( glLoadIdentity () ); GE( glMultMatrixf (float_matrix) ); @@ -612,20 +595,20 @@ _cogl_disable_clip_planes (void) void cogl_alpha_func (COGLenum func, - CoglFixed ref) + float ref) { - GE( glAlphaFunc (func, COGL_FIXED_TO_FLOAT(ref)) ); + GE( glAlphaFunc (func, (ref)) ); } void -cogl_perspective (CoglFixed fovy, - CoglFixed aspect, - CoglFixed zNear, - CoglFixed zFar) +cogl_perspective (float fovy, + float aspect, + float zNear, + float zFar) { - CoglFixed xmax, ymax; - CoglFixed x, y, c, d; - CoglFixed fovy_rad_half = COGL_FIXED_MUL (fovy, COGL_FIXED_PI) / 360; + float xmax, ymax; + float x, y, c, d; + float fovy_rad_half = (fovy * G_PI) / 360; GLfloat m[16]; @@ -645,23 +628,19 @@ cogl_perspective (CoglFixed fovy, * 2) When working with small numbers, we are loosing significant * precision */ - ymax = - COGL_FIXED_MUL (zNear, - COGL_FIXED_FAST_DIV (cogl_fixed_sin (fovy_rad_half), - cogl_fixed_cos (fovy_rad_half))); + ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half))); + xmax = (ymax * aspect); - xmax = COGL_FIXED_MUL (ymax, aspect); - - x = COGL_FIXED_FAST_DIV (zNear, xmax); - y = COGL_FIXED_FAST_DIV (zNear, ymax); - c = COGL_FIXED_FAST_DIV (-(zFar + zNear), ( zFar - zNear)); - d = cogl_fixed_mul_div (-(2 * zFar), zNear, (zFar - zNear)); + x = (zNear / xmax); + y = (zNear / ymax); + c = (-(zFar + zNear) / ( zFar - zNear)); + d = (-(2 * zFar) * zNear) / (zFar - zNear); #define M(row,col) m[col*4+row] - M(0,0) = COGL_FIXED_TO_FLOAT (x); - M(1,1) = COGL_FIXED_TO_FLOAT (y); - M(2,2) = COGL_FIXED_TO_FLOAT (c); - M(2,3) = COGL_FIXED_TO_FLOAT (d); + M(0,0) = (x); + M(1,1) = (y); + M(2,2) = (c); + M(2,3) = (d); M(3,2) = -1.0F; GE( glMultMatrixf (m) ); @@ -672,22 +651,22 @@ cogl_perspective (CoglFixed fovy, memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16); #define m ctx->inverse_projection - M(0, 0) = 1.0f / COGL_FIXED_TO_FLOAT (x); - M(1, 1) = 1.0f / COGL_FIXED_TO_FLOAT (y); + M(0, 0) = 1.0f / (x); + M(1, 1) = 1.0f / (y); M(2, 3) = -1.0f; - M(3, 2) = 1.0f / COGL_FIXED_TO_FLOAT (d); - M(3, 3) = COGL_FIXED_TO_FLOAT (c) / COGL_FIXED_TO_FLOAT (d); + M(3, 2) = 1.0f / (d); + M(3, 3) = (c) / (d); #undef m #undef M } void -cogl_frustum (CoglFixed left, - CoglFixed right, - CoglFixed bottom, - CoglFixed top, - CoglFixed z_near, - CoglFixed z_far) +cogl_frustum (float left, + float right, + float bottom, + float top, + float z_near, + float z_far) { GLfloat c, d; @@ -696,32 +675,32 @@ cogl_frustum (CoglFixed left, GE( glMatrixMode (GL_PROJECTION) ); GE( glLoadIdentity () ); - GE( glFrustum (COGL_FIXED_TO_DOUBLE (left), - COGL_FIXED_TO_DOUBLE (right), - COGL_FIXED_TO_DOUBLE (bottom), - COGL_FIXED_TO_DOUBLE (top), - COGL_FIXED_TO_DOUBLE (z_near), - COGL_FIXED_TO_DOUBLE (z_far)) ); + GE( glFrustum ((GLdouble)(left), + (GLdouble)(right), + (GLdouble)(bottom), + (GLdouble)(top), + (GLdouble)(z_near), + (GLdouble)(z_far)) ); GE( glMatrixMode (GL_MODELVIEW) ); /* Calculate and store the inverse of the matrix */ memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16); - c = -COGL_FIXED_TO_FLOAT (z_far + z_near) - / COGL_FIXED_TO_FLOAT (z_far - z_near); - d = -COGL_FIXED_TO_FLOAT (2 * COGL_FIXED_MUL (z_far, z_near)) - / COGL_FIXED_TO_FLOAT (z_far - z_near); + c = - (z_far + z_near) + / (z_far - z_near); + d = - (2 * (z_far * z_near)) + / (z_far - z_near); #define M(row,col) ctx->inverse_projection[col*4+row] - M(0,0) = COGL_FIXED_TO_FLOAT (right - left) - / COGL_FIXED_TO_FLOAT (2 * z_near); - M(0,3) = COGL_FIXED_TO_FLOAT (right + left) - / COGL_FIXED_TO_FLOAT (2 * z_near); - M(1,1) = COGL_FIXED_TO_FLOAT (top - bottom) - / COGL_FIXED_TO_FLOAT (2 * z_near); - M(1,3) = COGL_FIXED_TO_FLOAT (top + bottom) - / COGL_FIXED_TO_FLOAT (2 * z_near); + M(0,0) = (right - left) + / (2 * z_near); + M(0,3) = (right + left) + / (2 * z_near); + M(1,1) = (top - bottom) + / (2 * z_near); + M(1,3) = (top + bottom) + / (2 * z_near); M(2,3) = -1.0f; M(3,2) = 1.0f / d; M(3,3) = c / d; @@ -738,45 +717,61 @@ cogl_viewport (guint width, void cogl_setup_viewport (guint width, guint height, - CoglFixed fovy, - CoglFixed aspect, - CoglFixed z_near, - CoglFixed z_far) + float fovy, + float aspect, + float z_near, + float z_far) { GLfloat z_camera; + GLfloat projection_matrix[16]; GE( glViewport (0, 0, width, height) ); cogl_perspective (fovy, aspect, z_near, z_far); - GE( glLoadIdentity () ); - /* - * camera distance from screen, 0.5 * tan (FOV) + * In theory, we can compute the camera distance from screen as: * - * We have been having some problems with this; the theoretically correct - * value of 0.866025404f for the default 60 deg fovy angle happens to be - * touch to small in reality, which on full-screen stage with an actor of - * the same size results in about 1px on the left and top edges of the - * actor being offscreen. Perhaps more significantly, it also causes - * hinting artifacts when rendering text. + * 0.5 * tan (FOV) * - * So for the default 60 deg angle we worked out that the value of 0.869 - * is giving correct stretch and no noticeable artifacts on text. Seems - * good on all drivers too. + * However, it's better to compute the z_camera from our projection + * matrix so that we get a 1:1 mapping at the screen distance. Consider + * the upper-left corner of the screen. It has object coordinates + * (0,0,0), so by the transform below, ends up with eye coordinate + * + * x_eye = x_object / width - 0.5 = - 0.5 + * y_eye = (height - y_object) / width - 0.5 = 0.5 + * z_eye = z_object / width - z_camera = - z_camera + * + * From cogl_perspective(), we know that the projection matrix has + * the form: + * + * (x, 0, 0, 0) + * (0, y, 0, 0) + * (0, 0, c, d) + * (0, 0, -1, 0) + * + * Applied to the above, we get clip coordinates of + * + * x_clip = x * (- 0.5) + * y_clip = y * 0.5 + * w_clip = - 1 * (- z_camera) = z_camera + * + * Dividing through by w to get normalized device coordinates, we + * have, x_nd = x * 0.5 / z_camera, y_nd = - y * 0.5 / z_camera. + * The upper left corner of the screen has normalized device coordinates, + * (-1, 1), so to have the correct 1:1 mapping, we have to have: + * + * z_camera = 0.5 * x = 0.5 * y + * + * If x != y, then we have a non-uniform aspect ration, and a 1:1 mapping + * doesn't make sense. */ -#define DEFAULT_Z_CAMERA 0.869f - z_camera = DEFAULT_Z_CAMERA; + cogl_get_projection_matrix (projection_matrix); + z_camera = 0.5 * projection_matrix[0]; - if (fovy != COGL_FIXED_60) - { - CoglFixed fovy_rad = COGL_FIXED_MUL (fovy, COGL_FIXED_PI) / 180; - - z_camera = - COGL_FIXED_TO_FLOAT (COGL_FIXED_DIV (cogl_fixed_sin (fovy_rad), - cogl_fixed_cos (fovy_rad)) >> 1); - } + GE( glLoadIdentity () ); GE( glTranslatef (-0.5f, -0.5f, -z_camera) ); GE( glScalef ( 1.0f / width, @@ -1164,75 +1159,21 @@ cogl_features_available (CoglFeatureFlags features) } void -cogl_get_modelview_matrix (CoglFixed m[16]) +cogl_get_modelview_matrix (float m[16]) { - GLdouble md[16]; - - glGetDoublev(GL_MODELVIEW_MATRIX, &md[0]); - -#define M(m,row,col) m[col*4+row] - M(m,0,0) = COGL_FIXED_FROM_FLOAT (M(md,0,0)); - M(m,0,1) = COGL_FIXED_FROM_FLOAT (M(md,0,1)); - M(m,0,2) = COGL_FIXED_FROM_FLOAT (M(md,0,2)); - M(m,0,3) = COGL_FIXED_FROM_FLOAT (M(md,0,3)); - - M(m,1,0) = COGL_FIXED_FROM_FLOAT (M(md,1,0)); - M(m,1,1) = COGL_FIXED_FROM_FLOAT (M(md,1,1)); - M(m,1,2) = COGL_FIXED_FROM_FLOAT (M(md,1,2)); - M(m,1,3) = COGL_FIXED_FROM_FLOAT (M(md,1,3)); - - M(m,2,0) = COGL_FIXED_FROM_FLOAT (M(md,2,0)); - M(m,2,1) = COGL_FIXED_FROM_FLOAT (M(md,2,1)); - M(m,2,2) = COGL_FIXED_FROM_FLOAT (M(md,2,2)); - M(m,2,3) = COGL_FIXED_FROM_FLOAT (M(md,2,3)); - - M(m,3,0) = COGL_FIXED_FROM_FLOAT (M(md,3,0)); - M(m,3,1) = COGL_FIXED_FROM_FLOAT (M(md,3,1)); - M(m,3,2) = COGL_FIXED_FROM_FLOAT (M(md,3,2)); - M(m,3,3) = COGL_FIXED_FROM_FLOAT (M(md,3,3)); -#undef M + glGetFloatv (GL_MODELVIEW_MATRIX, m); } void -cogl_get_projection_matrix (CoglFixed m[16]) +cogl_get_projection_matrix (float m[16]) { - GLdouble md[16]; - - glGetDoublev(GL_PROJECTION_MATRIX, &md[0]); - -#define M(m,row,col) m[col*4+row] - M(m,0,0) = COGL_FIXED_FROM_FLOAT (M(md,0,0)); - M(m,0,1) = COGL_FIXED_FROM_FLOAT (M(md,0,1)); - M(m,0,2) = COGL_FIXED_FROM_FLOAT (M(md,0,2)); - M(m,0,3) = COGL_FIXED_FROM_FLOAT (M(md,0,3)); - - M(m,1,0) = COGL_FIXED_FROM_FLOAT (M(md,1,0)); - M(m,1,1) = COGL_FIXED_FROM_FLOAT (M(md,1,1)); - M(m,1,2) = COGL_FIXED_FROM_FLOAT (M(md,1,2)); - M(m,1,3) = COGL_FIXED_FROM_FLOAT (M(md,1,3)); - - M(m,2,0) = COGL_FIXED_FROM_FLOAT (M(md,2,0)); - M(m,2,1) = COGL_FIXED_FROM_FLOAT (M(md,2,1)); - M(m,2,2) = COGL_FIXED_FROM_FLOAT (M(md,2,2)); - M(m,2,3) = COGL_FIXED_FROM_FLOAT (M(md,2,3)); - - M(m,3,0) = COGL_FIXED_FROM_FLOAT (M(md,3,0)); - M(m,3,1) = COGL_FIXED_FROM_FLOAT (M(md,3,1)); - M(m,3,2) = COGL_FIXED_FROM_FLOAT (M(md,3,2)); - M(m,3,3) = COGL_FIXED_FROM_FLOAT (M(md,3,3)); -#undef M + glGetFloatv (GL_PROJECTION_MATRIX, m); } void -cogl_get_viewport (CoglFixed v[4]) +cogl_get_viewport (float v[4]) { - GLdouble vd[4]; - glGetDoublev(GL_VIEWPORT, &vd[0]); - - v[0] = COGL_FIXED_FROM_FLOAT (vd[0]); - v[1] = COGL_FIXED_FROM_FLOAT (vd[1]); - v[2] = COGL_FIXED_FROM_FLOAT (vd[2]); - v[3] = COGL_FIXED_FROM_FLOAT (vd[3]); + glGetFloatv (GL_VIEWPORT, v); } void @@ -1263,9 +1204,9 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha) void cogl_fog_set (const CoglColor *fog_color, - CoglFixed density, - CoglFixed start, - CoglFixed stop) + float density, + float start, + float stop) { GLfloat fogColor[4]; @@ -1281,8 +1222,8 @@ cogl_fog_set (const CoglColor *fog_color, glFogi (GL_FOG_MODE, GL_LINEAR); glHint (GL_FOG_HINT, GL_NICEST); - glFogf (GL_FOG_DENSITY, COGL_FIXED_TO_FLOAT (density)); - glFogf (GL_FOG_START, COGL_FIXED_TO_FLOAT (start)); - glFogf (GL_FOG_END, COGL_FIXED_TO_FLOAT (stop)); + glFogf (GL_FOG_DENSITY, (density)); + glFogf (GL_FOG_START, (start)); + glFogf (GL_FOG_END, (stop)); } diff --git a/clutter/cogl/gles/Makefile.am b/clutter/cogl/gles/Makefile.am index f552df269..377253230 100644 --- a/clutter/cogl/gles/Makefile.am +++ b/clutter/cogl/gles/Makefile.am @@ -10,7 +10,7 @@ libclutterinclude_HEADERS = \ $(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-types.h \ - $(top_builddir)/clutter/cogl/cogl-mesh.h \ + $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h \ $(top_builddir)/clutter/cogl/cogl-material.h \ $(top_builddir)/clutter/cogl/cogl-matrix.h diff --git a/clutter/cogl/gles/cogl-context.c b/clutter/cogl/gles/cogl-context.c index ee64cbab5..496969ae2 100644 --- a/clutter/cogl/gles/cogl-context.c +++ b/clutter/cogl/gles/cogl-context.c @@ -73,7 +73,7 @@ cogl_create_context () _context->shader_handles = NULL; _context->draw_buffer = COGL_WINDOW_BUFFER; - _context->mesh_handles = NULL; + _context->vertex_buffer_handles = NULL; _context->blend_src_factor = CGL_SRC_ALPHA; _context->blend_dst_factor = CGL_ONE_MINUS_SRC_ALPHA; @@ -84,7 +84,7 @@ cogl_create_context () #endif /* Init OpenGL state */ - GE( cogl_wrap_glTexEnvx (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ); + GE( cogl_wrap_glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ); GE( glColorMask (TRUE, TRUE, TRUE, FALSE) ); GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ); cogl_enable (0); diff --git a/clutter/cogl/gles/cogl-context.h b/clutter/cogl/gles/cogl-context.h index 88e02e2aa..c1d107270 100644 --- a/clutter/cogl/gles/cogl-context.h +++ b/clutter/cogl/gles/cogl-context.h @@ -53,15 +53,15 @@ typedef struct gboolean enable_backface_culling; /* Primitives */ - CoglFixedVec2 path_start; - CoglFixedVec2 path_pen; + floatVec2 path_start; + floatVec2 path_pen; GArray *path_nodes; guint last_path; - CoglFixedVec2 path_nodes_min; - CoglFixedVec2 path_nodes_max; + floatVec2 path_nodes_min; + floatVec2 path_nodes_max; /* Cache of inverse projection matrix */ - CoglFixed inverse_projection[16]; + float inverse_projection[16]; /* Textures */ GArray *texture_handles; @@ -72,6 +72,7 @@ typedef struct can be flushed */ GLuint texture_current; GLenum texture_target; + GLenum texture_format; /* Materials */ GArray *material_handles; @@ -86,8 +87,8 @@ typedef struct GArray *program_handles; GArray *shader_handles; - /* Mesh */ - GArray *mesh_handles; + /* Vertex buffers */ + GArray *vertex_buffer_handles; /* Clip stack */ CoglClipStackState clip; diff --git a/clutter/cogl/gles/cogl-fbo.c b/clutter/cogl/gles/cogl-fbo.c index d5b02818b..3b1099e26 100644 --- a/clutter/cogl/gles/cogl-fbo.c +++ b/clutter/cogl/gles/cogl-fbo.c @@ -227,12 +227,12 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen) /* Setup new viewport and matrices */ GE( glViewport (0, 0, fbo->width, fbo->height) ); - GE( cogl_wrap_glTranslatex (-COGL_FIXED_1, -COGL_FIXED_1, 0) ); - GE( cogl_wrap_glScalex (COGL_FIXED_DIV (COGL_FIXED_FROM_INT (2), - COGL_FIXED_FROM_INT (fbo->width)), - COGL_FIXED_DIV (COGL_FIXED_FROM_INT (2), - COGL_FIXED_FROM_INT (fbo->height)), - COGL_FIXED_1) ); + GE( cogl_wrap_glTranslatef (-1.0, -1.0, 0) ); + GE( cogl_wrap_glScalef (((float)(2) / + (float)(fbo->width)), + ((float)(2) / + (float)(fbo->height)), + 1.0) ); /* Bind offscreen framebuffer object */ GE( glBindFramebuffer (GL_FRAMEBUFFER, fbo->gl_handle) ); diff --git a/clutter/cogl/gles/cogl-gles2-wrapper.c b/clutter/cogl/gles/cogl-gles2-wrapper.c index f3ef6355b..387416aaa 100644 --- a/clutter/cogl/gles/cogl-gles2-wrapper.c +++ b/clutter/cogl/gles/cogl-gles2-wrapper.c @@ -105,7 +105,7 @@ cogl_gles2_wrapper_create_shader (GLenum type, const char *source) void cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper) { - GLfixed default_fog_color[4] = { 0, 0, 0, 0 }; + GLfloat default_fog_color[4] = { 0, 0, 0, 0 }; memset (wrapper, 0, sizeof (CoglGles2Wrapper)); @@ -125,11 +125,11 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper) /* Initialize the fogging options */ cogl_wrap_glDisable (GL_FOG); - cogl_wrap_glFogx (GL_FOG_MODE, GL_LINEAR); - cogl_wrap_glFogx (GL_FOG_DENSITY, COGL_FIXED_1); - cogl_wrap_glFogx (GL_FOG_START, 0); - cogl_wrap_glFogx (GL_FOG_END, 1); - cogl_wrap_glFogxv (GL_FOG_COLOR, default_fog_color); + cogl_wrap_glFogf (GL_FOG_MODE, GL_LINEAR); + cogl_wrap_glFogf (GL_FOG_DENSITY, 1.0); + cogl_wrap_glFogf (GL_FOG_START, 0); + cogl_wrap_glFogf (GL_FOG_END, 1); + cogl_wrap_glFogfv (GL_FOG_COLOR, default_fog_color); /* Initialize alpha testing */ cogl_wrap_glDisable (GL_ALPHA_TEST); @@ -639,15 +639,6 @@ cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper, GLenum matrix_num) } } -void -cogl_wrap_glClearColorx (GLclampx r, GLclampx g, GLclampx b, GLclampx a) -{ - glClearColor (COGL_FIXED_TO_FLOAT (r), - COGL_FIXED_TO_FLOAT (g), - COGL_FIXED_TO_FLOAT (b), - COGL_FIXED_TO_FLOAT (a)); -} - void cogl_wrap_glPushMatrix () { @@ -810,58 +801,58 @@ cogl_wrap_glMultMatrix (const float *m) } void -cogl_wrap_glMultMatrixx (const GLfixed *m) +cogl_wrap_glMultMatrixf (const GLfloat *m) { float new_matrix[16]; int i; for (i = 0; i < 16; i++) - new_matrix[i] = COGL_FIXED_TO_FLOAT (m[i]); + new_matrix[i] = (m[i]); cogl_wrap_glMultMatrix (new_matrix); } void -cogl_wrap_glFrustumx (GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed z_near, GLfixed z_far) +cogl_wrap_glFrustumf (GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat z_near, GLfloat z_far) { float matrix[16]; - float two_near = COGL_FIXED_TO_FLOAT (2 * z_near); + float two_near = (2 * z_near); memset (matrix, 0, sizeof (matrix)); - matrix[0] = two_near / COGL_FIXED_TO_FLOAT (right - left); - matrix[5] = two_near / COGL_FIXED_TO_FLOAT (top - bottom); - matrix[8] = COGL_FIXED_TO_FLOAT (right + left) - / COGL_FIXED_TO_FLOAT (right - left); - matrix[9] = COGL_FIXED_TO_FLOAT (top + bottom) - / COGL_FIXED_TO_FLOAT (top - bottom); - matrix[10] = -COGL_FIXED_TO_FLOAT (z_far + z_near) - / COGL_FIXED_TO_FLOAT (z_far - z_near); + matrix[0] = two_near / (right - left); + matrix[5] = two_near / (top - bottom); + matrix[8] = (right + left) + / (right - left); + matrix[9] = (top + bottom) + / (top - bottom); + matrix[10] = - (z_far + z_near) + / (z_far - z_near); matrix[11] = -1.0f; - matrix[14] = -two_near * COGL_FIXED_TO_FLOAT (z_far) - / COGL_FIXED_TO_FLOAT (z_far - z_near); + matrix[14] = -two_near * (z_far) + / (z_far - z_near); cogl_wrap_glMultMatrix (matrix); } void -cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z) +cogl_wrap_glScalef (GLfloat x, GLfloat y, GLfloat z) { float matrix[16]; memset (matrix, 0, sizeof (matrix)); - matrix[0] = COGL_FIXED_TO_FLOAT (x); - matrix[5] = COGL_FIXED_TO_FLOAT (y); - matrix[10] = COGL_FIXED_TO_FLOAT (z); + matrix[0] = (x); + matrix[5] = (y); + matrix[10] = (z); matrix[15] = 1.0f; cogl_wrap_glMultMatrix (matrix); } void -cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z) +cogl_wrap_glTranslatef (GLfloat x, GLfloat y, GLfloat z) { float matrix[16]; @@ -869,22 +860,22 @@ cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z) matrix[0] = 1.0f; matrix[5] = 1.0f; matrix[10] = 1.0f; - matrix[12] = COGL_FIXED_TO_FLOAT (x); - matrix[13] = COGL_FIXED_TO_FLOAT (y); - matrix[14] = COGL_FIXED_TO_FLOAT (z); + matrix[12] = (x); + matrix[13] = (y); + matrix[14] = (z); matrix[15] = 1.0f; cogl_wrap_glMultMatrix (matrix); } void -cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z) +cogl_wrap_glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { float matrix[16]; - float xf = COGL_FIXED_TO_FLOAT (x); - float yf = COGL_FIXED_TO_FLOAT (y); - float zf = COGL_FIXED_TO_FLOAT (z); - float anglef = COGL_FIXED_TO_FLOAT (angle) * G_PI / 180.0f; + float xf = (x); + float yf = (y); + float zf = (z); + float anglef = (angle) * G_PI / 180.0f; float c = cosf (anglef); float s = sinf (anglef); @@ -912,21 +903,21 @@ cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z) } void -cogl_wrap_glOrthox (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, - GLfixed near, GLfixed far) +cogl_wrap_glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, + GLfloat near, GLfloat far) { float matrix[16]; - float xrange = COGL_FIXED_TO_FLOAT (right - left); - float yrange = COGL_FIXED_TO_FLOAT (top - bottom); - float zrange = COGL_FIXED_TO_FLOAT (far - near); + float xrange = (right - left); + float yrange = (top - bottom); + float zrange = (far - near); memset (matrix, 0, sizeof (matrix)); matrix[0] = 2.0f / xrange; matrix[5] = 2.0f / yrange; matrix[10] = 2.0f / zrange; - matrix[12] = COGL_FIXED_TO_FLOAT (right + left) / xrange; - matrix[13] = COGL_FIXED_TO_FLOAT (top + bottom) / yrange; - matrix[14] = COGL_FIXED_TO_FLOAT (far + near) / zrange; + matrix[12] = (right + left) / xrange; + matrix[13] = (top + bottom) / yrange; + matrix[14] = (far + near) / zrange; matrix[15] = 1.0f; cogl_wrap_glMultMatrix (matrix); @@ -1049,8 +1040,8 @@ cogl_gles2_do_set_uniform (GLint location, CoglBoxedValue *value) } } -void -cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) +static void +cogl_wrap_prepare_for_draw (void) { CoglGles2WrapperProgram *program; @@ -1247,9 +1238,25 @@ cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) w->dirty_vertex_attrib_enables = 0; } } +} + +void +cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) +{ + cogl_wrap_prepare_for_draw (); + glDrawArrays (mode, first, count); } +void +cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + cogl_wrap_prepare_for_draw (); + + glDrawElements (mode, count, type, indices); +} + void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, GLenum internal_format) @@ -1268,7 +1275,7 @@ cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, } void -cogl_wrap_glTexEnvx (GLenum target, GLenum pname, GLfixed param) +cogl_wrap_glTexEnvf (GLenum target, GLenum pname, GLfloat param) { /* This function is only used to set the texture mode once to GL_MODULATE. The shader is hard-coded to modulate the texture so @@ -1479,30 +1486,17 @@ cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref) } void -cogl_wrap_glColor4x (GLclampx r, GLclampx g, GLclampx b, GLclampx a) +cogl_wrap_glColor4f (GLclampf r, GLclampf g, GLclampf b, GLclampf a) { - glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB, - COGL_FIXED_TO_FLOAT (r), - COGL_FIXED_TO_FLOAT (g), - COGL_FIXED_TO_FLOAT (b), - COGL_FIXED_TO_FLOAT (a)); + glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB, r, g, b, a); } void -cogl_wrap_glClipPlanex (GLenum plane, GLfixed *equation) +cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation) { /* FIXME */ } -static void -cogl_gles2_float_array_to_fixed (int size, - const GLfloat *floats, - GLfixed *fixeds) -{ - while (size-- > 0) - *(fixeds++) = COGL_FIXED_FROM_FLOAT (*(floats++)); -} - void cogl_wrap_glGetIntegerv (GLenum pname, GLint *params) { @@ -1525,37 +1519,30 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params) } void -cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params) +cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params) { _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); switch (pname) { case GL_MODELVIEW_MATRIX: - cogl_gles2_float_array_to_fixed (16, w->modelview_stack - + w->modelview_stack_pos * 16, - params); + memcpy (params, w->modelview_stack + w->modelview_stack_pos * 16, + sizeof (GLfloat) * 16); break; case GL_PROJECTION_MATRIX: - cogl_gles2_float_array_to_fixed (16, w->projection_stack - + w->projection_stack_pos * 16, - params); + memcpy (params, w->projection_stack + w->projection_stack_pos * 16, + sizeof (GLfloat) * 16); break; case GL_VIEWPORT: - { - GLfloat v[4]; - - glGetFloatv (GL_VIEWPORT, v); - cogl_gles2_float_array_to_fixed (4, v, params); - } + glGetFloatv (GL_VIEWPORT, params); break; } } void -cogl_wrap_glFogx (GLenum pname, GLfixed param) +cogl_wrap_glFogf (GLenum pname, GLfloat param) { _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); @@ -1567,23 +1554,23 @@ cogl_wrap_glFogx (GLenum pname, GLfixed param) case GL_FOG_DENSITY: _COGL_GLES2_CHANGE_UNIFORM (w, FOG_DENSITY, fog_density, - COGL_FIXED_TO_FLOAT (param)); + (param)); break; case GL_FOG_START: _COGL_GLES2_CHANGE_UNIFORM (w, FOG_START, fog_start, - COGL_FIXED_TO_FLOAT (param)); + (param)); break; case GL_FOG_END: _COGL_GLES2_CHANGE_UNIFORM (w, FOG_END, fog_end, - COGL_FIXED_TO_FLOAT (param)); + (param)); break; } } void -cogl_wrap_glFogxv (GLenum pname, const GLfixed *params) +cogl_wrap_glFogfv (GLenum pname, const GLfloat *params) { int i; _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); @@ -1591,7 +1578,7 @@ cogl_wrap_glFogxv (GLenum pname, const GLfixed *params) if (pname == GL_FOG_COLOR) { for (i = 0; i < 4; i++) - w->fog_color[i] = COGL_FIXED_TO_FLOAT (params[i]); + w->fog_color[i] = (params[i]); w->dirty_uniforms |= COGL_GLES2_DIRTY_FOG_COLOR; } diff --git a/clutter/cogl/gles/cogl-gles2-wrapper.h b/clutter/cogl/gles/cogl-gles2-wrapper.h index 76100a842..5cbad279d 100644 --- a/clutter/cogl/gles/cogl-gles2-wrapper.h +++ b/clutter/cogl/gles/cogl-gles2-wrapper.h @@ -264,22 +264,20 @@ struct _CoglGles2WrapperShader void cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper); void cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper); -void cogl_wrap_glClearColorx (GLclampx r, GLclampx g, GLclampx b, GLclampx a); - void cogl_wrap_glPushMatrix (); void cogl_wrap_glPopMatrix (); void cogl_wrap_glMatrixMode (GLenum mode); void cogl_wrap_glLoadIdentity (); -void cogl_wrap_glMultMatrixx (const GLfixed *m); -void cogl_wrap_glFrustumx (GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed z_near, GLfixed z_far); -void cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z); -void cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z); -void cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -void cogl_wrap_glOrthox (GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed near, GLfixed far); +void cogl_wrap_glMultMatrixf (const GLfloat *m); +void cogl_wrap_glFrustumf (GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat z_near, GLfloat z_far); +void cogl_wrap_glScalef (GLfloat x, GLfloat y, GLfloat z); +void cogl_wrap_glTranslatef (GLfloat x, GLfloat y, GLfloat z); +void cogl_wrap_glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +void cogl_wrap_glOrthof (GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat near, GLfloat far); void cogl_wrap_glEnable (GLenum cap); void cogl_wrap_glDisable (GLenum cap); @@ -293,7 +291,7 @@ void cogl_wrap_glColorPointer (GLint size, GLenum type, GLsizei stride, void cogl_wrap_glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); -void cogl_wrap_glTexEnvx (GLenum target, GLenum pname, GLfixed param); +void cogl_wrap_glTexEnvf (GLenum target, GLenum pname, GLfloat param); void cogl_wrap_glClientActiveTexture (GLenum texture); void cogl_wrap_glActiveTexture (GLenum texture); @@ -303,18 +301,19 @@ void cogl_wrap_glDisableClientState (GLenum array); void cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref); -void cogl_wrap_glColor4x (GLclampx r, GLclampx g, GLclampx b, GLclampx a); +void cogl_wrap_glColor4f (GLclampf r, GLclampf g, GLclampf b, GLclampf a); -void cogl_wrap_glClipPlanex (GLenum plane, GLfixed *equation); +void cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation); void cogl_wrap_glGetIntegerv (GLenum pname, GLint *params); -void cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params); +void cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params); -void cogl_wrap_glFogx (GLenum pname, GLfixed param); -void cogl_wrap_glFogxv (GLenum pname, const GLfixed *params); +void cogl_wrap_glFogf (GLenum pname, GLfloat param); +void cogl_wrap_glFogfv (GLenum pname, const GLfloat *params); void cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count); - +void cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); void cogl_wrap_glTexParameteri (GLenum target, GLenum pname, GLfloat param); void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, @@ -330,35 +329,35 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program); /* If we're not using GL ES 2 then just use the GL functions directly */ -#define cogl_wrap_glClearColorx glClearColorx #define cogl_wrap_glDrawArrays glDrawArrays +#define cogl_wrap_glDrawElements glDrawElements #define cogl_wrap_glPushMatrix glPushMatrix #define cogl_wrap_glPopMatrix glPopMatrix #define cogl_wrap_glMatrixMode glMatrixMode #define cogl_wrap_glLoadIdentity glLoadIdentity -#define cogl_wrap_glMultMatrixx glMultMatrixx -#define cogl_wrap_glFrustumx glFrustumx -#define cogl_wrap_glScalex glScalex -#define cogl_wrap_glTranslatex glTranslatex -#define cogl_wrap_glRotatex glRotatex -#define cogl_wrap_glOrthox glOrthox +#define cogl_wrap_glMultMatrixf glMultMatrixf +#define cogl_wrap_glFrustumf glFrustumf +#define cogl_wrap_glScalef glScalef +#define cogl_wrap_glTranslatef glTranslatef +#define cogl_wrap_glRotatef glRotatef +#define cogl_wrap_glOrthof glOrthof #define cogl_wrap_glEnable glEnable #define cogl_wrap_glDisable glDisable #define cogl_wrap_glTexCoordPointer glTexCoordPointer #define cogl_wrap_glVertexPointer glVertexPointer #define cogl_wrap_glColorPointer glColorPointer #define cogl_wrap_glNormalPointer glNormalPointer -#define cogl_wrap_glTexEnvx glTexEnvx +#define cogl_wrap_glTexEnvf glTexEnvf #define cogl_wrap_glActiveTexture glActiveTexture #define cogl_wrap_glEnableClientState glEnableClientState #define cogl_wrap_glDisableClientState glDisableClientState #define cogl_wrap_glAlphaFunc glAlphaFunc -#define cogl_wrap_glColor4x glColor4x -#define cogl_wrap_glClipPlanex glClipPlanex +#define cogl_wrap_glColor4f glColor4f +#define cogl_wrap_glClipPlanef glClipPlanef #define cogl_wrap_glGetIntegerv glGetIntegerv -#define cogl_wrap_glGetFixedv glGetFixedv -#define cogl_wrap_glFogx glFogx -#define cogl_wrap_glFogxv glFogxv +#define cogl_wrap_glGetFloatv glGetFloatv +#define cogl_wrap_glFogf glFogf +#define cogl_wrap_glFogfv glFogfv #define cogl_wrap_glTexParameteri glTexParameteri /* The extra third parameter of the bind texture wrapper isn't needed diff --git a/clutter/cogl/gles/cogl-primitives.c b/clutter/cogl/gles/cogl-primitives.c index f6248ea9e..1a588056d 100644 --- a/clutter/cogl/gles/cogl-primitives.c +++ b/clutter/cogl/gles/cogl-primitives.c @@ -34,63 +34,35 @@ #include #include +#include #define _COGL_MAX_BEZ_RECURSE_DEPTH 16 void -_cogl_rectangle (gint x, - gint y, - guint width, - guint height) +_cogl_rectangle (float x, + float y, + float width, + float height) { - /* 32-bit integers are not supported as coord types - in GLES . Fixed type has got 16 bits left of the - point which is equal to short anyway. */ - - GLshort rect_verts[8] = { - (GLshort) x, (GLshort) y, - (GLshort) (x + width), (GLshort) y, - (GLshort) x, (GLshort) (y + height), - (GLshort) (x + width), (GLshort) (y + height) + GLfloat rect_verts[8] = { + (GLfloat) x, (GLfloat) y, + (GLfloat) (x + width), (GLfloat) y, + (GLfloat) x, (GLfloat) (y + height), + (GLfloat) (x + width), (GLfloat) (y + height) }; _COGL_GET_CONTEXT (ctx, NO_RETVAL); cogl_enable (COGL_ENABLE_VERTEX_ARRAY | (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0)); - GE ( cogl_wrap_glVertexPointer (2, GL_SHORT, 0, rect_verts ) ); + GE ( cogl_wrap_glVertexPointer (2, GL_FLOAT, 0, rect_verts ) ); GE ( cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) ); } - -void -_cogl_rectanglex (CoglFixed x, - CoglFixed y, - CoglFixed width, - CoglFixed height) -{ - GLfixed rect_verts[8] = { - x, y, - x + width, y, - x, y + height, - x + width, y + height - }; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_enable (COGL_ENABLE_VERTEX_ARRAY - | (ctx->color_alpha < 255 - ? COGL_ENABLE_BLEND : 0)); - - GE( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, rect_verts) ); - GE( cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) ); - -} - void _cogl_path_add_node (gboolean new_sub_path, - CoglFixed x, - CoglFixed y) + float x, + float y) { CoglPathNode new_node; @@ -147,19 +119,17 @@ _cogl_path_stroke_nodes () } static void -_cogl_path_get_bounds (CoglFixedVec2 nodes_min, - CoglFixedVec2 nodes_max, - gint *bounds_x, - gint *bounds_y, - guint *bounds_w, - guint *bounds_h) +_cogl_path_get_bounds (floatVec2 nodes_min, + floatVec2 nodes_max, + float *bounds_x, + float *bounds_y, + float *bounds_w, + float *bounds_h) { - *bounds_x = COGL_FIXED_FLOOR (nodes_min.x); - *bounds_y = COGL_FIXED_FLOOR (nodes_min.y); - *bounds_w = COGL_FIXED_CEIL (nodes_max.x - - COGL_FIXED_FROM_INT (*bounds_x)); - *bounds_h = COGL_FIXED_CEIL (nodes_max.y - - COGL_FIXED_FROM_INT (*bounds_y)); + *bounds_x = nodes_min.x; + *bounds_y = nodes_min.y; + *bounds_w = nodes_max.x - *bounds_x; + *bounds_h = nodes_max.y - *bounds_y; } static gint compare_ints (gconstpointer a, @@ -169,18 +139,18 @@ static gint compare_ints (gconstpointer a, } void -_cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, - CoglFixedVec2 nodes_max, +_cogl_add_path_to_stencil_buffer (floatVec2 nodes_min, + floatVec2 nodes_max, guint path_size, CoglPathNode *path, gboolean merge) { guint path_start = 0; guint sub_path_num = 0; - gint bounds_x; - gint bounds_y; - guint bounds_w; - guint bounds_h; + float bounds_x; + float bounds_y; + float bounds_w; + float bounds_h; _cogl_path_get_bounds (nodes_min, nodes_max, &bounds_x, &bounds_y, &bounds_w, &bounds_h); @@ -244,12 +214,8 @@ _cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, GE( cogl_wrap_glMatrixMode (GL_PROJECTION) ); GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glLoadIdentity () ); - cogl_rectanglex (-COGL_FIXED_1, -COGL_FIXED_1, - COGL_FIXED_FROM_INT (2), - COGL_FIXED_FROM_INT (2)); - cogl_rectanglex (-COGL_FIXED_1, -COGL_FIXED_1, - COGL_FIXED_FROM_INT (2), - COGL_FIXED_FROM_INT (2)); + cogl_rectangle (-1.0, -1.0, 2, 2); + cogl_rectangle (-1.0, -1.0, 2, 2); GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glPopMatrix () ); @@ -292,14 +258,14 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path, for (i=0; i < bounds_h; i++) scanlines[i]=NULL; - first_x = prev_x = COGL_FIXED_TO_INT (path->x); - first_y = prev_y = COGL_FIXED_TO_INT (path->y); + first_x = prev_x = (path->x); + first_y = prev_y = (path->y); /* create scanline intersection list */ for (i=1; i < path_size; i++) { - gint dest_x = COGL_FIXED_TO_INT (path[i].x); - gint dest_y = COGL_FIXED_TO_INT (path[i].y); + gint dest_x = (path[i].x); + gint dest_y = (path[i].y); gint ydir; gint dx; gint dy; @@ -362,7 +328,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path, { gint spans = 0; gint span_no; - GLfixed *coords; + GLfloat *coords; /* count number of spans */ for (i=0; i < bounds_h; i++) @@ -380,7 +346,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path, iter = next->next; } } - coords = g_malloc0 (spans * sizeof (GLfixed) * 3 * 2 * 2); + coords = g_malloc0 (spans * sizeof (GLfloat) * 3 * 2 * 2); span_no = 0; /* build list of triangles */ @@ -390,15 +356,15 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path, while (iter) { GSList *next = iter->next; - GLfixed x0, x1; - GLfixed y0, y1; + GLfloat x0, x1; + GLfloat y0, y1; if (!next) break; - x0 = COGL_FIXED_FROM_INT (GPOINTER_TO_INT (iter->data)); - x1 = COGL_FIXED_FROM_INT (GPOINTER_TO_INT (next->data)); - y0 = COGL_FIXED_FROM_INT (bounds_y + i); - y1 = COGL_FIXED_FROM_INT (bounds_y + i + 1) + 2048; + x0 = (float)(GPOINTER_TO_INT (iter->data)); + x1 = (float)(GPOINTER_TO_INT (next->data)); + y0 = (float)(bounds_y + i); + y1 = (float)(bounds_y + i + 1) + 2048; /* render scanlines 1.0625 high to avoid gaps when transformed */ @@ -435,10 +401,10 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path, void _cogl_path_fill_nodes () { - gint bounds_x; - gint bounds_y; - guint bounds_w; - guint bounds_h; + float bounds_x; + float bounds_y; + float bounds_w; + float bounds_h; _COGL_GET_CONTEXT (ctx, NO_RETVAL); diff --git a/clutter/cogl/gles/cogl-texture.c b/clutter/cogl/gles/cogl-texture.c index 5d4933e85..90152a762 100644 --- a/clutter/cogl/gles/cogl-texture.c +++ b/clutter/cogl/gles/cogl-texture.c @@ -40,12 +40,14 @@ #include #include +#include #if HAVE_COGL_GLES2 #define glVertexPointer cogl_wrap_glVertexPointer #define glTexCoordPointer cogl_wrap_glTexCoordPointer #define glColorPointer cogl_wrap_glColorPointer #define glDrawArrays cogl_wrap_glDrawArrays +#define glDrawElements cogl_wrap_glDrawElements #define glTexParameteri cogl_wrap_glTexParameteri #define glClientActiveTexture cogl_wrap_glClientActiveTexture #define glActiveTexture cogl_wrap_glActiveTexture @@ -71,15 +73,15 @@ struct _CoglSpanIter gint index; GArray *array; CoglTexSliceSpan *span; - CoglFixed pos; - CoglFixed next_pos; - CoglFixed origin; - CoglFixed cover_start; - CoglFixed cover_end; - CoglFixed intersect_start; - CoglFixed intersect_end; - CoglFixed intersect_start_local; - CoglFixed intersect_end_local; + float pos; + float next_pos; + float origin; + float cover_start; + float cover_end; + float intersect_start; + float intersect_end; + float intersect_start_local; + float intersect_end_local; gboolean intersects; }; @@ -118,7 +120,7 @@ _cogl_span_iter_update (CoglSpanIter *iter) /* Offset next position by span size */ iter->next_pos = iter->pos + - COGL_FIXED_FROM_INT (iter->span->size - iter->span->waste); + (float)(iter->span->size - iter->span->waste); /* Check if span intersects the area to cover */ if (iter->next_pos <= iter->cover_start || @@ -147,9 +149,9 @@ _cogl_span_iter_update (CoglSpanIter *iter) static void _cogl_span_iter_begin (CoglSpanIter *iter, GArray *array, - CoglFixed origin, - CoglFixed cover_start, - CoglFixed cover_end) + float origin, + float cover_start, + float cover_end) { /* Copy info */ iter->index = 0; @@ -400,10 +402,10 @@ _cogl_texture_draw_and_read (CoglTexture *tex, GLint *viewport) { gint bpp; - CoglFixed rx1, ry1; - CoglFixed rx2, ry2; - CoglFixed tx1, ty1; - CoglFixed tx2, ty2; + float rx1, ry1; + float rx2, ry2; + float tx1, ty1; + float tx2, ty2; int bw, bh; CoglBitmap rect_bmp; CoglHandle handle; @@ -424,9 +426,9 @@ _cogl_texture_draw_and_read (CoglTexture *tex, /* Draw the texture image */ cogl_texture_rectangle (handle, 0, 0, - COGL_FIXED_FROM_INT (tex->bitmap.width), - COGL_FIXED_FROM_INT (tex->bitmap.height), - 0, 0, COGL_FIXED_1, COGL_FIXED_1); + (float)(tex->bitmap.width), + (float)(tex->bitmap.height), + 0, 0, 1.0, 1.0); /* Read into target bitmap */ prep_for_gl_pixels_download (tex->bitmap.rowstride); @@ -441,7 +443,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex, ry1 = 0; ry2 = 0; ty1 = 0; ty2 = 0; -#define CFIX COGL_FIXED_FROM_INT +#define CFIX (float) /* Walk Y axis until whole bitmap height consumed */ for (bh = tex->bitmap.height; bh > 0; bh -= viewport[3]) @@ -452,7 +454,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex, /* Normalized texture Y coords */ ty1 = ty2; - ty2 = COGL_FIXED_DIV (CFIX (ry2), CFIX (tex->bitmap.height)); + ty2 = (CFIX (ry2) / CFIX (tex->bitmap.height)); rx1 = 0; rx2 = 0; tx1 = 0; tx2 = 0; @@ -466,7 +468,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex, /* Normalized texture X coords */ tx1 = tx2; - tx2 = COGL_FIXED_DIV (CFIX (rx2), CFIX (tex->bitmap.width)); + tx2 = (CFIX (rx2) / CFIX (tex->bitmap.width)); /* Clear buffer with transparent black, draw with white for direct copy to framebuffer */ @@ -546,10 +548,10 @@ _cogl_texture_download_from_gl (CoglTexture *tex, GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glLoadIdentity () ); - GE( cogl_wrap_glOrthox (0, COGL_FIXED_FROM_INT (viewport[2]), - 0, COGL_FIXED_FROM_INT (viewport[3]), - COGL_FIXED_FROM_INT (0), - COGL_FIXED_FROM_INT (100)) ); + GE( cogl_wrap_glOrthof (0, (float)(viewport[2]), + 0, (float)(viewport[3]), + (float)(0), + (float)(100)) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glPushMatrix () ); @@ -664,8 +666,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, /* Iterate vertical spans */ for (source_y = src_y, _cogl_span_iter_begin (&y_iter, tex->slice_y_spans, - 0, COGL_FIXED_FROM_INT (dst_y), - COGL_FIXED_FROM_INT (dst_y + height)); + 0, (float)(dst_y), + (float)(dst_y + height)); !_cogl_span_iter_end (&y_iter); @@ -685,8 +687,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, /* Iterate horizontal spans */ for (source_x = src_x, _cogl_span_iter_begin (&x_iter, tex->slice_x_spans, - 0, COGL_FIXED_FROM_INT (dst_x), - COGL_FIXED_FROM_INT (dst_x + width)); + 0, (float)(dst_x), + (float)(dst_x + width)); !_cogl_span_iter_end (&x_iter); @@ -704,15 +706,15 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, x_iter.index); /* Pick intersection width and height */ - inter_w = COGL_FIXED_TO_INT (x_iter.intersect_end - + inter_w = (x_iter.intersect_end - x_iter.intersect_start); - inter_h = COGL_FIXED_TO_INT (y_iter.intersect_end - + inter_h = (y_iter.intersect_end - y_iter.intersect_start); /* Localize intersection top-left corner to slice*/ - local_x = COGL_FIXED_TO_INT (x_iter.intersect_start - + local_x = (x_iter.intersect_start - x_iter.pos); - local_y = COGL_FIXED_TO_INT (y_iter.intersect_start - + local_y = (y_iter.intersect_start - y_iter.pos); /* Pick slice GL handle */ @@ -770,7 +772,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, guint wx, wy; src = source_bmp->data - + (src_y + COGL_FIXED_TO_INT (y_iter.intersect_start) + + (src_y + ((int)y_iter.intersect_start) - dst_y) * source_bmp->rowstride + (src_x + x_span->start + x_span->size - x_span->waste @@ -815,7 +817,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex, guint copy_width; src = source_bmp->data - + (src_x + COGL_FIXED_TO_INT (x_iter.intersect_start) + + (src_x + ((int)x_iter.intersect_start) - dst_x) * bpp + (src_y + y_span->start + y_span->size - y_span->waste @@ -1314,11 +1316,11 @@ _cogl_texture_free (CoglTexture *tex) } CoglHandle -cogl_texture_new_with_size (guint width, - guint height, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format) +cogl_texture_new_with_size (guint width, + guint height, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format) { CoglTexture *tex; gint bpp; @@ -1339,7 +1341,7 @@ cogl_texture_new_with_size (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; - tex->auto_mipmap = auto_mipmap; + tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->bitmap.width = width; tex->bitmap.height = height; @@ -1374,14 +1376,14 @@ cogl_texture_new_with_size (guint width, } CoglHandle -cogl_texture_new_from_data (guint width, - guint height, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat format, - CoglPixelFormat internal_format, - guint rowstride, - const guchar *data) +cogl_texture_new_from_data (guint width, + guint height, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat format, + CoglPixelFormat internal_format, + guint rowstride, + const guchar *data) { CoglTexture *tex; gint bpp; @@ -1403,7 +1405,7 @@ cogl_texture_new_from_data (guint width, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; - tex->auto_mipmap = auto_mipmap; + tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); tex->bitmap.width = width; tex->bitmap.height = height; @@ -1449,30 +1451,13 @@ cogl_texture_new_from_data (guint width, } CoglHandle -cogl_texture_new_from_file (const gchar *filename, - gint max_waste, - gboolean auto_mipmap, - CoglPixelFormat internal_format, - GError **error) +cogl_texture_new_from_bitmap (CoglBitmap *bmp, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format) { - CoglBitmap bmp; CoglTexture *tex; - - g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); - /* Try loading with imaging backend */ - if (!_cogl_bitmap_from_file (&bmp, filename, error)) - { - /* Try fallback */ - if (!_cogl_bitmap_fallback_from_file (&bmp, filename)) - return COGL_INVALID_HANDLE; - else if (error && *error) - { - g_error_free (*error); - *error = NULL; - } - } - /* Create new texture and fill with loaded data */ tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); @@ -1480,10 +1465,11 @@ cogl_texture_new_from_file (const gchar *filename, COGL_HANDLE_DEBUG_NEW (texture, tex); tex->is_foreign = FALSE; - tex->auto_mipmap = auto_mipmap; + tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0); - tex->bitmap = bmp; + tex->bitmap = *bmp; tex->bitmap_owner = TRUE; + bmp->data = NULL; tex->slice_x_spans = NULL; tex->slice_y_spans = NULL; @@ -1524,6 +1510,30 @@ cogl_texture_new_from_file (const gchar *filename, return _cogl_texture_handle_new (tex); } +CoglHandle +cogl_texture_new_from_file (const gchar *filename, + gint max_waste, + CoglTextureFlags flags, + CoglPixelFormat internal_format, + GError **error) +{ + CoglBitmap *bmp; + CoglHandle handle; + + g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); + + if (!(bmp = cogl_bitmap_new_from_file (filename, error))) + return COGL_INVALID_HANDLE; + + handle = cogl_texture_new_from_bitmap (bmp, + max_waste, + flags, + internal_format); + cogl_bitmap_free (bmp); + + return handle; +} + CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, GLenum gl_target, @@ -2097,7 +2107,9 @@ _cogl_texture_flush_vertices (void) GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) ); - GE( glBindTexture (ctx->texture_target, ctx->texture_current) ); + GE( cogl_gles2_wrapper_bind_texture (ctx->texture_target, + ctx->texture_current, + ctx->texture_format) ); GE( glDrawElements (GL_TRIANGLES, needed_indices, GL_UNSIGNED_SHORT, @@ -2140,24 +2152,24 @@ _cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1, static void _cogl_texture_quad_sw (CoglTexture *tex, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2) + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { CoglSpanIter iter_x , iter_y; - CoglFixed tw , th; - CoglFixed tqx , tqy; - CoglFixed first_tx , first_ty; - CoglFixed first_qx , first_qy; - CoglFixed slice_tx1 , slice_ty1; - CoglFixed slice_tx2 , slice_ty2; - CoglFixed slice_qx1 , slice_qy1; - CoglFixed slice_qx2 , slice_qy2; + float tw , th; + float tqx , tqy; + float first_tx , first_ty; + float first_qx , first_qy; + float slice_tx1 , slice_ty1; + float slice_tx2 , slice_ty2; + float slice_qx1 , slice_qy1; + float slice_qx2 , slice_qy2; GLuint gl_handle; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -2172,7 +2184,7 @@ _cogl_texture_quad_sw (CoglTexture *tex, slices */ if (tx2 < tx1) { - CoglFixed temp = x1; + float temp = x1; x1 = x2; x2 = temp; temp = tx1; @@ -2181,7 +2193,7 @@ _cogl_texture_quad_sw (CoglTexture *tex, } if (ty2 < ty1) { - CoglFixed temp = y1; + float temp = y1; y1 = y2; y2 = temp; temp = ty1; @@ -2190,27 +2202,27 @@ _cogl_texture_quad_sw (CoglTexture *tex, } /* Scale ratio from texture to quad widths */ - tw = COGL_FIXED_FROM_INT (tex->bitmap.width); - th = COGL_FIXED_FROM_INT (tex->bitmap.height); + tw = (float)(tex->bitmap.width); + th = (float)(tex->bitmap.height); - tqx = COGL_FIXED_DIV (x2 - x1, COGL_FIXED_MUL (tw, (tx2 - tx1))); - tqy = COGL_FIXED_DIV (y2 - y1, COGL_FIXED_MUL (th, (ty2 - ty1))); + tqx = (x2 - x1) / (tw * (tx2 - tx1)); + tqy = (y2 - y1) / (th * (ty2 - ty1)); /* Integral texture coordinate for first tile */ - first_tx = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (tx1)); - first_ty = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (ty1)); + first_tx = (float)(floorf (tx1)); + first_ty = (float)(floorf (ty1)); /* Denormalize texture coordinates */ - first_tx = COGL_FIXED_MUL (first_tx, tw); - first_ty = COGL_FIXED_MUL (first_ty, th); - tx1 = COGL_FIXED_MUL (tx1, tw); - ty1 = COGL_FIXED_MUL (ty1, th); - tx2 = COGL_FIXED_MUL (tx2, tw); - ty2 = COGL_FIXED_MUL (ty2, th); + first_tx = (first_tx * tw); + first_ty = (first_ty * th); + tx1 = (tx1 * tw); + ty1 = (ty1 * th); + tx2 = (tx2 * tw); + ty2 = (ty2 * th); /* Quad coordinate of the first tile */ - first_qx = x1 - COGL_FIXED_MUL (tx1 - first_tx, tqx); - first_qy = y1 - COGL_FIXED_MUL (ty1 - first_ty, tqy); + first_qx = x1 - (tx1 - first_tx) * tqx; + first_qy = y1 - (ty1 - first_ty) * tqy; /* Iterate until whole quad height covered */ @@ -2223,11 +2235,9 @@ _cogl_texture_quad_sw (CoglTexture *tex, if (!iter_y.intersects) continue; /* Span-quad intersection in quad coordinates */ - slice_qy1 = first_qy + - COGL_FIXED_MUL (iter_y.intersect_start - first_ty, tqy); + slice_qy1 = first_qy + (iter_y.intersect_start - first_ty) * tqy; - slice_qy2 = first_qy + - COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy); + slice_qy2 = first_qy + (iter_y.intersect_end - first_ty) * tqy; /* Localize slice texture coordinates */ slice_ty1 = iter_y.intersect_start - iter_y.pos; @@ -2248,11 +2258,9 @@ _cogl_texture_quad_sw (CoglTexture *tex, if (!iter_x.intersects) continue; /* Span-quad intersection in quad coordinates */ - slice_qx1 = first_qx + - COGL_FIXED_MUL (iter_x.intersect_start - first_tx, tqx); + slice_qx1 = first_qx + (iter_x.intersect_start - first_tx) * tqx; - slice_qx2 = first_qx + - COGL_FIXED_MUL (iter_x.intersect_end - first_tx, tqx); + slice_qx2 = first_qx + (iter_x.intersect_end - first_tx) * tqx; /* Localize slice texture coordinates */ slice_tx1 = iter_x.intersect_start - iter_x.pos; @@ -2265,14 +2273,14 @@ _cogl_texture_quad_sw (CoglTexture *tex, #if COGL_DEBUG printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); - printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); - printf("qy1: %f\n", COGL_FIXED_TO_FLOAT (slice_qy1)); - printf("qx2: %f\n", COGL_FIXED_TO_FLOAT (slice_qx2)); - printf("qy2: %f\n", COGL_FIXED_TO_FLOAT (slice_qy2)); - printf("tx1: %f\n", COGL_FIXED_TO_FLOAT (slice_tx1)); - printf("ty1: %f\n", COGL_FIXED_TO_FLOAT (slice_ty1)); - printf("tx2: %f\n", COGL_FIXED_TO_FLOAT (slice_tx2)); - printf("ty2: %f\n", COGL_FIXED_TO_FLOAT (slice_ty2)); + printf("qx1: %f\n", (slice_qx1)); + printf("qy1: %f\n", (slice_qy1)); + printf("qx2: %f\n", (slice_qx2)); + printf("qy2: %f\n", (slice_qy2)); + printf("tx1: %f\n", (slice_tx1)); + printf("ty1: %f\n", (slice_ty1)); + printf("tx2: %f\n", (slice_tx2)); + printf("ty2: %f\n", (slice_ty2)); #endif /* Pick and bind opengl texture object */ @@ -2287,29 +2295,30 @@ _cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_flush_vertices (); ctx->texture_target = tex->gl_target; ctx->texture_current = gl_handle; + ctx->texture_format = tex->gl_intformat; - _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1), - COGL_FIXED_TO_FLOAT (slice_qy1), - COGL_FIXED_TO_FLOAT (slice_qx2), - COGL_FIXED_TO_FLOAT (slice_qy2), - COGL_FIXED_TO_FLOAT (slice_tx1), - COGL_FIXED_TO_FLOAT (slice_ty1), - COGL_FIXED_TO_FLOAT (slice_tx2), - COGL_FIXED_TO_FLOAT (slice_ty2)); + _cogl_texture_add_quad_vertices ( (slice_qx1), + (slice_qy1), + (slice_qx2), + (slice_qy2), + (slice_tx1), + (slice_ty1), + (slice_tx2), + (slice_ty2)); } } } static void _cogl_texture_quad_hw (CoglTexture *tex, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2) + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { GLuint gl_handle; CoglTexSliceSpan *x_span; @@ -2331,6 +2340,7 @@ _cogl_texture_quad_hw (CoglTexture *tex, _cogl_texture_flush_vertices (); ctx->texture_target = tex->gl_target; ctx->texture_current = gl_handle; + ctx->texture_format = tex->gl_intformat; /* Don't include the waste in the texture coordinates */ x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); @@ -2342,19 +2352,19 @@ _cogl_texture_quad_hw (CoglTexture *tex, ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size; ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size; - _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1), - COGL_FIXED_TO_FLOAT (y1), - COGL_FIXED_TO_FLOAT (x2), - COGL_FIXED_TO_FLOAT (y2), - COGL_FIXED_TO_FLOAT (tx1), - COGL_FIXED_TO_FLOAT (ty1), - COGL_FIXED_TO_FLOAT (tx2), - COGL_FIXED_TO_FLOAT (ty2)); + _cogl_texture_add_quad_vertices ( (x1), + (y1), + (x2), + (y2), + (tx1), + (ty1), + (tx2), + (ty2)); } void cogl_texture_multiple_rectangles (CoglHandle handle, - const CoglFixed *verts, + const float *verts, guint n_rects) { CoglTexture *tex; @@ -2401,10 +2411,10 @@ cogl_texture_multiple_rectangles (CoglHandle handle, if (tex->slice_gl_handles->len == 1 && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && tex->gl_target == GL_TEXTURE_2D) - || (verts[4] >= 0 && verts[4] <= COGL_FIXED_1 - && verts[6] >= 0 && verts[6] <= COGL_FIXED_1 - && verts[5] >= 0 && verts[5] <= COGL_FIXED_1 - && verts[7] >= 0 && verts[7] <= COGL_FIXED_1))) + || (verts[4] >= 0 && verts[4] <= 1.0 + && verts[6] >= 0 && verts[6] <= 1.0 + && verts[5] >= 0 && verts[5] <= 1.0 + && verts[7] >= 0 && verts[7] <= 1.0))) _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3], verts[4],verts[5], verts[6],verts[7]); else @@ -2420,16 +2430,16 @@ cogl_texture_multiple_rectangles (CoglHandle handle, void cogl_texture_rectangle (CoglHandle handle, - CoglFixed x1, - CoglFixed y1, - CoglFixed x2, - CoglFixed y2, - CoglFixed tx1, - CoglFixed ty1, - CoglFixed tx2, - CoglFixed ty2) + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { - CoglFixed verts[8]; + float verts[8]; verts[0] = x1; verts[1] = y1; @@ -2531,7 +2541,7 @@ cogl_texture_polygon (CoglHandle handle, OpenGL */ for (i = 0; i < n_vertices; i++, p++) { -#define CFX_F COGL_FIXED_TO_FLOAT +#define CFX_F p->v[0] = CFX_F(vertices[i].x); p->v[1] = CFX_F(vertices[i].y); diff --git a/clutter/cogl/gles/cogl.c b/clutter/cogl/gles/cogl.c index bb4a0ea76..717b1e13f 100644 --- a/clutter/cogl/gles/cogl.c +++ b/clutter/cogl/gles/cogl.c @@ -37,6 +37,7 @@ #include "cogl-context.h" #include "cogl-gles2-wrapper.h" +#include /* GL error to string conversion */ #if COGL_DEBUG @@ -92,10 +93,10 @@ cogl_paint_init (const CoglColor *color) fprintf(stderr, "\n ============== Paint Start ================ \n"); #endif - cogl_wrap_glClearColorx (cogl_color_get_red (color), - cogl_color_get_green (color), - cogl_color_get_blue (color), - 0); + glClearColor (cogl_color_get_red (color), + cogl_color_get_green (color), + cogl_color_get_blue (color), + 0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); cogl_wrap_glDisable (GL_LIGHTING); @@ -116,41 +117,21 @@ cogl_pop_matrix (void) } void -cogl_scale (CoglFixed x, CoglFixed y) +cogl_scale (float x, float y) { - GE( cogl_wrap_glScalex (x, y, COGL_FIXED_1) ); + GE( cogl_wrap_glScalef (x, y, 1.0) ); } void -cogl_translatex (CoglFixed x, CoglFixed y, CoglFixed z) +cogl_translate (float x, float y, float z) { - GE( cogl_wrap_glTranslatex (x, y, z) ); + GE( cogl_wrap_glTranslatef (x, y, z) ); } void -cogl_translate (gint x, gint y, gint z) +cogl_rotate (float angle, float x, float y, float z) { - GE( cogl_wrap_glTranslatex (COGL_FIXED_FROM_INT(x), - COGL_FIXED_FROM_INT(y), - COGL_FIXED_FROM_INT(z)) ); -} - -void -cogl_rotatex (CoglFixed angle, - CoglFixed x, - CoglFixed y, - CoglFixed z) -{ - GE( cogl_wrap_glRotatex (angle,x,y,z) ); -} - -void -cogl_rotate (gint angle, gint x, gint y, gint z) -{ - GE( cogl_wrap_glRotatex (COGL_FIXED_FROM_INT(angle), - COGL_FIXED_FROM_INT(x), - COGL_FIXED_FROM_INT(y), - COGL_FIXED_FROM_INT(z)) ); + GE( cogl_wrap_glRotatef (angle, x, y, z) ); } static inline gboolean @@ -315,7 +296,7 @@ cogl_set_source_color (const CoglColor *color) #else /* conversion can cause issues with picking on some gles implementations */ - GE( cogl_wrap_glColor4x (cogl_color_get_red (color), + GE( cogl_wrap_glColor4f (cogl_color_get_red (color), cogl_color_get_green (color), cogl_color_get_blue (color), cogl_color_get_alpha (color)) ); @@ -326,22 +307,22 @@ cogl_set_source_color (const CoglColor *color) } static void -apply_matrix (const CoglFixed *matrix, CoglFixed *vertex) +apply_matrix (const float *matrix, float *vertex) { int x, y; - CoglFixed vertex_out[4] = { 0 }; + float vertex_out[4] = { 0 }; for (y = 0; y < 4; y++) for (x = 0; x < 4; x++) - vertex_out[y] += cogl_fixed_mul (vertex[x], matrix[y + x * 4]); + vertex_out[y] += (vertex[x] * matrix[y + x * 4]); memcpy (vertex, vertex_out, sizeof (vertex_out)); } static void -project_vertex (CoglFixed *modelview, - CoglFixed *project, - CoglFixed *vertex) +project_vertex (float *modelview, + float *project, + float *vertex) { int i; @@ -351,62 +332,61 @@ project_vertex (CoglFixed *modelview, apply_matrix (project, vertex); /* Convert from homogenized coordinates */ for (i = 0; i < 4; i++) - vertex[i] = cogl_fixed_div (vertex[i], vertex[3]); + vertex[i] = (vertex[i] / vertex[3]); } static void set_clip_plane (GLint plane_num, - const CoglFixed *vertex_a, - const CoglFixed *vertex_b) + const float *vertex_a, + const float *vertex_b) { - GLfixed plane[4]; - GLfixed angle; + GLfloat plane[4]; + GLfloat angle; _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* Calculate the angle between the axes and the line crossing the two points */ - angle = cogl_fixed_mul (cogl_fixed_atan2 (vertex_b[1] - vertex_a[1], - vertex_b[0] - vertex_a[0]), - COGL_RADIANS_TO_DEGREES); + angle = atan2f (vertex_b[1] - vertex_a[1], + vertex_b[0] - vertex_a[0]) * (180.0/G_PI); GE( cogl_wrap_glPushMatrix () ); /* Load the identity matrix and multiply by the reverse of the projection matrix so we can specify the plane in screen coordinates */ GE( cogl_wrap_glLoadIdentity () ); - GE( cogl_wrap_glMultMatrixx ((GLfixed *) ctx->inverse_projection) ); + GE( cogl_wrap_glMultMatrixf ((GLfloat *) ctx->inverse_projection) ); /* Rotate about point a */ - GE( cogl_wrap_glTranslatex (vertex_a[0], vertex_a[1], vertex_a[2]) ); + GE( cogl_wrap_glTranslatef (vertex_a[0], vertex_a[1], vertex_a[2]) ); /* Rotate the plane by the calculated angle so that it will connect the two points */ - GE( cogl_wrap_glRotatex (angle, 0.0f, 0.0f, 1.0f) ); - GE( cogl_wrap_glTranslatex (-vertex_a[0], -vertex_a[1], -vertex_a[2]) ); + GE( cogl_wrap_glRotatef (angle, 0.0f, 0.0f, 1.0f) ); + GE( cogl_wrap_glTranslatef (-vertex_a[0], -vertex_a[1], -vertex_a[2]) ); plane[0] = 0; - plane[1] = -COGL_FIXED_1; + plane[1] = -1.0; plane[2] = 0; plane[3] = vertex_a[1]; - GE( cogl_wrap_glClipPlanex (plane_num, plane) ); + GE( cogl_wrap_glClipPlanef (plane_num, plane) ); GE( cogl_wrap_glPopMatrix () ); } void -_cogl_set_clip_planes (CoglFixed x_offset, - CoglFixed y_offset, - CoglFixed width, - CoglFixed height) +_cogl_set_clip_planes (float x_offset, + float y_offset, + float width, + float height) { - GLfixed modelview[16], projection[16]; + GLfloat modelview[16], projection[16]; - CoglFixed vertex_tl[4] = { x_offset, y_offset, 0, COGL_FIXED_1 }; - CoglFixed vertex_tr[4] = { x_offset + width, y_offset, 0, COGL_FIXED_1 }; - CoglFixed vertex_bl[4] = { x_offset, y_offset + height, 0, COGL_FIXED_1 }; - CoglFixed vertex_br[4] = { x_offset + width, y_offset + height, - 0, COGL_FIXED_1 }; + float vertex_tl[4] = { x_offset, y_offset, 0, 1.0 }; + float vertex_tr[4] = { x_offset + width, y_offset, 0, 1.0 }; + float vertex_bl[4] = { x_offset, y_offset + height, 0, 1.0 }; + float vertex_br[4] = { x_offset + width, y_offset + height, + 0, 1.0 }; - GE( cogl_wrap_glGetFixedv (GL_MODELVIEW_MATRIX, modelview) ); - GE( cogl_wrap_glGetFixedv (GL_PROJECTION_MATRIX, projection) ); + GE( cogl_wrap_glGetFloatv (GL_MODELVIEW_MATRIX, modelview) ); + GE( cogl_wrap_glGetFloatv (GL_PROJECTION_MATRIX, projection) ); project_vertex (modelview, projection, vertex_tl); project_vertex (modelview, projection, vertex_tr); @@ -421,7 +401,7 @@ _cogl_set_clip_planes (CoglFixed x_offset, if ((vertex_tl[0] < vertex_tr[0] ? 1 : 0) != (vertex_bl[1] < vertex_tl[1] ? 1 : 0)) { - CoglFixed temp[4]; + float temp[4]; memcpy (temp, vertex_tl, sizeof (temp)); memcpy (vertex_tl, vertex_tr, sizeof (temp)); memcpy (vertex_tr, temp, sizeof (temp)); @@ -437,10 +417,10 @@ _cogl_set_clip_planes (CoglFixed x_offset, } void -_cogl_add_stencil_clip (CoglFixed x_offset, - CoglFixed y_offset, - CoglFixed width, - CoglFixed height, +_cogl_add_stencil_clip (float x_offset, + float y_offset, + float width, + float height, gboolean first) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -457,7 +437,7 @@ _cogl_add_stencil_clip (CoglFixed x_offset, GE( glStencilFunc (GL_NEVER, 0x1, 0x1) ); GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) ); - cogl_rectanglex (x_offset, y_offset, width, height); + cogl_rectangle (x_offset, y_offset, width, height); } else { @@ -465,7 +445,7 @@ _cogl_add_stencil_clip (CoglFixed x_offset, rectangle */ GE( glStencilFunc (GL_NEVER, 0x1, 0x3) ); GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); - cogl_rectanglex (x_offset, y_offset, width, height); + cogl_rectangle (x_offset, y_offset, width, height); /* Subtract one from all pixels in the stencil buffer so that only pixels where both the original stencil buffer and the @@ -476,9 +456,7 @@ _cogl_add_stencil_clip (CoglFixed x_offset, GE( cogl_wrap_glMatrixMode (GL_PROJECTION) ); GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glLoadIdentity () ); - cogl_rectanglex (-COGL_FIXED_1, -COGL_FIXED_1, - COGL_FIXED_FROM_INT (2), - COGL_FIXED_FROM_INT (2)); + cogl_rectangle (-1.0, -1.0, 2, 2); GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glPopMatrix () ); @@ -490,10 +468,10 @@ _cogl_add_stencil_clip (CoglFixed x_offset, } void -_cogl_set_matrix (const CoglFixed *matrix) +_cogl_set_matrix (const float *matrix) { GE( cogl_wrap_glLoadIdentity () ); - GE( cogl_wrap_glMultMatrixx (matrix) ); + GE( cogl_wrap_glMultMatrixf (matrix) ); } void @@ -522,25 +500,25 @@ _cogl_disable_clip_planes (void) void cogl_alpha_func (COGLenum func, - CoglFixed ref) + float ref) { - GE( cogl_wrap_glAlphaFunc (func, COGL_FIXED_TO_FLOAT(ref)) ); + GE( cogl_wrap_glAlphaFunc (func, (ref)) ); } /* * Fixed point implementation of the perspective function */ void -cogl_perspective (CoglFixed fovy, - CoglFixed aspect, - CoglFixed zNear, - CoglFixed zFar) +cogl_perspective (float fovy, + float aspect, + float zNear, + float zFar) { - CoglFixed xmax, ymax; - CoglFixed x, y, c, d; - CoglFixed fovy_rad_half = cogl_fixed_mul (fovy, COGL_FIXED_PI) / 360; + float xmax, ymax; + float x, y, c, d; + float fovy_rad_half = (fovy * G_PI) / 360; - GLfixed m[16]; + GLfloat m[16]; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -558,76 +536,74 @@ cogl_perspective (CoglFixed fovy, * 2) When working with small numbers, we can are loosing significant * precision */ - ymax = cogl_fixed_mul (zNear, - cogl_fixed_div (cogl_fixed_sin (fovy_rad_half), - cogl_fixed_cos (fovy_rad_half))); - xmax = cogl_fixed_mul (ymax, aspect); + ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half))); + xmax = (ymax * aspect); - x = cogl_fixed_div (zNear, xmax); - y = cogl_fixed_div (zNear, ymax); - c = cogl_fixed_div (-(zFar + zNear), ( zFar - zNear)); - d = cogl_fixed_div (-(cogl_fixed_mul (2 * zFar, zNear)), (zFar - zNear)); + x = (zNear / xmax); + y = (zNear / ymax); + c = (-(zFar + zNear) / ( zFar - zNear)); + d = (-(2 * zFar) * zNear) / (zFar - zNear); #define M(row,col) m[col*4+row] M(0,0) = x; M(1,1) = y; M(2,2) = c; M(2,3) = d; - M(3,2) = -COGL_FIXED_1; + M(3,2) = -1.0; - GE( cogl_wrap_glMultMatrixx (m) ); + GE( cogl_wrap_glMultMatrixf (m) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); /* Calculate and store the inverse of the matrix */ - memset (ctx->inverse_projection, 0, sizeof (CoglFixed) * 16); + memset (ctx->inverse_projection, 0, sizeof (float) * 16); #define m ctx->inverse_projection - M(0, 0) = cogl_fixed_div (COGL_FIXED_1, x); - M(1, 1) = cogl_fixed_div (COGL_FIXED_1, y); - M(2, 3) = -COGL_FIXED_1; - M(3, 2) = cogl_fixed_div (COGL_FIXED_1, d); - M(3, 3) = cogl_fixed_div (c, d); + M(0, 0) = (1.0 / x); + M(1, 1) = (1.0 / y); + M(2, 3) = -1.0; + M(3, 2) = (1.0 / d); + M(3, 3) = (c / d); #undef m #undef M } void -cogl_frustum (CoglFixed left, - CoglFixed right, - CoglFixed bottom, - CoglFixed top, - CoglFixed z_near, - CoglFixed z_far) +cogl_frustum (float left, + float right, + float bottom, + float top, + float z_near, + float z_far) { - CoglFixed c, d; + float c, d; _COGL_GET_CONTEXT (ctx, NO_RETVAL); GE( cogl_wrap_glMatrixMode (GL_PROJECTION) ); GE( cogl_wrap_glLoadIdentity () ); - GE( cogl_wrap_glFrustumx (left, right, + GE( cogl_wrap_glFrustumf (left, right, bottom, top, z_near, z_far) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); /* Calculate and store the inverse of the matrix */ - memset (ctx->inverse_projection, 0, sizeof (CoglFixed) * 16); + memset (ctx->inverse_projection, 0, sizeof (float) * 16); - c = -cogl_fixed_div (z_far + z_near, z_far - z_near); - d = -cogl_fixed_div (2 * cogl_fixed_mul (z_far, z_near), z_far - z_near); + c = -(z_far + z_near / z_far - z_near); + d = -(2 * (z_far * z_near) / z_far - z_near); #define M(row,col) ctx->inverse_projection[col*4+row] - M(0,0) = cogl_fixed_div (right - left, 2 * z_near); - M(0,3) = cogl_fixed_div (right + left, 2 * z_near); - M(1,1) = cogl_fixed_div (top - bottom, 2 * z_near); - M(1,3) = cogl_fixed_div (top + bottom, 2 * z_near); - M(2,3) = -COGL_FIXED_1; - M(3,2) = cogl_fixed_div (COGL_FIXED_1, d); - M(3,3) = cogl_fixed_div (c, d); + M(0,0) = (right - left / 2 * z_near); + M(0,3) = (right + left / 2 * z_near); + M(1,1) = (top - bottom / 2 * z_near); + M(1,3) = (top + bottom / 2 * z_near); + M(2,3) = -1.0; + M(3,2) = (1.0 / d); + M(3,3) = (c / d); #undef M } @@ -639,51 +615,44 @@ cogl_viewport (guint width, } void -cogl_setup_viewport (guint w, - guint h, - CoglFixed fovy, - CoglFixed aspect, - CoglFixed z_near, - CoglFixed z_far) +cogl_setup_viewport (guint w, + guint h, + float fovy, + float aspect, + float z_near, + float z_far) { gint width = (gint) w; gint height = (gint) h; - CoglFixed z_camera; + float z_camera; + float projection_matrix[16]; GE( glViewport (0, 0, width, height) ); /* For Ortho projection. - * cogl_wrap_glOrthox (0, width << 16, 0, height << 16, -1 << 16, 1 << 16); + * cogl_wrap_glOrthof (0, width << 16, 0, height << 16, -1 << 16, 1 << 16); */ cogl_perspective (fovy, aspect, z_near, z_far); - GE( cogl_wrap_glLoadIdentity () ); - /* - * camera distance from screen, 0.5 * tan (FOV) + * camera distance from screen * * See comments in ../gl/cogl.c */ -#define DEFAULT_Z_CAMERA 0.869f - z_camera = COGL_FIXED_FROM_FLOAT (DEFAULT_Z_CAMERA); - if (fovy != COGL_FIXED_60) - { - CoglFixed fovy_rad = cogl_fixed_mul (fovy, COGL_FIXED_PI) / 180; - - z_camera = cogl_fixed_div (cogl_fixed_sin (fovy_rad), - cogl_fixed_cos (fovy_rad)) >> 1; - } - + cogl_get_projection_matrix (projection_matrix); + z_camera = 0.5 * projection_matrix[0]; - GE( cogl_wrap_glTranslatex (-1 << 15, -1 << 15, -z_camera) ); + GE( cogl_wrap_glLoadIdentity () ); - GE( cogl_wrap_glScalex ( COGL_FIXED_1 / width, - -COGL_FIXED_1 / height, - COGL_FIXED_1 / width) ); + GE( cogl_wrap_glTranslatef (-0.5f, -0.5f, -z_camera) ); - GE( cogl_wrap_glTranslatex (0, -COGL_FIXED_1 * height, 0) ); + GE( cogl_wrap_glScalef ( 1.0 / width, + -1.0 / height, + 1.0 / width) ); + + GE( cogl_wrap_glTranslatef (0, -1.0 * height, 0) ); } static void @@ -735,19 +704,19 @@ cogl_features_available (CoglFeatureFlags features) } void -cogl_get_modelview_matrix (CoglFixed m[16]) +cogl_get_modelview_matrix (float m[16]) { - cogl_wrap_glGetFixedv(GL_MODELVIEW_MATRIX, &m[0]); + cogl_wrap_glGetFloatv (GL_MODELVIEW_MATRIX, m); } void -cogl_get_projection_matrix (CoglFixed m[16]) +cogl_get_projection_matrix (float m[16]) { - cogl_wrap_glGetFixedv(GL_PROJECTION_MATRIX, &m[0]); + cogl_wrap_glGetFloatv (GL_PROJECTION_MATRIX, m); } void -cogl_get_viewport (CoglFixed v[4]) +cogl_get_viewport (float v[4]) { GLint viewport[4]; int i; @@ -755,7 +724,7 @@ cogl_get_viewport (CoglFixed v[4]) cogl_wrap_glGetIntegerv (GL_VIEWPORT, viewport); for (i = 0; i < 4; i++) - v[i] = COGL_FIXED_FROM_INT (viewport[i]); + v[i] = (float)(viewport[i]); } void @@ -773,11 +742,11 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha) void cogl_fog_set (const CoglColor *fog_color, - CoglFixed density, - CoglFixed z_near, - CoglFixed z_far) + float density, + float z_near, + float z_far) { - GLfixed fogColor[4]; + GLfloat fogColor[4]; fogColor[0] = cogl_color_get_red (fog_color); fogColor[1] = cogl_color_get_green (fog_color); @@ -786,12 +755,12 @@ cogl_fog_set (const CoglColor *fog_color, cogl_wrap_glEnable (GL_FOG); - cogl_wrap_glFogxv (GL_FOG_COLOR, fogColor); + cogl_wrap_glFogfv (GL_FOG_COLOR, fogColor); - cogl_wrap_glFogx (GL_FOG_MODE, GL_LINEAR); + cogl_wrap_glFogf (GL_FOG_MODE, GL_LINEAR); glHint (GL_FOG_HINT, GL_NICEST); - cogl_wrap_glFogx (GL_FOG_DENSITY, (GLfixed) density); - cogl_wrap_glFogx (GL_FOG_START, (GLfixed) z_near); - cogl_wrap_glFogx (GL_FOG_END, (GLfixed) z_far); + cogl_wrap_glFogf (GL_FOG_DENSITY, (GLfloat) density); + cogl_wrap_glFogf (GL_FOG_START, (GLfloat) z_near); + cogl_wrap_glFogf (GL_FOG_END, (GLfloat) z_far); } diff --git a/clutter/eglnative/clutter-stage-egl.c b/clutter/eglnative/clutter-stage-egl.c index f56eaf13b..a767d55b5 100644 --- a/clutter/eglnative/clutter-stage-egl.c +++ b/clutter/eglnative/clutter-stage-egl.c @@ -199,6 +199,12 @@ clutter_stage_egl_realize (ClutterActor *actor) CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); return; } + + /* since we only have one size and it cannot change, we + * just need to update the GL viewport now that we have + * been realized + */ + CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_ACTOR_SYNC_MATRICES); } else { diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index 0dfe23941..ecc6e8dd9 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -320,7 +320,7 @@ create_cogl_texture (ClutterTexture *texture, CoglHandle handle; gboolean using_rectangle; GLint gl_format; - CoglPixelFormat cogl_format; + CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_RGBA_8888; guint depth; g_object_get (G_OBJECT (texture_glx), "pixmap-depth", &depth, NULL); diff --git a/clutter/pango/cogl-pango-glyph-cache.c b/clutter/pango/cogl-pango-glyph-cache.c index 7a2bf2f23..8532e800e 100644 --- a/clutter/pango/cogl-pango-glyph-cache.c +++ b/clutter/pango/cogl-pango-glyph-cache.c @@ -272,6 +272,7 @@ cogl_pango_glyph_cache_set (CoglPangoGlyphCache *cache, texture = texture->next); if (texture == NULL) { + CoglTextureFlags flags = COGL_TEXTURE_NONE; guchar *clear_data; /* Allocate a new texture that is the nearest power of two @@ -280,19 +281,27 @@ cogl_pango_glyph_cache_set (CoglPangoGlyphCache *cache, texture = g_slice_new (CoglPangoGlyphCacheTexture); texture->texture_size = MIN_TEXTURE_SIZE; - while (texture->texture_size < band_height - || texture->texture_size < width) - texture->texture_size *= 2; + while (texture->texture_size < band_height || + texture->texture_size < width) + { + texture->texture_size *= 2; + } /* Allocate an empty buffer to clear the texture */ - clear_data = g_malloc0 (texture->texture_size - * texture->texture_size); + clear_data = + g_malloc0 (texture->texture_size * texture->texture_size); - texture->texture = cogl_texture_new_from_data - (texture->texture_size, texture->texture_size, - 32, cache->use_mipmapping, - COGL_PIXEL_FORMAT_A_8, COGL_PIXEL_FORMAT_A_8, - texture->texture_size, clear_data); + if (cache->use_mipmapping) + flags |= COGL_TEXTURE_AUTO_MIPMAP; + + texture->texture = + cogl_texture_new_from_data (texture->texture_size, + texture->texture_size, + 32, flags, + COGL_PIXEL_FORMAT_A_8, + COGL_PIXEL_FORMAT_A_8, + texture->texture_size, + clear_data); g_free (clear_data); @@ -342,13 +351,13 @@ cogl_pango_glyph_cache_set (CoglPangoGlyphCache *cache, value = g_slice_new (CoglPangoGlyphCacheValue); value->texture = cogl_texture_ref (band->texture); - value->tx1 = COGL_FIXED_FROM_INT (band->space_remaining) + value->tx1 = (float)(band->space_remaining) / band->texture_size; - value->tx2 = COGL_FIXED_FROM_INT (band->space_remaining + width) + value->tx2 = (float)(band->space_remaining + width) / band->texture_size; - value->ty1 = COGL_FIXED_FROM_INT (band->top) + value->ty1 = (float)(band->top) / band->texture_size; - value->ty2 = COGL_FIXED_FROM_INT (band->top + height) + value->ty2 = (float)(band->top + height) / band->texture_size; value->draw_x = draw_x; value->draw_y = draw_y; diff --git a/clutter/pango/cogl-pango-glyph-cache.h b/clutter/pango/cogl-pango-glyph-cache.h index 2f4b5798b..33364e1c7 100644 --- a/clutter/pango/cogl-pango-glyph-cache.h +++ b/clutter/pango/cogl-pango-glyph-cache.h @@ -37,10 +37,10 @@ struct _CoglPangoGlyphCacheValue { CoglHandle texture; - CoglFixed tx1; - CoglFixed ty1; - CoglFixed tx2; - CoglFixed ty2; + float tx1; + float ty1; + float tx2; + float ty2; int draw_x; int draw_y; diff --git a/clutter/pango/cogl-pango-render.c b/clutter/pango/cogl-pango-render.c index e69c412ac..3cafc81e2 100644 --- a/clutter/pango/cogl-pango-render.c +++ b/clutter/pango/cogl-pango-render.c @@ -67,7 +67,7 @@ cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv) { if (priv->glyph_rectangles->len > 0) { - CoglFixed *rectangles = (CoglFixed *) priv->glyph_rectangles->data; + float *rectangles = (float *) priv->glyph_rectangles->data; cogl_texture_multiple_rectangles (priv->glyph_texture, rectangles, priv->glyph_rectangles->len / 8); g_array_set_size (priv->glyph_rectangles, 0); @@ -77,11 +77,11 @@ cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv) static void cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, CoglPangoGlyphCacheValue *cache_value, - CoglFixed x1, - CoglFixed y1) + float x1, + float y1) { - CoglFixed x2, y2; - CoglFixed *p; + float x2, y2; + float *p; if (priv->glyph_rectangles->len > 0 && priv->glyph_texture != cache_value->texture) @@ -93,7 +93,7 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, y2 = y1 + CLUTTER_INT_TO_FIXED (cache_value->draw_height); g_array_set_size (priv->glyph_rectangles, priv->glyph_rectangles->len + 8); - p = &g_array_index (priv->glyph_rectangles, CoglFixed, + p = &g_array_index (priv->glyph_rectangles, float, priv->glyph_rectangles->len - 8); *(p++) = x1; *(p++) = y1; @@ -102,8 +102,6 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, *(p++) = cache_value->tx2; *(p++) = cache_value->ty2; } -#define COGL_PANGO_UNIT_TO_FIXED(x) ((x) << (COGL_FIXED_Q - 10)) - static void cogl_pango_renderer_finalize (GObject *object); static void cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, PangoFont *font, @@ -133,7 +131,7 @@ cogl_pango_renderer_init (CoglPangoRenderer *priv) priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE); priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE); priv->use_mipmapping = FALSE; - priv->glyph_rectangles = g_array_new (FALSE, FALSE, sizeof (CoglFixed)); + priv->glyph_rectangles = g_array_new (FALSE, FALSE, sizeof (float)); } static void @@ -413,10 +411,10 @@ static void cogl_pango_renderer_draw_box (int x, int y, int width, int height) { - cogl_path_rectangle (COGL_FIXED_FROM_INT (x), - COGL_FIXED_FROM_INT (y - height), - COGL_FIXED_FROM_INT (width), - COGL_FIXED_FROM_INT (height)); + cogl_path_rectangle ((float)(x), + (float)(y - height), + (float)(width), + (float)(height)); cogl_path_stroke (); } @@ -424,23 +422,23 @@ static void cogl_pango_renderer_get_device_units (PangoRenderer *renderer, int xin, int yin, - CoglFixed *xout, - CoglFixed *yout) + float *xout, + float *yout) { const PangoMatrix *matrix; if ((matrix = pango_renderer_get_matrix (renderer))) { /* Convert user-space coords to device coords */ - *xout = COGL_FIXED_FROM_FLOAT ((xin * matrix->xx + yin * matrix->xy) + *xout = ((xin * matrix->xx + yin * matrix->xy) / PANGO_SCALE + matrix->x0); - *yout = COGL_FIXED_FROM_FLOAT ((yin * matrix->yy + xin * matrix->yx) + *yout = ((yin * matrix->yy + xin * matrix->yx) / PANGO_SCALE + matrix->y0); } else { - *xout = COGL_PANGO_UNIT_TO_FIXED (xin); - *yout = COGL_PANGO_UNIT_TO_FIXED (yin); + *xout = PANGO_PIXELS (xin); + *yout = PANGO_PIXELS (yin); } } @@ -452,7 +450,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, int width, int height) { - CoglFixed x1, x2, y1, y2; + float x1, x2, y1, y2; cogl_pango_renderer_set_color_for_part (renderer, part); @@ -463,7 +461,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, x + width, y + height, &x2, &y2); - cogl_rectanglex (x1, y1, x2 - x1, y2 - y1); + cogl_rectangle (x1, y1, x2 - x1, y2 - y1); } static void @@ -476,15 +474,15 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, double x12, double x22) { - CoglFixed points[8]; + float points[8]; - points[0] = COGL_FIXED_FROM_FLOAT (x11); - points[1] = COGL_FIXED_FROM_FLOAT (y1); - points[2] = COGL_FIXED_FROM_FLOAT (x12); - points[3] = COGL_FIXED_FROM_FLOAT (y2); - points[4] = COGL_FIXED_FROM_FLOAT (x22); + points[0] = (x11); + points[1] = (y1); + points[2] = (x12); + points[3] = (y2); + points[4] = (x22); points[5] = points[3]; - points[6] = COGL_FIXED_FROM_FLOAT (x21); + points[6] = (x21); points[7] = points[1]; cogl_pango_renderer_set_color_for_part (renderer, part); @@ -510,7 +508,7 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, for (i = 0; i < glyphs->num_glyphs; i++) { PangoGlyphInfo *gi = glyphs->glyphs + i; - CoglFixed x, y; + float x, y; cogl_pango_renderer_get_device_units (renderer, xi + gi->geometry.x_offset, @@ -526,15 +524,15 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, if (font == NULL || (metrics = pango_font_get_metrics (font, NULL)) == NULL) { - cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), - COGL_FIXED_TO_INT (y), + cogl_pango_renderer_draw_box ( (x), + (y), PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_HEIGHT); } else { - cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), - COGL_FIXED_TO_INT (y), + cogl_pango_renderer_draw_box ( (x), + (y), metrics->approximate_char_width / PANGO_SCALE, metrics->ascent / PANGO_SCALE); @@ -555,20 +553,20 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, { cogl_pango_renderer_glyphs_end (priv); - cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), - COGL_FIXED_TO_INT (y), + cogl_pango_renderer_draw_box ( (x), + (y), PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_HEIGHT); } else { - CoglFixed width, height; + float width, height; - x += COGL_FIXED_FROM_INT (cache_value->draw_x); - y += COGL_FIXED_FROM_INT (cache_value->draw_y); + x += (float)(cache_value->draw_x); + y += (float)(cache_value->draw_y); - width = x + COGL_FIXED_FROM_INT (cache_value->draw_width); - height = y + COGL_FIXED_FROM_INT (cache_value->draw_height); + width = x + (float)(cache_value->draw_width); + height = y + (float)(cache_value->draw_height); cogl_pango_renderer_draw_glyph (priv, cache_value, x, y); } diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index b83a0b2f3..0f75daf2c 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -427,12 +427,6 @@ event_translate (ClutterBackend *backend, case ConfigureNotify: if (!stage_x11->is_foreign_xwin) { - /* Set a flag so that the stage will know the actor is being - resized in response to the window size changing as - opposed to a request from the application. This prevents - it from trying to resize the window again */ - stage_x11->handling_configure = TRUE; - CLUTTER_NOTE (BACKEND, "%s: ConfigureNotify[%x] (%d, %d)", G_STRLOC, (unsigned int) stage_x11->xwin, @@ -443,8 +437,6 @@ event_translate (ClutterBackend *backend, xevent->xconfigure.width, xevent->xconfigure.height); - stage_x11->handling_configure = FALSE; - /* the resize process is complete, so we can ask the stage * to set up the GL viewport with the new size */ diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index d01d8e2b1..725a75650 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -270,21 +270,8 @@ clutter_stage_x11_allocate (ClutterActor *self, stage_x11->xwin_width = new_width; stage_x11->xwin_height = new_height; - /* The 'handling_configure' flag below is used to prevent the - window from being resized again in response to a - ConfigureNotify event. Normally this will not be a problem - because the window will be resized to xwin_width and - xwin_height so the above test will prevent it from resizing - the window a second time. However if the stage is resized - multiple times without the events being processed in between - (eg, when calling g_object_set to set both width and height) - then there will be multiple ConfigureNotify events in the - queue. Handling the first event will undo the work of setting - the second property which will cause it to keep generating - events in an infinite loop. See bug #810 */ if (stage_x11->xwin != None && - !stage_x11->is_foreign_xwin && - !stage_x11->handling_configure) + !stage_x11->is_foreign_xwin) { CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)", G_STRLOC, @@ -577,7 +564,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->is_foreign_xwin = FALSE; stage->fullscreen_on_map = FALSE; - stage->handling_configure = FALSE; stage->is_cursor_visible = TRUE; stage->title = NULL; diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index 229f058e1..c1a913950 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -47,7 +47,6 @@ struct _ClutterStageX11 guint is_foreign_xwin : 1; guint fullscreen_on_map : 1; - guint handling_configure : 1; guint is_cursor_visible : 1; Display *xdpy; diff --git a/clutter/x11/clutter-x11-texture-pixmap.c b/clutter/x11/clutter-x11-texture-pixmap.c index 29f9d6798..6b2c6fd95 100644 --- a/clutter/x11/clutter-x11-texture-pixmap.c +++ b/clutter/x11/clutter-x11-texture-pixmap.c @@ -440,7 +440,7 @@ clutter_x11_texture_pixmap_set_property (GObject *object, { case PROP_PIXMAP: clutter_x11_texture_pixmap_set_pixmap (texture, - g_value_get_uint (value)); + g_value_get_ulong (value)); break; case PROP_AUTO: clutter_x11_texture_pixmap_set_automatic (texture, @@ -481,7 +481,7 @@ clutter_x11_texture_pixmap_get_property (GObject *object, switch (prop_id) { case PROP_PIXMAP: - g_value_set_uint (value, priv->pixmap); + g_value_set_ulong (value, priv->pixmap); break; case PROP_PIXMAP_WIDTH: g_value_set_uint (value, priv->pixmap_width); @@ -557,12 +557,12 @@ clutter_x11_texture_pixmap_class_init (ClutterX11TexturePixmapClass *klass) klass->update_area = clutter_x11_texture_pixmap_update_area_real; - pspec = g_param_spec_uint ("pixmap", - "Pixmap", - "The X11 Pixmap to be bound", - 0, G_MAXINT, - None, - G_PARAM_READWRITE); + pspec = g_param_spec_ulong ("pixmap", + "Pixmap", + "The X11 Pixmap to be bound", + 0, G_MAXULONG, + None, + G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_PIXMAP, pspec); @@ -605,12 +605,12 @@ clutter_x11_texture_pixmap_class_init (ClutterX11TexturePixmapClass *klass) g_object_class_install_property (object_class, PROP_AUTO, pspec); - pspec = g_param_spec_uint ("window", - "Window", - "The X11 Window to be bound", - 0, G_MAXINT, - None, - G_PARAM_READWRITE); + pspec = g_param_spec_ulong ("window", + "Window", + "The X11 Window to be bound", + 0, G_MAXULONG, + None, + G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_WINDOW, pspec); diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index c136c4721..9c93f95fe 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -1 +1 @@ -SUBDIRS = clutter cogl +SUBDIRS = cogl clutter diff --git a/doc/reference/clutter/clutter-docs.xml b/doc/reference/clutter/clutter-docs.xml index baeb0b5bf..a9ecc8a0f 100644 --- a/doc/reference/clutter/clutter-docs.xml +++ b/doc/reference/clutter/clutter-docs.xml @@ -105,6 +105,7 @@ + diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 3f0a8429f..748691144 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -2,17 +2,17 @@ clutter-media ClutterMedia ClutterMedia -ClutterMediaInterface +ClutterMediaIface clutter_media_set_uri clutter_media_get_uri clutter_media_set_playing clutter_media_get_playing -clutter_media_set_position -clutter_media_get_position -clutter_media_set_volume -clutter_media_get_volume +clutter_media_set_progress +clutter_media_get_progress +clutter_media_set_audio_volume +clutter_media_get_audio_volume clutter_media_get_can_seek -clutter_media_get_buffer_percent +clutter_media_get_buffer_fill clutter_media_get_duration clutter_media_set_filename @@ -29,26 +29,24 @@ clutter_media_get_type Unit conversion ClutterUnit CLUTTER_UNITS_FORMAT -CLUTTER_UNITS_FROM_DEVICE -CLUTTER_UNITS_TO_DEVICE -CLUTTER_UNITS_FROM_FIXED -CLUTTER_UNITS_TO_FIXED CLUTTER_UNITS_FROM_FLOAT CLUTTER_UNITS_TO_FLOAT CLUTTER_UNITS_FROM_INT CLUTTER_UNITS_TO_INT + + +CLUTTER_UNITS_FROM_DEVICE +CLUTTER_UNITS_TO_DEVICE +CLUTTER_UNITS_FROM_FIXED +CLUTTER_UNITS_TO_FIXED CLUTTER_UNITS_FROM_PANGO_UNIT CLUTTER_UNITS_TO_PANGO_UNIT -CLUTTER_UNITS_TMP_FROM_DEVICE -CLUTTER_UNITS_TMP_TO_DEVICE -CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE -CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE -CLUTTER_UNITS_FROM_PARENT_WIDTH_PERCENTAGE -CLUTTER_UNITS_FROM_PARENT_HEIGHT_PERCENTAGE CLUTTER_UNITS_FROM_MM -CLUTTER_UNITS_FROM_MMX CLUTTER_UNITS_FROM_POINTS -CLUTTER_UNITS_FROM_POINTSX +CLUTTER_UNITS_FROM_EM +clutter_units_mm +clutter_units_pt +clutter_units_em CLUTTER_MAXUNIT @@ -102,7 +100,7 @@ ClutterAlpha ClutterAlphaClass clutter_alpha_new clutter_alpha_new_full -clutter_alpha_new_for_mode +clutter_alpha_new_with_func clutter_alpha_get_alpha CLUTTER_ALPHA_MAX_ALPHA ClutterAlphaFunc @@ -113,6 +111,10 @@ clutter_alpha_get_timeline clutter_alpha_set_mode clutter_alpha_get_mode + +clutter_alpha_register_closure +clutter_alpha_register_func + clutter_ramp_inc_func clutter_ramp_dec_func @@ -169,6 +171,35 @@ ClutterCloneTexturePrivate clutter_clone_texture_get_type +
+clutter-cairo-texture +ClutterCairoTexture +ClutterCairoTexture +ClutterCairoTextureClass +clutter_cairo_texture_new +clutter_cairo_texture_set_surface_size +clutter_cairo_texture_get_surface_size + + +clutter_cairo_texture_create +clutter_cairo_texture_create_region + + +clutter_cairo_set_source_color + + +CLUTTER_TYPE_CAIRO_TEXTURE +CLUTTER_CAIRO_TEXTURE +CLUTTER_IS_CAIRO_TEXTURE +CLUTTER_CAIRO_TEXTURE_CLASS +CLUTTER_IS_CAIRO_TEXTURE_CLASS +CLUTTER_CAIRO_TEXTURE_GET_CLASS + + +ClutterCairoTexturePrivate +clutter_cairo_texture_get_type +
+
clutter-group ClutterGroup @@ -518,6 +549,7 @@ clutter_stage_show_cursor clutter_stage_hide_cursor clutter_stage_get_actor_at_pos clutter_stage_ensure_current +clutter_stage_ensure_viewport clutter_stage_queue_redraw clutter_stage_event clutter_stage_set_key_focus @@ -889,7 +921,6 @@ clutter_feature_get_all clutter-fixed Fixed Point Support ClutterFixed -CFX_Q CFX_ONE CFX_HALF CFX_MAX @@ -923,23 +954,13 @@ CLUTTER_ANGLE_TO_DEG CLUTTER_ANGLE_TO_DEGX CLUTTER_ANGLE_MAX_DEG CFX_RADIANS_TO_DEGREES -clutter_cosi clutter_cosx -clutter_sini clutter_sinx -CLUTTER_SQRTI_ARG_10_PERCENT -CLUTTER_SQRTI_ARG_5_PERCENT -CLUTTER_SQRTI_ARG_MAX -clutter_sqrti -clutter_sqrtx -clutter_log2x -clutter_pow2x -clutter_powx +clutter_tanx +clutter_atanx +clutter_atan2x clutter_qmulx clutter_qdivx -clutter_tani -clutter_atani -clutter_atan2i CLUTTER_MAXFIXED @@ -1187,39 +1208,6 @@ CLUTTER_COGL CLUTTER_NO_FPU
-
-clutter-effect -Clutter Effects -ClutterEffectTemplate -ClutterEffectTemplateClass -clutter_effect_template_new -clutter_effect_template_new_full -clutter_effect_template_new_for_duration -clutter_effect_template_construct -clutter_effect_template_get_timeline_clone -clutter_effect_template_set_timeline_clone - - -ClutterEffectCompleteFunc -clutter_effect_fade -clutter_effect_move -clutter_effect_path -clutter_effect_scale -clutter_effect_depth -clutter_effect_rotate - - -CLUTTER_TYPE_EFFECT_TEMPLATE -CLUTTER_EFFECT_TEMPLATE -CLUTTER_IS_EFFECT_TEMPLATE -CLUTTER_EFFECT_TEMPLATE_CLASS -CLUTTER_IS_EFFECT_TEMPLATE_CLASS -CLUTTER_EFFECT_TEMPLATE_GET_CLASS - -ClutterEffectTemplatePrivate -clutter_effect_template_get_type -
-
clutter-behaviour-depth ClutterBehaviourDepth @@ -1507,8 +1495,8 @@ ClutterAnimation ClutterAnimationClass ClutterAnimationMode clutter_animation_new -clutter_animation_set_actor -clutter_animation_get_actor +clutter_animation_set_object +clutter_animation_get_object clutter_animation_set_mode clutter_animation_get_mode clutter_animation_set_duration @@ -1567,6 +1555,10 @@ clutter_interval_get_interval clutter_interval_compute_value clutter_interval_validate + +ClutterProgressFunc +clutter_interval_register_progress_func + CLUTTER_TYPE_INTERVAL CLUTTER_INTERVAL @@ -1688,6 +1680,23 @@ ClutterTextPrivate clutter_text_get_type
+
+clutter-animatable +ClutterAnimatable +ClutterAnimatable +ClutterAnimatableIface +clutter_animatable_animate_property + + +CLUTTER_TYPE_ANIMATABLE +CLUTTER_ANIMATABLE +CLUTTER_IS_ANIMATABLE +CLUTTER_ANIMATABLE_GET_IFACE + + +clutter_animatable_get_type +
+
Key Bindings clutter-binding-pool @@ -1711,4 +1720,12 @@ clutter_binding_pool_unblock_action clutter_binding_pool_activate + + +CLUTTER_BINDING_POOL +CLUTTER_IS_BINDING_POOL +CLUTTER_TYPE_BINDING_POOL + + +clutter_binding_pool_get_type
diff --git a/doc/reference/clutter/clutter.types b/doc/reference/clutter/clutter.types index f59698f02..c4fc972dc 100644 --- a/doc/reference/clutter/clutter.types +++ b/doc/reference/clutter/clutter.types @@ -28,3 +28,4 @@ clutter_shader_get_type clutter_child_meta_get_type clutter_cairo_texture_get_type clutter_text_get_type +clutter_animatable_get_type diff --git a/doc/reference/cogl/cogl-docs.sgml b/doc/reference/cogl/cogl-docs.sgml index 7e2c0974c..ea48e5a1a 100644 --- a/doc/reference/cogl/cogl-docs.sgml +++ b/doc/reference/cogl/cogl-docs.sgml @@ -62,7 +62,7 @@ - + diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt index b30cf9efe..a00db7c77 100644 --- a/doc/reference/cogl/cogl-sections.txt +++ b/doc/reference/cogl/cogl-sections.txt @@ -23,11 +23,10 @@ cogl_get_viewport cogl_push_matrix cogl_pop_matrix cogl_scale -cogl_translatex cogl_translate -cogl_rotatex cogl_rotate +CoglClipStackState cogl_clip_set cogl_clip_set_from_path cogl_clip_set_from_path_preserve @@ -89,22 +88,28 @@ cogl_path_stroke cogl_path_stroke_preserve cogl_set_source_color cogl_set_source_color4ub -cogl_set_source_color4x +cogl_set_source_color4f +cogl_color cogl_rectangle -cogl_rectanglex
cogl-texture Textures CoglTextureVertex +CoglTextureFlags cogl_texture_new_with_size cogl_texture_new_from_file cogl_texture_new_from_data cogl_texture_new_from_foreign +cogl_texture_new_from_bitmap cogl_is_texture +cogl_texture_ref +cogl_texture_unref + + cogl_texture_get_width cogl_texture_get_height cogl_texture_get_format @@ -117,11 +122,18 @@ cogl_texture_get_gl_texture cogl_texture_get_data cogl_texture_set_filters cogl_texture_set_region -cogl_texture_ref -cogl_texture_unref + + cogl_texture_rectangle cogl_texture_multiple_rectangles cogl_texture_polygon + + +CoglBitmap +cogl_bitmap_new_from_file +cogl_bitmap_free +cogl_bitmap_get_size_from_file +
@@ -145,6 +157,7 @@ cogl_program_link cogl_program_use cogl_program_get_uniform_location cogl_program_uniform_1f +cogl_program_uniform_1i cogl_program_uniform_float cogl_program_uniform_int cogl_program_uniform_matrix @@ -228,6 +241,7 @@ cogl_fixed_pow cogl_fixed_pow2 cogl_fixed_sin cogl_fixed_sqrt +cogl_fixed_tan CoglAngle @@ -257,7 +271,7 @@ cogl_color_copy cogl_color_free cogl_color_set_from_4ub cogl_color_set_from_4d -cogl_color_set_from_4x +cogl_color_set_from_4f cogl_color_get_red @@ -279,19 +293,21 @@ cogl_color_get_alpha_float
-cogl-mesh -Mesh API -cogl_mesh_new -cogl_mesh_ref -cogl_mesh_unref -CoglMeshAttributeFlags -cogl_mesh_add_attribute -cogl_mesh_delete_attribute -cogl_mesh_enable_attribute -cogl_mesh_disable_attribute -cogl_mesh_draw_arrays -cogl_mesh_draw_range_elements -cogl_mesh_submit +cogl-vertex-buffer +Vertex Buffers +CoglVertexBufferAttribFlags +COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK +COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK +cogl_vertex_buffer_new +cogl_vertex_buffer_ref +cogl_vertex_buffer_unref +cogl_vertex_buffer_add +cogl_vertex_buffer_delete +cogl_vertex_buffer_enable +cogl_vertex_buffer_disable +cogl_vertex_buffer_submit +cogl_vertex_buffer_draw +cogl_vertex_buffer_draw_range_elements
diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am index e3c36a873..04f85afdc 100644 --- a/tests/conform/Makefile.am +++ b/tests/conform/Makefile.am @@ -12,9 +12,9 @@ test_conformance_SOURCES = \ test-timeline-rewind.c \ test-timeline-smoothness.c \ test-timeline.c \ - test-mesh-contiguous.c \ - test-mesh-interleved.c \ - test-mesh-mutability.c \ + test-vertex-buffer-contiguous.c \ + test-vertex-buffer-interleved.c \ + test-vertex-buffer-mutability.c \ test-path.c \ test-pick.c \ test-clutter-rectangle.c \ diff --git a/tests/conform/test-backface-culling.c b/tests/conform/test-backface-culling.c index 3b7948e96..f43b7a38b 100644 --- a/tests/conform/test-backface-culling.c +++ b/tests/conform/test-backface-culling.c @@ -114,33 +114,33 @@ on_paint (ClutterActor *actor, TestState *state) the first */ for (i = 0; i < 2; i++) { - CoglFixed x1 = 0, x2, y1 = 0, y2 = COGL_FIXED_FROM_INT (TEXTURE_SIZE); + float x1 = 0, x2, y1 = 0, y2 = (float)(TEXTURE_SIZE); CoglTextureVertex verts[4]; memset (verts, 0, sizeof (verts)); /* Set the color to white so that all the textures will be drawn at their own color */ - cogl_set_source_color4x (COGL_FIXED_1, COGL_FIXED_1, - COGL_FIXED_1, COGL_FIXED_1); + cogl_set_source_color4f (1.0, 1.0, + 1.0, 1.0); - x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); + x2 = x1 + (float)(TEXTURE_SIZE); /* Draw a front-facing texture */ cogl_texture_rectangle (state->texture, x1, y1, x2, y2, - 0, 0, COGL_FIXED_1, COGL_FIXED_1); + 0, 0, 1.0, 1.0); x1 = x2; - x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); + x2 = x1 + (float)(TEXTURE_SIZE); /* Draw a back-facing texture */ cogl_texture_rectangle (state->texture, x2, y1, x1, y2, - 0, 0, COGL_FIXED_1, COGL_FIXED_1); + 0, 0, 1.0, 1.0); x1 = x2; - x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); + x2 = x1 + (float)(TEXTURE_SIZE); /* Draw a front-facing texture polygon */ verts[0].x = x1; verts[0].y = y2; @@ -148,14 +148,14 @@ on_paint (ClutterActor *actor, TestState *state) verts[2].x = x2; verts[2].y = y1; verts[3].x = x1; verts[3].y = y1; verts[0].tx = 0; verts[0].ty = 0; - verts[1].tx = COGL_FIXED_1; verts[1].ty = 0; - verts[2].tx = COGL_FIXED_1; verts[2].ty = COGL_FIXED_1; - verts[3].tx = 0; verts[3].ty = COGL_FIXED_1; + verts[1].tx = 1.0; verts[1].ty = 0; + verts[2].tx = 1.0; verts[2].ty = 1.0; + verts[3].tx = 0; verts[3].ty = 1.0; cogl_texture_polygon (state->texture, 4, verts, FALSE); x1 = x2; - x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); + x2 = x1 + (float)(TEXTURE_SIZE); /* Draw a back-facing texture polygon */ verts[0].x = x1; verts[0].y = y1; @@ -163,19 +163,19 @@ on_paint (ClutterActor *actor, TestState *state) verts[2].x = x2; verts[2].y = y2; verts[3].x = x1; verts[3].y = y2; verts[0].tx = 0; verts[0].ty = 0; - verts[1].tx = COGL_FIXED_1; verts[1].ty = 0; - verts[2].tx = COGL_FIXED_1; verts[2].ty = COGL_FIXED_1; - verts[3].tx = 0; verts[3].ty = COGL_FIXED_1; + verts[1].tx = 1.0; verts[1].ty = 0; + verts[2].tx = 1.0; verts[2].ty = 1.0; + verts[3].tx = 0; verts[3].ty = 1.0; cogl_texture_polygon (state->texture, 4, verts, FALSE); x1 = x2; - x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); + x2 = x1 + (float)(TEXTURE_SIZE); /* Draw a regular rectangle (this should always show) */ - cogl_set_source_color4x (COGL_FIXED_1, 0, 0, COGL_FIXED_1); - cogl_rectangle (COGL_FIXED_TO_INT (x1), COGL_FIXED_TO_INT (y1), - COGL_FIXED_TO_INT (x2 - x1), COGL_FIXED_TO_INT (y2 - y1)); + cogl_set_source_color4f (1.0, 0, 0, 1.0); + cogl_rectangle ( (x1), (y1), + (x2 - x1), (y2 - y1)); /* The second time round draw beneath the first with backface culling disabled */ @@ -225,7 +225,7 @@ make_texture (void) tex = cogl_texture_new_from_data (TEXTURE_SIZE, TEXTURE_SIZE, 8, - FALSE, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_ANY, TEXTURE_SIZE * 4, diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 1b8d54c0f..f6e14d38f 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -46,17 +46,17 @@ main (int argc, char **argv) #endif g_test_init (&argc, &argv, NULL); - + g_test_bug_base ("http://bugzilla.openedhand.com/show_bug.cgi?id=%s"); g_assert (clutter_init (shared_state->argc_addr, shared_state->argv_addr) == CLUTTER_INIT_SUCCESS); - + /* Initialise the state you need to share with everything. */ shared_state->argc_addr = &argc; shared_state->argv_addr = &argv; - + TEST_CONFORM_SIMPLE ("/timeline", test_timeline); if (g_test_slow ()) { @@ -65,7 +65,7 @@ main (int argc, char **argv) TEST_CONFORM_SIMPLE ("/timeline", test_timeline_rewind); TEST_CONFORM_SIMPLE ("/timeline", test_timeline_smoothness); } - + TEST_CONFORM_SIMPLE ("/picking", test_pick); /* ClutterText */ @@ -88,15 +88,15 @@ main (int argc, char **argv) TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_color); TEST_CONFORM_SIMPLE ("/fixed", test_fixed_constants); - + TEST_CONFORM_SIMPLE ("/invariants", test_initial_state); TEST_CONFORM_SIMPLE ("/invariants", test_realized); TEST_CONFORM_SIMPLE ("/invariants", test_mapped); TEST_CONFORM_SIMPLE ("/invariants", test_show_on_set_parent); - TEST_CONFORM_SIMPLE ("/mesh", test_mesh_contiguous); - TEST_CONFORM_SIMPLE ("/mesh", test_mesh_interleved); - TEST_CONFORM_SIMPLE ("/mesh", test_mesh_mutability); + TEST_CONFORM_SIMPLE ("/vertex-buffer", test_vertex_buffer_contiguous); + TEST_CONFORM_SIMPLE ("/vertex-buffer", test_vertex_buffer_interleved); + TEST_CONFORM_SIMPLE ("/vertex-buffer", test_vertex_buffer_mutability); TEST_CONFORM_SIMPLE ("/opacity", test_label_opacity); TEST_CONFORM_SIMPLE ("/opacity", test_rectangle_opacity); diff --git a/tests/conform/test-mesh-contiguous.c b/tests/conform/test-vertex-buffer-contiguous.c similarity index 74% rename from tests/conform/test-mesh-contiguous.c rename to tests/conform/test-vertex-buffer-contiguous.c index b5d940ad7..2603e8539 100644 --- a/tests/conform/test-mesh-contiguous.c +++ b/tests/conform/test-vertex-buffer-contiguous.c @@ -4,9 +4,9 @@ #include "test-conform-common.h" -/* This test verifies that the simplest usage of the mesh API, where we add - * contiguous (x,y) GLfloat vertices, and RGBA GLubyte color attributes to a - * mesh object, submit, and draw. +/* This test verifies that the simplest usage of the vertex buffer API, + * where we add contiguous (x,y) GLfloat vertices, and RGBA GLubyte color + * attributes to a buffer, submit, and draw. * * It also tries to verify that the enable/disable attribute APIs are working * too. @@ -17,7 +17,7 @@ typedef struct _TestState { - CoglHandle mesh; + CoglHandle buffer; ClutterGeometry stage_geom; guint frame; } TestState; @@ -44,7 +44,7 @@ validate_result (TestState *state) if (g_test_verbose ()) g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0); - + /* Should see a red pixel */ glReadPixels (110, y_off, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); if (g_test_verbose ()) @@ -56,11 +56,11 @@ validate_result (TestState *state) if (g_test_verbose ()) g_print ("pixel 2 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0); - + #undef RED #undef GREEN #undef BLUE - + /* Comment this out if you want visual feedback of what this test * paints. */ @@ -71,35 +71,35 @@ static void on_paint (ClutterActor *actor, TestState *state) { /* Draw a faded blue triangle */ - cogl_mesh_enable_attribute (state->mesh, "gl_Color::blue"); + cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue"); cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_mesh_draw_arrays (state->mesh, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - + cogl_vertex_buffer_draw (state->buffer, + GL_TRIANGLE_STRIP, /* mode */ + 0, /* first */ + 3); /* count */ + /* Draw a red triangle */ /* Here we are testing that the disable attribute works; if it doesn't * the triangle will remain faded blue */ cogl_translate (100, 0, 0); - cogl_mesh_disable_attribute (state->mesh, "gl_Color::blue"); + cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue"); cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_mesh_draw_arrays (state->mesh, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ + cogl_vertex_buffer_draw (state->buffer, + GL_TRIANGLE_STRIP, /* mode */ + 0, /* first */ + 3); /* count */ /* Draw a faded blue triangle */ /* Here we are testing that the re-enable works; if it doesn't * the triangle will remain red */ cogl_translate (100, 0, 0); - cogl_mesh_enable_attribute (state->mesh, "gl_Color::blue"); + cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue"); cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_mesh_draw_arrays (state->mesh, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - + cogl_vertex_buffer_draw (state->buffer, + GL_TRIANGLE_STRIP, /* mode */ + 0, /* first */ + 3); /* count */ + /* XXX: Experiments have shown that for some buggy drivers, when using * glReadPixels there is some kind of race, so we delay our test for a * few frames and a few seconds: @@ -108,7 +108,7 @@ on_paint (ClutterActor *actor, TestState *state) validate_result (state); else g_usleep (G_USEC_PER_SEC); - + state->frame++; } @@ -121,8 +121,8 @@ queue_redraw (gpointer stage) } void -test_mesh_contiguous (TestConformSimpleFixture *fixture, - gconstpointer data) +test_vertex_buffer_contiguous (TestConformSimpleFixture *fixture, + gconstpointer data) { TestState state; ClutterActor *stage; @@ -149,7 +149,7 @@ test_mesh_contiguous (TestConformSimpleFixture *fixture, idle_source = g_idle_add (queue_redraw, stage); g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - + { GLfloat triangle_verts[3][2] = { @@ -163,29 +163,29 @@ test_mesh_contiguous (TestConformSimpleFixture *fixture, {0x00, 0x00, 0xff, 0x00}, /* transparent blue */ {0x00, 0x00, 0xff, 0x00} /* transparent blue */ }; - state.mesh = cogl_mesh_new (3 /* n vertices */); - cogl_mesh_add_attribute (state.mesh, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_verts); - cogl_mesh_add_attribute (state.mesh, - "gl_Color::blue", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - triangle_colors); - cogl_mesh_submit (state.mesh); + state.buffer = cogl_vertex_buffer_new (3 /* n vertices */); + cogl_vertex_buffer_add (state.buffer, + "gl_Vertex", + 2, /* n components */ + GL_FLOAT, + FALSE, /* normalized */ + 0, /* stride */ + triangle_verts); + cogl_vertex_buffer_add (state.buffer, + "gl_Color::blue", + 4, /* n components */ + GL_UNSIGNED_BYTE, + FALSE, /* normalized */ + 0, /* stride */ + triangle_colors); + cogl_vertex_buffer_submit (state.buffer); } clutter_actor_show_all (stage); clutter_main (); - cogl_mesh_unref (state.mesh); + cogl_vertex_buffer_unref (state.buffer); g_source_remove (idle_source); diff --git a/tests/conform/test-mesh-interleved.c b/tests/conform/test-vertex-buffer-interleved.c similarity index 76% rename from tests/conform/test-mesh-interleved.c rename to tests/conform/test-vertex-buffer-interleved.c index 5cd3a2b1b..6afad872f 100644 --- a/tests/conform/test-mesh-interleved.c +++ b/tests/conform/test-vertex-buffer-interleved.c @@ -4,9 +4,9 @@ #include "test-conform-common.h" -/* This test verifies that interleved attributes work with the mesh API. - * We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color - * attributes to a mesh object, submit and draw. +/* This test verifies that interleved attributes work with the vertex buffer + * API. We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color + * attributes to a buffer, submit and draw. * * If you want visual feedback of what this test paints for debugging purposes, * then remove the call to clutter_main_quit() in validate_result. @@ -14,7 +14,7 @@ typedef struct _TestState { - CoglHandle mesh; + CoglHandle buffer; ClutterGeometry stage_geom; guint frame; } TestState; @@ -51,11 +51,11 @@ validate_result (TestState *state) if (g_test_verbose ()) g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0); - + #undef RED #undef GREEN #undef BLUE - + /* Comment this out if you want visual feedback of what this test * paints. */ @@ -66,10 +66,10 @@ static void on_paint (ClutterActor *actor, TestState *state) { /* Draw a faded blue triangle */ - cogl_mesh_draw_arrays (state->mesh, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ + cogl_vertex_buffer_draw (state->buffer, + GL_TRIANGLE_STRIP, /* mode */ + 0, /* first */ + 3); /* count */ /* XXX: Experiments have shown that for some buggy drivers, when using * glReadPixels there is some kind of race, so we delay our test for a @@ -79,7 +79,7 @@ on_paint (ClutterActor *actor, TestState *state) validate_result (state); else g_usleep (G_USEC_PER_SEC); - + state->frame++; } @@ -92,8 +92,8 @@ queue_redraw (gpointer stage) } void -test_mesh_interleved (TestConformSimpleFixture *fixture, - gconstpointer data) +test_vertex_buffer_interleved (TestConformSimpleFixture *fixture, + gconstpointer data) { TestState state; ClutterActor *stage; @@ -120,7 +120,7 @@ test_mesh_interleved (TestConformSimpleFixture *fixture, idle_source = g_idle_add (queue_redraw, stage); g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - + { InterlevedVertex verts[3] = { @@ -141,29 +141,29 @@ test_mesh_interleved (TestConformSimpleFixture *fixture, */ g_assert (sizeof (InterlevedVertex) == 12); - state.mesh = cogl_mesh_new (3 /* n vertices */); - cogl_mesh_add_attribute (state.mesh, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 12, /* stride */ - &verts[0].x); - cogl_mesh_add_attribute (state.mesh, - "gl_Color", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 12, /* stride */ - &verts[0].r); - cogl_mesh_submit (state.mesh); + state.buffer = cogl_vertex_buffer_new (3 /* n vertices */); + cogl_vertex_buffer_add (state.buffer, + "gl_Vertex", + 2, /* n components */ + GL_FLOAT, + FALSE, /* normalized */ + 12, /* stride */ + &verts[0].x); + cogl_vertex_buffer_add (state.buffer, + "gl_Color", + 4, /* n components */ + GL_UNSIGNED_BYTE, + FALSE, /* normalized */ + 12, /* stride */ + &verts[0].r); + cogl_vertex_buffer_submit (state.buffer); } clutter_actor_show_all (stage); clutter_main (); - cogl_mesh_unref (state.mesh); + cogl_vertex_buffer_unref (state.buffer); g_source_remove (idle_source); diff --git a/tests/conform/test-mesh-mutability.c b/tests/conform/test-vertex-buffer-mutability.c similarity index 71% rename from tests/conform/test-mesh-mutability.c rename to tests/conform/test-vertex-buffer-mutability.c index af7ec80f5..c1a24298e 100644 --- a/tests/conform/test-mesh-mutability.c +++ b/tests/conform/test-vertex-buffer-mutability.c @@ -4,7 +4,7 @@ #include "test-conform-common.h" -/* This test verifies that modifying mesh objects works, by updating +/* This test verifies that modifying a vertex buffer works, by updating * vertex positions, and deleting and re-adding different color attributes. * * If you want visual feedback of what this test paints for debugging purposes, @@ -13,7 +13,7 @@ typedef struct _TestState { - CoglHandle mesh; + CoglHandle buffer; ClutterGeometry stage_geom; guint frame; } TestState; @@ -47,7 +47,7 @@ validate_result (TestState *state) #undef RED #undef GREEN #undef BLUE - + /* Comment this out if you want visual feedback of what this test * paints. */ @@ -76,41 +76,41 @@ on_paint (ClutterActor *actor, TestState *state) cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_mesh_add_attribute (state->mesh, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_verts); - cogl_mesh_delete_attribute (state->mesh, "gl_Color"); - cogl_mesh_submit (state->mesh); - - cogl_mesh_draw_arrays (state->mesh, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - + cogl_vertex_buffer_add (state->buffer, + "gl_Vertex", + 2, /* n components */ + GL_FLOAT, + FALSE, /* normalized */ + 0, /* stride */ + triangle_verts); + cogl_vertex_buffer_delete (state->buffer, "gl_Color"); + cogl_vertex_buffer_submit (state->buffer); + + cogl_vertex_buffer_draw (state->buffer, + GL_TRIANGLE_STRIP, /* mode */ + 0, /* first */ + 3); /* count */ + /* * Draw a faded green triangle */ - cogl_mesh_add_attribute (state->mesh, - "gl_Color", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - triangle_colors); - cogl_mesh_submit (state->mesh); + cogl_vertex_buffer_add (state->buffer, + "gl_Color", + 4, /* n components */ + GL_UNSIGNED_BYTE, + FALSE, /* normalized */ + 0, /* stride */ + triangle_colors); + cogl_vertex_buffer_submit (state->buffer); cogl_translate (100, 0, 0); - cogl_mesh_draw_arrays (state->mesh, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ + cogl_vertex_buffer_draw (state->buffer, + GL_TRIANGLE_STRIP, /* mode */ + 0, /* first */ + 3); /* count */ + - /* XXX: Experiments have shown that for some buggy drivers, when using * glReadPixels there is some kind of race, so we delay our test for a * few frames and a few seconds: @@ -119,7 +119,7 @@ on_paint (ClutterActor *actor, TestState *state) validate_result (state); else g_usleep (G_USEC_PER_SEC); - + state->frame++; } @@ -132,8 +132,8 @@ queue_redraw (gpointer stage) } void -test_mesh_mutability (TestConformSimpleFixture *fixture, - gconstpointer data) +test_vertex_buffer_mutability (TestConformSimpleFixture *fixture, + gconstpointer data) { TestState state; ClutterActor *stage; @@ -160,7 +160,7 @@ test_mesh_mutability (TestConformSimpleFixture *fixture, idle_source = g_idle_add (queue_redraw, stage); g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - + { GLfloat triangle_verts[3][2] = { @@ -174,29 +174,29 @@ test_mesh_mutability (TestConformSimpleFixture *fixture, {0x00, 0x00, 0xff, 0x00}, /* transparent blue */ {0x00, 0x00, 0xff, 0x00} /* transparent blue */ }; - state.mesh = cogl_mesh_new (3 /* n vertices */); - cogl_mesh_add_attribute (state.mesh, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_verts); - cogl_mesh_add_attribute (state.mesh, - "gl_Color", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - triangle_colors); - cogl_mesh_submit (state.mesh); + state.buffer = cogl_vertex_buffer_new (3 /* n vertices */); + cogl_vertex_buffer_add (state.buffer, + "gl_Vertex", + 2, /* n components */ + GL_FLOAT, + FALSE, /* normalized */ + 0, /* stride */ + triangle_verts); + cogl_vertex_buffer_add (state.buffer, + "gl_Color", + 4, /* n components */ + GL_UNSIGNED_BYTE, + FALSE, /* normalized */ + 0, /* stride */ + triangle_colors); + cogl_vertex_buffer_submit (state.buffer); } clutter_actor_show_all (stage); clutter_main (); - cogl_mesh_unref (state.mesh); + cogl_vertex_buffer_unref (state.buffer); g_source_remove (idle_source); diff --git a/tests/interactive/Makefile.am b/tests/interactive/Makefile.am index cd05130fb..5ba1d1794 100644 --- a/tests/interactive/Makefile.am +++ b/tests/interactive/Makefile.am @@ -15,7 +15,6 @@ UNIT_TESTS = \ test-script.c \ test-model.c \ test-grab.c \ - test-effects.c \ test-fullscreen.c \ test-shader.c \ test-unproject.c \ @@ -40,7 +39,8 @@ UNIT_TESTS = \ test-easing.c \ test-binding-pool.c \ test-text.c \ - test-text-field.c + test-text-field.c \ + test-clutter-cairo-flowers.c if X11_TESTS UNIT_TESTS += test-pixmap.c diff --git a/tests/interactive/test-actors.c b/tests/interactive/test-actors.c index d5116cdf7..ded1e1a24 100644 --- a/tests/interactive/test-actors.c +++ b/tests/interactive/test-actors.c @@ -168,7 +168,8 @@ test_actors_main (int argc, char *argv[]) g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh); /* Set up some behaviours to handle scaling */ - alpha = clutter_alpha_new_full (timeline, clutter_sine_func, NULL, NULL); + alpha = clutter_alpha_new_with_func (timeline, clutter_sine_func, + NULL, NULL); scaler_1 = clutter_behaviour_scale_new (alpha, 0.5, 0.5, diff --git a/tests/interactive/test-animation.c b/tests/interactive/test-animation.c index 000e02bd8..ee0ff7337 100644 --- a/tests/interactive/test-animation.c +++ b/tests/interactive/test-animation.c @@ -23,13 +23,12 @@ on_button_press (ClutterActor *actor, ClutterAnimation *animation; gint old_x, old_y, new_x, new_y; guint old_width, old_height, new_width, new_height; - guint8 old_op, new_op; gdouble new_angle; ClutterVertex vertex = { 0, }; + ClutterColor new_color = { 0, }; clutter_actor_get_position (actor, &old_x, &old_y); clutter_actor_get_size (actor, &old_width, &old_height); - old_op = clutter_actor_get_opacity (actor); /* determine the final state of the animation depending on * the state of the actor @@ -40,8 +39,12 @@ on_button_press (ClutterActor *actor, new_y = old_y - 100; new_width = old_width + 200; new_height = old_height + 200; - new_op = 255; new_angle = 360.0; + + new_color.red = 0xdd; + new_color.green = 0x44; + new_color.blue = 0xdd; + new_color.alpha = 0xff; } else { @@ -49,8 +52,12 @@ on_button_press (ClutterActor *actor, new_y = old_y + 100; new_width = old_width - 200; new_height = old_height - 200; - new_op = 128; new_angle = 0.0; + + new_color.red = 0x44; + new_color.green = 0xdd; + new_color.blue = 0x44; + new_color.alpha = 0x88; } vertex.x = CLUTTER_UNITS_FROM_FLOAT ((float) new_width / 2); @@ -62,7 +69,7 @@ on_button_press (ClutterActor *actor, "y", new_y, "width", new_width, "height", new_height, - "opacity", new_op, + "color", &new_color, "rotation-angle-z", new_angle, "fixed::rotation-center-z", &vertex, "fixed::reactive", FALSE, diff --git a/tests/interactive/test-behave.c b/tests/interactive/test-behave.c index 6ecf255f5..07985d774 100644 --- a/tests/interactive/test-behave.c +++ b/tests/interactive/test-behave.c @@ -171,8 +171,7 @@ test_behave_main (int argc, char *argv[]) NULL); /* Set an alpha func to power behaviour - ramp is constant rise */ - alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR); - clutter_alpha_set_timeline (alpha, timeline); + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); /* Create a behaviour for that alpha */ o_behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff); diff --git a/tests/interactive/test-clip.c b/tests/interactive/test-clip.c index 5ccddfbcc..119b4ac68 100644 --- a/tests/interactive/test-clip.c +++ b/tests/interactive/test-clip.c @@ -302,8 +302,10 @@ test_clip_main (int argc, char **argv) stub_actor = clutter_rectangle_new (); clutter_container_add (CLUTTER_CONTAINER (data.stage), stub_actor, NULL); - data.hand = cogl_texture_new_from_file ("redhand.png", 64, FALSE, - COGL_PIXEL_FORMAT_ANY, NULL); + data.hand = cogl_texture_new_from_file ("redhand.png", 64, + COGL_TEXTURE_NONE, + COGL_PIXEL_FORMAT_ANY, + NULL); label = clutter_text_new_with_text ("Sans 12px", instructions); clutter_text_set_line_wrap (CLUTTER_TEXT (label), TRUE); diff --git a/tests/interactive/test-clutter-cairo-flowers.c b/tests/interactive/test-clutter-cairo-flowers.c new file mode 100644 index 000000000..c66531672 --- /dev/null +++ b/tests/interactive/test-clutter-cairo-flowers.c @@ -0,0 +1,212 @@ +/* + * Pretty cairo flower hack. + */ + +#include + +#include /* for sleep(), used for screenshots */ +#include +#include "math.h" + +#define PETAL_MIN 20 +#define PETAL_VAR 40 +#define N_FLOWERS 40 /* reduce if you have a small card */ + +typedef struct Flower +{ + ClutterActor *ctex; + gint x,y,rot,v,rv; +} +Flower; + +ClutterActor* +make_flower_actor (void) +{ + /* No science here, just a hack from toying */ + gint i, j; + + double colors[] = { + 0.71, 0.81, 0.83, + 1.0, 0.78, 0.57, + 0.64, 0.30, 0.35, + 0.73, 0.40, 0.39, + 0.91, 0.56, 0.64, + 0.70, 0.47, 0.45, + 0.92, 0.75, 0.60, + 0.82, 0.86, 0.85, + 0.51, 0.56, 0.67, + 1.0, 0.79, 0.58, + + }; + + gint size; + gint petal_size; + gint n_groups; /* Num groups of petals 1-3 */ + gint n_petals; /* num of petals 4 - 8 */ + gint pm1, pm2; + + gint idx, last_idx = -1; + + ClutterActor *ctex; + cairo_t *cr; + + petal_size = PETAL_MIN + rand() % PETAL_VAR; + size = petal_size * 8; + + n_groups = rand() % 3 + 1; + + ctex = clutter_cairo_texture_new (size, size); + + cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (ctex)); + + cairo_set_tolerance (cr, 0.1); + + /* Clear */ + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + + cairo_translate(cr, size/2, size/2); + + for (i=0; iy += flowers[i]->v; + flowers[i]->rot += flowers[i]->rv; + + if (flowers[i]->y > (gint)clutter_actor_get_height + (clutter_stage_get_default ())) + flowers[i]->y = -clutter_actor_get_height (flowers[i]->ctex); + + clutter_actor_set_position (flowers[i]->ctex, + flowers[i]->x, flowers[i]->y); + + clutter_actor_set_rotation (flowers[i]->ctex, + CLUTTER_Z_AXIS, + flowers[i]->rot, + clutter_actor_get_width (flowers[i]->ctex)/2, + clutter_actor_get_height (flowers[i]->ctex)/2, + 0); + } + + return TRUE; +} + +void foo(void) { g_usleep(10000000); } + +int +test_clutter_cairo_flowers_main (int argc, char **argv) +{ + int i; + ClutterActor *stage; + ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; + Flower *flowers[N_FLOWERS]; + + srand(time(NULL)); + + clutter_init (&argc, &argv); + + stage = clutter_stage_get_default (); + + clutter_stage_set_color (CLUTTER_STAGE (stage), + &stage_color); + + g_object_set(stage, "fullscreen", TRUE, NULL); + + for (i=0; i< N_FLOWERS; i++) + { + flowers[i] = g_new0(Flower, 1); + flowers[i]->ctex = make_flower_actor(); + flowers[i]->x = rand() % clutter_actor_get_width(stage) + - (PETAL_MIN+PETAL_VAR)*2; + flowers[i]->y = rand() % clutter_actor_get_height(stage); + flowers[i]->rv = rand() % 5 + 1; + flowers[i]->v = rand() % 10 + 2; + + clutter_group_add (CLUTTER_GROUP(stage), flowers[i]->ctex); + clutter_actor_set_position (flowers[i]->ctex, + flowers[i]->x, flowers[i]->y); + } + + g_timeout_add (50, tick, flowers); + + clutter_actor_show_all (CLUTTER_ACTOR (stage)); + + g_signal_connect (stage, "key-press-event", + G_CALLBACK (clutter_main_quit), + NULL); + + clutter_main(); + + return 1; +} + diff --git a/tests/interactive/test-cogl-offscreen.c b/tests/interactive/test-cogl-offscreen.c index c18f73f33..893862e08 100644 --- a/tests/interactive/test-cogl-offscreen.c +++ b/tests/interactive/test-cogl-offscreen.c @@ -150,12 +150,14 @@ test_coglbox_init (TestCoglbox *self) self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); printf ("Loading redhand.png\n"); - priv->texhand_id = cogl_texture_new_from_file ("redhand.png", 0, FALSE, + priv->texhand_id = cogl_texture_new_from_file ("redhand.png", 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); printf ("Creating texture with size\n"); - priv->texture_id = cogl_texture_new_with_size (200,200,0, FALSE, + priv->texture_id = cogl_texture_new_with_size (200, 200, 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_RGB_888); if (priv->texture_id == COGL_INVALID_HANDLE) diff --git a/tests/interactive/test-cogl-tex-convert.c b/tests/interactive/test-cogl-tex-convert.c index d9dcb48fe..816ea403b 100644 --- a/tests/interactive/test-cogl-tex-convert.c +++ b/tests/interactive/test-cogl-tex-convert.c @@ -159,19 +159,23 @@ test_coglbox_init (TestCoglbox *self) self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); priv->cogl_tex_id[0] = - cogl_texture_new_from_file ("redhand.png", 0, FALSE, + cogl_texture_new_from_file ("redhand.png", 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); priv->cogl_tex_id[1] = - cogl_texture_new_from_file ("redhand.png", 0, FALSE, + cogl_texture_new_from_file ("redhand.png", 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_BGRA_8888, NULL); priv->cogl_tex_id[2] = - cogl_texture_new_from_file ("redhand.png", 0, FALSE, + cogl_texture_new_from_file ("redhand.png", 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ARGB_8888, NULL); priv->cogl_tex_id[3] = - cogl_texture_new_from_file ("redhand.png", 0, FALSE, + cogl_texture_new_from_file ("redhand.png", 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_G_8, NULL); } diff --git a/tests/interactive/test-cogl-tex-getset.c b/tests/interactive/test-cogl-tex-getset.c index e562db7bf..056b5693d 100644 --- a/tests/interactive/test-cogl-tex-getset.c +++ b/tests/interactive/test-cogl-tex-getset.c @@ -141,7 +141,8 @@ test_coglbox_init (TestCoglbox *self) /* Load image from file */ priv->cogl_tex_id[0] = - cogl_texture_new_from_file ("redhand.png", 40, FALSE, + cogl_texture_new_from_file ("redhand.png", 40, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); if (priv->cogl_tex_id[0] == COGL_INVALID_HANDLE) @@ -176,7 +177,8 @@ test_coglbox_init (TestCoglbox *self) /* Create new texture from modified data */ priv->cogl_tex_id[1] = - cogl_texture_new_from_data (width, height, 0, FALSE, + cogl_texture_new_from_data (width, height, 0, + COGL_TEXTURE_NONE, format, format, rowstride, data); diff --git a/tests/interactive/test-cogl-tex-polygon.c b/tests/interactive/test-cogl-tex-polygon.c index 1e9d38b18..ae64998df 100644 --- a/tests/interactive/test-cogl-tex-polygon.c +++ b/tests/interactive/test-cogl-tex-polygon.c @@ -248,21 +248,37 @@ test_coglbox_init (TestCoglbox *self) priv->use_linear_filtering = FALSE; priv->use_sliced = FALSE; - priv->sliced_tex = cogl_texture_new_from_file - ("redhand.png", 10, FALSE, COGL_PIXEL_FORMAT_ANY, &error); - if (priv->sliced_tex == NULL) + priv->sliced_tex = + cogl_texture_new_from_file ("redhand.png", 10, + COGL_TEXTURE_NONE, + COGL_PIXEL_FORMAT_ANY, + &error); + if (priv->sliced_tex == COGL_INVALID_HANDLE) { - g_warning ("Texture loading failed: %s", error->message); - g_error_free (error); - error = NULL; + if (error) + { + g_warning ("Texture loading failed: %s", error->message); + g_error_free (error); + error = NULL; + } + else + g_warning ("Texture loading failed: "); } - priv->not_sliced_tex = cogl_texture_new_from_file - ("redhand.png", -1, FALSE, COGL_PIXEL_FORMAT_ANY, &error); - if (priv->not_sliced_tex == NULL) + priv->not_sliced_tex = + cogl_texture_new_from_file ("redhand.png", -1, + COGL_TEXTURE_NONE, + COGL_PIXEL_FORMAT_ANY, + &error); + if (priv->not_sliced_tex == COGL_INVALID_HANDLE) { - g_warning ("Texture loading failed: %s", error->message); - g_error_free (error); + if (error) + { + g_warning ("Texture loading failed: %s", error->message); + g_error_free (error); + } + else + g_warning ("Texture loading failed: "); } } diff --git a/tests/interactive/test-cogl-tex-tile.c b/tests/interactive/test-cogl-tex-tile.c index fe7138a60..8e2739a92 100644 --- a/tests/interactive/test-cogl-tex-tile.c +++ b/tests/interactive/test-cogl-tex-tile.c @@ -90,22 +90,22 @@ test_coglbox_paint(ClutterActor *self) ClutterFixed sin_frame, cos_frame; ClutterFixed frac_frame; gint t; - sin_frame = clutter_sini (CLUTTER_ANGLE_FROM_DEG (priv->frame)); - cos_frame = clutter_cosi (CLUTTER_ANGLE_FROM_DEG (priv->frame)); + sin_frame = clutter_sinx (priv->frame); + cos_frame = clutter_cosx (priv->frame); pingpong_frame = (priv->frame <= 180 ? priv->frame : 360 - priv->frame); - frac_frame = COGL_FIXED_DIV (CLUTTER_INT_TO_FIXED (pingpong_frame), - CLUTTER_INT_TO_FIXED (180)); - frac_frame += (COGL_FIXED_1 >> 1); - frac_frame <<= 1; + frac_frame = (CLUTTER_INT_TO_FIXED (pingpong_frame) / + CLUTTER_INT_TO_FIXED (180)); + frac_frame += 0.5; + frac_frame *= 2; for (t=0; t<4; t+=2) { texcoords[t] += cos_frame; texcoords[t+1] += sin_frame; - texcoords[t] = COGL_FIXED_MUL (texcoords[t], frac_frame); - texcoords[t+1] = COGL_FIXED_MUL (texcoords[t+1], frac_frame); + texcoords[t] = (texcoords[t] * frac_frame); + texcoords[t+1] = (texcoords[t+1] * frac_frame); } priv = TEST_COGLBOX_GET_PRIVATE (self); @@ -150,7 +150,8 @@ test_coglbox_init (TestCoglbox *self) TestCoglboxPrivate *priv; self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); - priv->cogl_tex_id = cogl_texture_new_from_file ("redhand.png", 0, FALSE, + priv->cogl_tex_id = cogl_texture_new_from_file ("redhand.png", 0, + COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); diff --git a/tests/interactive/test-depth.c b/tests/interactive/test-depth.c index 34c024ede..a34ff43b5 100644 --- a/tests/interactive/test-depth.c +++ b/tests/interactive/test-depth.c @@ -26,7 +26,7 @@ raise_top (gpointer ignored) static ClutterActor * clone_box (ClutterTexture *original) { - gint width, height; + guint width, height; ClutterActor *group; ClutterActor *clone; @@ -40,7 +40,7 @@ clone_box (ClutterTexture *original) clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 180, width/2, 0, 0); - clutter_actor_set_depth (clone, -width/2); + clutter_actor_set_depth (clone, -(gint)width/2); clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); @@ -57,13 +57,13 @@ clone_box (ClutterTexture *original) clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, -width/2); + clutter_actor_set_depth (clone, -(gint)width/2); clutter_actor_set_position (clone, 0, height); clone = clutter_clone_texture_new (original); clutter_container_add_actor (CLUTTER_CONTAINER (group), clone); clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, -width/2); + clutter_actor_set_depth (clone, -(gint)width/2); clutter_actor_set_position (clone, 0, 0); clutter_actor_show_all (group); @@ -159,10 +159,10 @@ test_depth_main (int argc, char *argv[]) "completed", G_CALLBACK (timeline_completed), NULL); - d_behave = clutter_behaviour_depth_new (clutter_alpha_new_full (timeline, - clutter_ramp_inc_func, - NULL, NULL), - -100, 100); + d_behave = + clutter_behaviour_depth_new (clutter_alpha_new_full (timeline, + CLUTTER_LINEAR), + -100, 100); clutter_behaviour_apply (d_behave, label); /* add two faced actor */ @@ -170,12 +170,12 @@ test_depth_main (int argc, char *argv[]) clutter_container_add_actor (CLUTTER_CONTAINER (stage), janus); clutter_actor_set_position (janus, 300, 350); - r_behave = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, - clutter_ramp_inc_func, - NULL, NULL), - CLUTTER_Y_AXIS, - CLUTTER_ROTATE_CW, - 0, 360); + r_behave = + clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, + CLUTTER_LINEAR), + CLUTTER_Y_AXIS, + CLUTTER_ROTATE_CW, + 0, 360); clutter_behaviour_apply (r_behave, janus); @@ -187,12 +187,12 @@ test_depth_main (int argc, char *argv[]) clutter_actor_set_rotation (box, CLUTTER_X_AXIS, 45, 0, 0, 0); clutter_actor_set_opacity (box, 0x44); - r_behave = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, - clutter_ramp_inc_func, - NULL, NULL), - CLUTTER_Y_AXIS, - CLUTTER_ROTATE_CW, - 0, 360); + r_behave = + clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, + CLUTTER_LINEAR), + CLUTTER_Y_AXIS, + CLUTTER_ROTATE_CW, + 0, 360); clutter_behaviour_apply (r_behave, box); diff --git a/tests/interactive/test-effects.c b/tests/interactive/test-effects.c deleted file mode 100644 index 10dcbec7b..000000000 --- a/tests/interactive/test-effects.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include - -static ClutterEffectTemplate *tmpl = NULL; -static ClutterTimeline *timeline = NULL; - -G_MODULE_EXPORT int -test_effects_main (int argc, char *argv[]) -{ - ClutterActor *stage, *actor; - ClutterContainer *container; - ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff }; - ClutterColor rect_color = { 0, 0, 0, 0xdd }; - - clutter_init (&argc, &argv); - - timeline = clutter_timeline_new_for_duration (5000); - clutter_timeline_set_loop (timeline, TRUE); - tmpl = - clutter_effect_template_new (timeline, clutter_ramp_inc_func); - - stage = clutter_stage_get_default (); - container = CLUTTER_CONTAINER (stage); - g_signal_connect (stage, - "button-press-event", G_CALLBACK (clutter_main_quit), - NULL); - - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); - clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE); - clutter_actor_set_size (stage, 800, 600); - clutter_actor_show_all (stage); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 50, 10); - clutter_effect_fade (tmpl, actor, 0x22, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 750, 70); - clutter_effect_depth (tmpl, actor, -500, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 50, 140); - clutter_effect_move (tmpl, actor, 750, 140, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 750, 210); - { - ClutterKnot knots[2]; - - knots[0].x = 750; knots[0].y = 210; - knots[1].x = 350; knots[1].y = 210; - - clutter_effect_path (tmpl, actor, knots, 2, NULL, NULL); - } - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 50, 280); - clutter_actor_set_anchor_point_from_gravity (actor, CLUTTER_GRAVITY_CENTER); - - clutter_effect_scale (tmpl, actor, 2.0, 2.0, NULL, NULL); - clutter_actor_show (actor); - - actor = clutter_rectangle_new_with_color (&rect_color); - clutter_container_add_actor (container, actor); - clutter_actor_set_size (actor, 50, 50); - clutter_actor_set_position (actor, 750, 350); - clutter_effect_rotate (tmpl, actor, - CLUTTER_Z_AXIS, 180.0, - 25, 25, 0, - CLUTTER_ROTATE_CW, - NULL, NULL); - clutter_actor_show (actor); - - clutter_main (); - - g_object_unref (tmpl); - g_object_unref (timeline); - - return EXIT_SUCCESS; -} diff --git a/tests/interactive/test-layout.c b/tests/interactive/test-layout.c index c11900f10..f446779cc 100644 --- a/tests/interactive/test-layout.c +++ b/tests/interactive/test-layout.c @@ -748,6 +748,7 @@ G_MODULE_EXPORT int test_layout_main (int argc, char *argv[]) { ClutterActor *stage, *instructions; + ClutterAlpha *alpha; gint i; GError *error = NULL; @@ -764,10 +765,8 @@ test_layout_main (int argc, char *argv[]) G_CALLBACK (relayout_on_frame), NULL); - behaviour = clutter_behaviour_scale_new (clutter_alpha_new_full (main_timeline, - clutter_sine_func, - NULL, NULL), - 1.0, 1.0, 2.0, 2.0); + alpha = clutter_alpha_new_full (main_timeline, CLUTTER_SINE_IN_OUT); + behaviour = clutter_behaviour_scale_new (alpha, 1.0, 1.0, 2.0, 2.0); box = my_thing_new (10, 10); diff --git a/tests/interactive/test-multistage.c b/tests/interactive/test-multistage.c index 1021f8b90..21f6427ae 100644 --- a/tests/interactive/test-multistage.c +++ b/tests/interactive/test-multistage.c @@ -75,8 +75,7 @@ on_button_press (ClutterActor *actor, timeline = clutter_timeline_new_for_duration (2000); g_object_set (timeline, "loop", TRUE, NULL); - alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR); - clutter_alpha_set_timeline (alpha, timeline); + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); r_behave = clutter_behaviour_rotate_new (alpha, CLUTTER_Y_AXIS, CLUTTER_ROTATE_CW, diff --git a/tests/interactive/test-paint-wrapper.c b/tests/interactive/test-paint-wrapper.c index 27448b8d3..5bc60f018 100644 --- a/tests/interactive/test-paint-wrapper.c +++ b/tests/interactive/test-paint-wrapper.c @@ -205,7 +205,7 @@ test_paint_wrapper_main (int argc, char *argv[]) g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh); /* Set up some behaviours to handle scaling */ - alpha = clutter_alpha_new_full (timeline, clutter_sine_func, NULL, NULL); + alpha = clutter_alpha_new_full (timeline, CLUTTER_SINE_IN_OUT); scaler_1 = clutter_behaviour_scale_new (alpha, 0.5, 0.5, diff --git a/tests/interactive/test-rotate.c b/tests/interactive/test-rotate.c index b147a7d24..8b37b7637 100644 --- a/tests/interactive/test-rotate.c +++ b/tests/interactive/test-rotate.c @@ -45,8 +45,7 @@ test_rotate_main (int argc, char *argv[]) g_object_set (timeline, "loop", TRUE, NULL); /* Set an alpha func to power behaviour */ - alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR); - clutter_alpha_set_timeline (alpha, timeline); + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); /* Create a behaviour for that alpha */ r_behave = clutter_behaviour_rotate_new (alpha, diff --git a/tests/interactive/test-scale.c b/tests/interactive/test-scale.c index 587cf2016..0a466cb5d 100644 --- a/tests/interactive/test-scale.c +++ b/tests/interactive/test-scale.c @@ -78,9 +78,9 @@ test_scale_main (int argc, char *argv[]) clutter_group_add (CLUTTER_GROUP (stage), rect); timeline = clutter_timeline_new_for_duration (750); - alpha = clutter_alpha_new_full (timeline, - clutter_ramp_func, - NULL, NULL); + alpha = clutter_alpha_new_with_func (timeline, + clutter_ramp_func, + NULL, NULL); behave = clutter_behaviour_scale_new (alpha, 0.0, 0.0, /* scale start */ diff --git a/tests/interactive/test-text-field.c b/tests/interactive/test-text-field.c index ca582731d..3087a7fe4 100644 --- a/tests/interactive/test-text-field.c +++ b/tests/interactive/test-text-field.c @@ -19,7 +19,7 @@ on_entry_paint (ClutterActor *actor, cogl_path_round_rectangle (0, 0, CLUTTER_UNITS_TO_FIXED (width), CLUTTER_UNITS_TO_FIXED (height), - COGL_FIXED_FROM_INT (4), + (float)(4), COGL_ANGLE_FROM_DEG (1.0)); cogl_path_stroke (); } diff --git a/tests/interactive/test-texture-quality.c b/tests/interactive/test-texture-quality.c index 8c5721f85..b7a54ce89 100644 --- a/tests/interactive/test-texture-quality.c +++ b/tests/interactive/test-texture-quality.c @@ -81,8 +81,7 @@ test_texture_quality_main (int argc, char *argv[]) "completed", G_CALLBACK (timeline_completed), NULL); - alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR); - clutter_alpha_set_timeline (alpha, timeline); + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 400); clutter_behaviour_apply (depth_behavior, image); diff --git a/tests/interactive/test-threads.c b/tests/interactive/test-threads.c index 5f946b653..a8843329b 100644 --- a/tests/interactive/test-threads.c +++ b/tests/interactive/test-threads.c @@ -213,16 +213,15 @@ test_threads_main (int argc, char *argv[]) timeline = clutter_timeline_new (150, 50); clutter_timeline_set_loop (timeline, TRUE); - r_behaviour = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, - clutter_ramp_inc_func, - NULL, NULL), + + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); + r_behaviour = clutter_behaviour_rotate_new (alpha, CLUTTER_Z_AXIS, CLUTTER_ROTATE_CW, 0.0, 360.0); clutter_behaviour_apply (r_behaviour, rect); - alpha = clutter_alpha_new_full (timeline, clutter_ramp_inc_func, - NULL, NULL); + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); p_behaviour = clutter_behaviour_path_new_with_knots (alpha, knots, G_N_ELEMENTS (knots)); diff --git a/tests/interactive/test-viewport.c b/tests/interactive/test-viewport.c index fcee1cf89..65a7f2048 100644 --- a/tests/interactive/test-viewport.c +++ b/tests/interactive/test-viewport.c @@ -40,8 +40,7 @@ test_viewport_main (int argc, char *argv[]) clutter_timeline_set_loop (timeline, TRUE); /* Set an alpha func to power behaviour */ - alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR); - clutter_alpha_set_timeline (alpha, timeline); + alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); /* Create a behaviour for that alpha */ r_behave = clutter_behaviour_rotate_new (alpha, diff --git a/tests/micro-bench/test-text.c b/tests/micro-bench/test-text.c index afbb8b47b..a322e3c4f 100644 --- a/tests/micro-bench/test-text.c +++ b/tests/micro-bench/test-text.c @@ -9,10 +9,9 @@ #define COLS 18 #define ROWS 20 -gboolean idle (gpointer data) +static void +on_paint (ClutterActor *actor, gconstpointer *data) { - ClutterActor *stage = CLUTTER_ACTOR (data); - static GTimer *timer = NULL; static int fps = 0; @@ -29,8 +28,13 @@ gboolean idle (gpointer data) fps = 0; } - clutter_actor_paint (stage); ++fps; +} + +static gboolean +queue_redraw (gpointer stage) +{ + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); return TRUE; } @@ -41,6 +45,9 @@ main (int argc, char *argv[]) ClutterActor *stage; ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; ClutterColor label_color = { 0xff, 0xff, 0xff, 0xff }; + ClutterActor *group; + + setenv ("CLUTTER_VBLANK", "none", 0); clutter_init (&argc, &argv); @@ -48,6 +55,14 @@ main (int argc, char *argv[]) clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + group = clutter_group_new (); + clutter_actor_set_size (group, STAGE_WIDTH, STAGE_WIDTH); + clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); + + g_idle_add (queue_redraw, stage); + + g_signal_connect (group, "paint", G_CALLBACK (on_paint), NULL); + { gint row, col; @@ -88,15 +103,13 @@ main (int argc, char *argv[]) (1.0*STAGE_HEIGHT/ROWS));*/ clutter_actor_set_scale (label, scale, scale); clutter_text_set_line_wrap (CLUTTER_TEXT (label), FALSE); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); + clutter_container_add_actor (CLUTTER_CONTAINER (group), label); } } clutter_actor_show_all (stage); g_signal_connect (stage, "key-press-event", G_CALLBACK (clutter_main_quit), NULL); - - g_idle_add (idle, (gpointer) stage); clutter_main();