Merge commit 'origin/master' into cogl-material

Conflicts:

	clutter/clutter-texture.c
	clutter/cogl/cogl-texture.h
	clutter/cogl/cogl.h.in
	clutter/cogl/common/Makefile.am
	clutter/cogl/gl/Makefile.am
	clutter/cogl/gles/Makefile.am
	clutter/cogl/gles/cogl-gles2-wrapper.c
	clutter/cogl/gles/cogl-gles2-wrapper.h
This commit is contained in:
Robert Bragg 2009-01-23 15:23:49 +00:00
commit 3d07e34cc5
118 changed files with 5223 additions and 4864 deletions

19
.gitignore vendored
View File

@ -114,6 +114,7 @@ stamp-h1
/tests/interactive/test-text-field /tests/interactive/test-text-field
/tests/interactive/redhand.png /tests/interactive/redhand.png
/tests/interactive/test-script.json /tests/interactive/test-script.json
/tests/interactive/test-clutter-cairo-flowers
/tests/conform/test-conformance /tests/conform/test-conformance
/tests/conform/test-conformance-results.xml /tests/conform/test-conformance-results.xml
/tests/conform/test-conformance-results.html /tests/conform/test-conformance-results.html
@ -153,6 +154,24 @@ stamp-h1
/tests/conform/test-rectangle-opacity /tests/conform/test-rectangle-opacity
/tests/conform/test-backface-culling /tests/conform/test-backface-culling
/tests/conform/test-binding-pool /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/micro-bench/test-text
/tests/tools/disable-npots.sh /tests/tools/disable-npots.sh
/clutter/x11/clutter-x11-enum-types.[ch] /clutter/x11/clutter-x11-enum-types.[ch]

View File

@ -47,6 +47,7 @@ BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
source_h = \ source_h = \
$(srcdir)/clutter-actor.h \ $(srcdir)/clutter-actor.h \
$(srcdir)/clutter-alpha.h \ $(srcdir)/clutter-alpha.h \
$(srcdir)/clutter-animatable.h \
$(srcdir)/clutter-animation.h \ $(srcdir)/clutter-animation.h \
$(srcdir)/clutter-backend.h \ $(srcdir)/clutter-backend.h \
$(srcdir)/clutter-behaviour.h \ $(srcdir)/clutter-behaviour.h \
@ -63,7 +64,6 @@ source_h = \
$(srcdir)/clutter-color.h \ $(srcdir)/clutter-color.h \
$(srcdir)/clutter-container.h \ $(srcdir)/clutter-container.h \
$(srcdir)/clutter-deprecated.h \ $(srcdir)/clutter-deprecated.h \
$(srcdir)/clutter-effect.h \
$(srcdir)/clutter-event.h \ $(srcdir)/clutter-event.h \
$(srcdir)/clutter-feature.h \ $(srcdir)/clutter-feature.h \
$(srcdir)/clutter-fixed.h \ $(srcdir)/clutter-fixed.h \
@ -137,6 +137,7 @@ CLEANFILES = $(STAMPFILES)
source_c = \ source_c = \
clutter-actor.c \ clutter-actor.c \
clutter-alpha.c \ clutter-alpha.c \
clutter-animatable.c \
clutter-animation.c \ clutter-animation.c \
clutter-backend.c \ clutter-backend.c \
clutter-behaviour.c \ clutter-behaviour.c \
@ -153,7 +154,6 @@ source_c = \
clutter-clone-texture.c \ clutter-clone-texture.c \
clutter-color.c \ clutter-color.c \
clutter-container.c \ clutter-container.c \
clutter-effect.c \
clutter-enum-types.c \ clutter-enum-types.c \
clutter-event.c \ clutter-event.c \
clutter-feature.c \ clutter-feature.c \

View File

@ -610,13 +610,20 @@ clutter_actor_real_pick (ClutterActor *self,
*/ */
if (clutter_actor_should_pick_paint (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, cogl_set_source_color4ub (color->red,
color->green, color->green,
color->blue, color->blue,
color->alpha); color->alpha);
cogl_rectangle (0, 0,
clutter_actor_get_width (self), cogl_rectangle (0, 0, width, height);
clutter_actor_get_height (self));
} }
} }
@ -774,12 +781,12 @@ clutter_actor_real_allocate (ClutterActor *self,
g_object_thaw_notify (G_OBJECT (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 { typedef struct {
CoglFixed x; float x;
CoglFixed y; float y;
CoglFixed z; float z;
CoglFixed w; float w;
} fixed_vertex_t; } fixed_vertex_t;
/* copies a fixed vertex into a ClutterVertex */ /* copies a fixed vertex into a ClutterVertex */
@ -806,7 +813,7 @@ static inline void
mtx_transform (const ClutterFixed m[], mtx_transform (const ClutterFixed m[],
fixed_vertex_t *vertex) fixed_vertex_t *vertex)
{ {
ClutterFixed _x, _y, _z, _w; float _x, _y, _z, _w;
_x = vertex->x; _x = vertex->x;
_y = vertex->y; _y = vertex->y;
@ -816,25 +823,25 @@ mtx_transform (const ClutterFixed m[],
/* We care lot about precision here, so have to use MUL instead /* We care lot about precision here, so have to use MUL instead
* of FAST_MUL * of FAST_MUL
*/ */
vertex->x = COGL_FIXED_MUL (M (m, 0, 0), _x) vertex->x = CLUTTER_FIXED_MUL (M (m, 0, 0), _x)
+ COGL_FIXED_MUL (M (m, 0, 1), _y) + CLUTTER_FIXED_MUL (M (m, 0, 1), _y)
+ COGL_FIXED_MUL (M (m, 0, 2), _z) + CLUTTER_FIXED_MUL (M (m, 0, 2), _z)
+ COGL_FIXED_MUL (M (m, 0, 3), _w); + CLUTTER_FIXED_MUL (M (m, 0, 3), _w);
vertex->y = COGL_FIXED_MUL (M (m, 1, 0), _x) vertex->y = CLUTTER_FIXED_MUL (M (m, 1, 0), _x)
+ COGL_FIXED_MUL (M (m, 1, 1), _y) + CLUTTER_FIXED_MUL (M (m, 1, 1), _y)
+ COGL_FIXED_MUL (M (m, 1, 2), _z) + CLUTTER_FIXED_MUL (M (m, 1, 2), _z)
+ COGL_FIXED_MUL (M (m, 1, 3), _w); + CLUTTER_FIXED_MUL (M (m, 1, 3), _w);
vertex->z = COGL_FIXED_MUL (M (m, 2, 0), _x) vertex->z = CLUTTER_FIXED_MUL (M (m, 2, 0), _x)
+ COGL_FIXED_MUL (M (m, 2, 1), _y) + CLUTTER_FIXED_MUL (M (m, 2, 1), _y)
+ COGL_FIXED_MUL (M (m, 2, 2), _z) + CLUTTER_FIXED_MUL (M (m, 2, 2), _z)
+ COGL_FIXED_MUL (M (m, 2, 3), _w); + CLUTTER_FIXED_MUL (M (m, 2, 3), _w);
vertex->w = COGL_FIXED_MUL (M (m, 3, 0), _x) vertex->w = CLUTTER_FIXED_MUL (M (m, 3, 0), _x)
+ COGL_FIXED_MUL (M (m, 3, 1), _y) + CLUTTER_FIXED_MUL (M (m, 3, 1), _y)
+ COGL_FIXED_MUL (M (m, 3, 2), _z) + CLUTTER_FIXED_MUL (M (m, 3, 2), _z)
+ COGL_FIXED_MUL (M (m, 3, 3), _w); + CLUTTER_FIXED_MUL (M (m, 3, 3), _w);
/* Specially for Matthew: was going to put a comment here, but could not /* Specially for Matthew: was going to put a comment here, but could not
* think of anything at all to say ;) * 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 /* Help macros to scale from OpenGL <-1,1> coordinates system to our
* X-window based <0,window-size> coordinates * 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_X(x,w,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)) (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))) #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 /* 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); x = CLUTTER_UNITS_TO_FIXED (vertex->x);
y = CLUTTER_UNITS_TO_FIXED (vertex->y); y = CLUTTER_UNITS_TO_FIXED (vertex->y);
z = CLUTTER_UNITS_TO_FIXED (vertex->z); z = CLUTTER_UNITS_TO_FIXED (vertex->z);
w = COGL_FIXED_1; w = 1.0;
/* First we tranform the point using the OpenGL modelview matrix */ /* First we tranform the point using the OpenGL modelview matrix */
clutter_actor_transform_point_relative (self, ancestor, &x, &y, &z, &w); 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 * 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. * 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.x = CLUTTER_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (x) + 0.5, v[2]);
tmp.y = COGL_FIXED_MUL (COGL_FIXED_0_5 - CLUTTER_UNITS_TO_FIXED (y), v[3]); tmp.y = CLUTTER_FIXED_MUL (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.z = CLUTTER_FIXED_MUL (CLUTTER_UNITS_TO_FIXED (z) + 0.5, v[2]);
tmp.w = 0; tmp.w = 0;
fixed_vertex_to_units (&tmp, vertex); fixed_vertex_to_units (&tmp, vertex);
@ -1119,10 +1129,10 @@ clutter_actor_transform_vertices_relative (ClutterActor *self,
cogl_get_modelview_matrix (mtx); cogl_get_modelview_matrix (mtx);
fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]); fixed_vertex_transform (mtx, 0, 0, 0, 1.0, &vertices[0]);
fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]); fixed_vertex_transform (mtx, width, 0, 0, 1.0, &vertices[1]);
fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]); fixed_vertex_transform (mtx, 0, height, 0, 1.0, &vertices[2]);
fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]); fixed_vertex_transform (mtx, width, height, 0, 1.0, &vertices[3]);
cogl_pop_matrix(); cogl_pop_matrix();
} }
@ -1171,10 +1181,10 @@ clutter_actor_transform_and_project_box (ClutterActor *self,
cogl_get_modelview_matrix (mtx); cogl_get_modelview_matrix (mtx);
fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]); fixed_vertex_transform (mtx, 0, 0, 0, 1.0, &vertices[0]);
fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]); fixed_vertex_transform (mtx, width, 0, 0, 1.0, &vertices[1]);
fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]); fixed_vertex_transform (mtx, 0, height, 0, 1.0, &vertices[2]);
fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]); fixed_vertex_transform (mtx, width, height, 0, 1.0, &vertices[3]);
cogl_pop_matrix(); 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; * 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. * 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.x = CLUTTER_FIXED_MUL ((vertices[0].x + 0.5), v[2]);
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[0].y), v[3]); tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[0].y), v[3]);
tmp.z = COGL_FIXED_MUL ((vertices[0].z + COGL_FIXED_0_5), v[2]); tmp.z = CLUTTER_FIXED_MUL ((vertices[0].z + 0.5), v[2]);
fixed_vertex_to_units (&tmp, &verts[0]); fixed_vertex_to_units (&tmp, &verts[0]);
tmp.x = COGL_FIXED_MUL ((vertices[1].x + COGL_FIXED_0_5), v[2]); tmp.x = CLUTTER_FIXED_MUL ((vertices[1].x + 0.5), v[2]);
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[1].y), v[3]); tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[1].y), v[3]);
tmp.z = COGL_FIXED_MUL ((vertices[1].z + COGL_FIXED_0_5), v[2]); tmp.z = CLUTTER_FIXED_MUL ((vertices[1].z + 0.5), v[2]);
fixed_vertex_to_units (&tmp, &verts[1]); fixed_vertex_to_units (&tmp, &verts[1]);
tmp.x = COGL_FIXED_MUL ((vertices[2].x + COGL_FIXED_0_5), v[2]); tmp.x = CLUTTER_FIXED_MUL ((vertices[2].x + 0.5), v[2]);
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[2].y), v[3]); tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[2].y), v[3]);
tmp.z = COGL_FIXED_MUL ((vertices[2].z + COGL_FIXED_0_5), v[2]); tmp.z = CLUTTER_FIXED_MUL ((vertices[2].z + 0.5), v[2]);
fixed_vertex_to_units (&tmp, &verts[2]); fixed_vertex_to_units (&tmp, &verts[2]);
tmp.x = COGL_FIXED_MUL ((vertices[3].x + COGL_FIXED_0_5), v[2]); tmp.x = CLUTTER_FIXED_MUL ((vertices[3].x + 0.5), v[2]);
tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[3].y), v[3]); tmp.y = CLUTTER_FIXED_MUL ((0.5 - vertices[3].y), v[3]);
tmp.z = COGL_FIXED_MUL ((vertices[3].z + COGL_FIXED_0_5), v[2]); tmp.z = CLUTTER_FIXED_MUL ((vertices[3].z + 0.5), v[2]);
fixed_vertex_to_units (&tmp, &verts[3]); 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); gboolean is_stage = CLUTTER_IS_STAGE (self);
if (!is_stage) if (!is_stage)
cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->allocation.x1), cogl_translate (CLUTTER_UNITS_TO_FLOAT (priv->allocation.x1),
CLUTTER_UNITS_TO_FIXED (priv->allocation.y1), CLUTTER_UNITS_TO_FLOAT (priv->allocation.y1),
0); 0);
/* /*
@ -1355,55 +1365,55 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self)
* the translations included in the rotation are not scaled and so the * 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). * 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); cogl_scale (priv->scale_x, priv->scale_y);
if (priv->rzang) if (priv->rzang)
{ {
cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->rzx), cogl_translate (CLUTTER_UNITS_TO_FLOAT (priv->rzx),
CLUTTER_UNITS_TO_FIXED (priv->rzy), CLUTTER_UNITS_TO_FLOAT (priv->rzy),
0); 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), cogl_translate (CLUTTER_UNITS_TO_FLOAT (-priv->rzx),
CLUTTER_UNITS_TO_FIXED (-priv->rzy), CLUTTER_UNITS_TO_FLOAT (-priv->rzy),
0); 0);
} }
if (priv->ryang) if (priv->ryang)
{ {
cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->ryx), cogl_translate (CLUTTER_UNITS_TO_FLOAT (priv->ryx),
0, 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, 0,
CLUTTER_UNITS_TO_FIXED (-(priv->z + priv->ryz))); CLUTTER_UNITS_TO_FLOAT (-(priv->z + priv->ryz)));
} }
if (priv->rxang) if (priv->rxang)
{ {
cogl_translatex (0, cogl_translate (0,
CLUTTER_UNITS_TO_FIXED (priv->rxy), CLUTTER_UNITS_TO_FLOAT (priv->rxy),
CLUTTER_UNITS_TO_FIXED (priv->z + priv->rxz)); 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, cogl_translate (0,
CLUTTER_UNITS_TO_FIXED (-priv->rxy), CLUTTER_UNITS_TO_FLOAT (-priv->rxy),
CLUTTER_UNITS_TO_FIXED (-(priv->z + priv->rxz))); CLUTTER_UNITS_TO_FLOAT (-(priv->z + priv->rxz)));
} }
if (!is_stage && (priv->anchor_x || priv->anchor_y)) if (!is_stage && (priv->anchor_x || priv->anchor_y))
cogl_translatex (CLUTTER_UNITS_TO_FIXED (-priv->anchor_x), cogl_translate (CLUTTER_UNITS_TO_FLOAT (-priv->anchor_x),
CLUTTER_UNITS_TO_FIXED (-priv->anchor_y), CLUTTER_UNITS_TO_FLOAT (-priv->anchor_y),
0); 0);
if (priv->z) if (priv->z)
cogl_translatex (0, 0, priv->z); cogl_translate (0, 0, priv->z);
} }
/* Recursively applies the transforms associated with this actor and /* Recursively applies the transforms associated with this actor and
@ -1656,14 +1666,14 @@ clutter_actor_set_property (GObject *object,
case PROP_SCALE_X: case PROP_SCALE_X:
clutter_actor_set_scalex clutter_actor_set_scalex
(actor, (actor,
COGL_FIXED_FROM_FLOAT (g_value_get_double (value)), CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)),
priv->scale_y); priv->scale_y);
break; break;
case PROP_SCALE_Y: case PROP_SCALE_Y:
clutter_actor_set_scalex clutter_actor_set_scalex
(actor, (actor,
priv->scale_x, priv->scale_x,
COGL_FIXED_FROM_FLOAT (g_value_get_double (value))); CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)));
break; break;
case PROP_CLIP: case PROP_CLIP:
{ {
@ -1681,7 +1691,7 @@ clutter_actor_set_property (GObject *object,
{ {
ClutterFixed angle; 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_actor_set_rotation_internal (actor,
CLUTTER_X_AXIS, CLUTTER_X_AXIS,
angle, angle,
@ -1694,7 +1704,7 @@ clutter_actor_set_property (GObject *object,
{ {
ClutterFixed angle; 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_actor_set_rotation_internal (actor,
CLUTTER_Y_AXIS, CLUTTER_Y_AXIS,
angle, angle,
@ -1707,7 +1717,7 @@ clutter_actor_set_property (GObject *object,
{ {
ClutterFixed angle; 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_actor_set_rotation_internal (actor,
CLUTTER_Z_AXIS, CLUTTER_Z_AXIS,
angle, angle,
@ -1877,22 +1887,22 @@ clutter_actor_get_property (GObject *object,
} }
break; break;
case PROP_SCALE_X: 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; break;
case PROP_SCALE_Y: 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; break;
case PROP_REACTIVE: case PROP_REACTIVE:
g_value_set_boolean (value, clutter_actor_get_reactive (actor)); g_value_set_boolean (value, clutter_actor_get_reactive (actor));
break; break;
case PROP_ROTATION_ANGLE_X: 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; break;
case PROP_ROTATION_ANGLE_Y: 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; break;
case PROP_ROTATION_ANGLE_Z: 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; break;
case PROP_ROTATION_CENTER_X: case PROP_ROTATION_CENTER_X:
{ {
@ -3020,8 +3030,8 @@ clutter_actor_init (ClutterActor *self)
priv->has_clip = FALSE; priv->has_clip = FALSE;
priv->opacity = 0xff; priv->opacity = 0xff;
priv->id = clutter_id_pool_add (CLUTTER_CONTEXT()->id_pool, self); priv->id = clutter_id_pool_add (CLUTTER_CONTEXT()->id_pool, self);
priv->scale_x = COGL_FIXED_1; priv->scale_x = 1.0;
priv->scale_y = COGL_FIXED_1; priv->scale_y = 1.0;
priv->shader_data = NULL; priv->shader_data = NULL;
priv->show_on_set_parent = TRUE; 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 * Applications rarely need to call this, as redraws are handled
* automatically by modification functions. * 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 void
clutter_actor_queue_redraw (ClutterActor *self) clutter_actor_queue_redraw (ClutterActor *self)
@ -3087,7 +3100,16 @@ clutter_actor_queue_redraw (ClutterActor *self)
g_return_if_fail (CLUTTER_IS_ACTOR (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) if ((stage = clutter_actor_get_stage (self)) != NULL)
clutter_stage_queue_redraw (CLUTTER_STAGE (stage)); 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)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
clutter_actor_set_scalex (self, clutter_actor_set_scalex (self,
COGL_FIXED_FROM_FLOAT (scale_x), CLUTTER_FLOAT_TO_FIXED (scale_x),
COGL_FIXED_FROM_FLOAT (scale_y)); CLUTTER_FLOAT_TO_FIXED (scale_y));
} }
/** /**
@ -4964,10 +4986,10 @@ clutter_actor_get_scale (ClutterActor *self,
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (scale_x) 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) 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)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
clutter_actor_set_rotation_internal (self, axis, clutter_actor_set_rotation_internal (self, axis,
COGL_FIXED_FROM_FLOAT (angle), CLUTTER_FLOAT_TO_FIXED (angle),
x, y, z); x, y, z);
} }
@ -5294,7 +5316,7 @@ clutter_actor_set_rotation (ClutterActor *self,
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
clutter_actor_set_rotationx (self, axis, clutter_actor_set_rotationx (self, axis,
COGL_FIXED_FROM_FLOAT (angle), CLUTTER_FLOAT_TO_FIXED (angle),
x, y, z); x, y, z);
} }
@ -5335,7 +5357,7 @@ clutter_actor_get_rotationu (ClutterActor *self,
switch (axis) switch (axis)
{ {
case CLUTTER_X_AXIS: case CLUTTER_X_AXIS:
retval = COGL_FIXED_TO_DOUBLE (priv->rxang); retval = CLUTTER_FIXED_TO_DOUBLE (priv->rxang);
if (y) if (y)
*y = priv->rxy; *y = priv->rxy;
if (z) if (z)
@ -5343,7 +5365,7 @@ clutter_actor_get_rotationu (ClutterActor *self,
break; break;
case CLUTTER_Y_AXIS: case CLUTTER_Y_AXIS:
retval = COGL_FIXED_TO_DOUBLE (priv->ryang); retval = CLUTTER_FIXED_TO_DOUBLE (priv->ryang);
if (x) if (x)
*x = priv->ryx; *x = priv->ryx;
if (z) if (z)
@ -5351,7 +5373,7 @@ clutter_actor_get_rotationu (ClutterActor *self,
break; break;
case CLUTTER_Z_AXIS: case CLUTTER_Z_AXIS:
retval = COGL_FIXED_TO_DOUBLE (priv->rzang); retval = CLUTTER_FIXED_TO_DOUBLE (priv->rzang);
if (x) if (x)
*x = priv->rzx; *x = priv->rzx;
if (y) if (y)
@ -5450,7 +5472,7 @@ clutter_actor_get_rotation (ClutterActor *self,
{ {
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.0); 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, axis,
x, y, z)); x, y, z));
} }
@ -6521,6 +6543,8 @@ parse_units (ClutterActor *self,
if (end[0] == '%' && end[1] == '\0') if (end[0] == '%' && end[1] == '\0')
{ {
ClutterActor *stage;
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL) if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)
{ {
g_warning ("Unable to set percentage of %s on a top-level " g_warning ("Unable to set percentage of %s on a top-level "
@ -6533,12 +6557,20 @@ parse_units (ClutterActor *self,
goto out; goto out;
} }
stage = clutter_actor_get_stage (self);
if (stage == NULL)
stage = clutter_stage_get_default ();
if (dimension == PARSE_X || if (dimension == PARSE_X ||
dimension == PARSE_WIDTH || dimension == PARSE_WIDTH ||
dimension == PARSE_ANCHOR_X) dimension == PARSE_ANCHOR_X)
retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val); {
retval = clutter_actor_get_widthu (stage) * val;
}
else else
retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val); {
retval = clutter_actor_get_heightu (stage) * val;
}
goto out; goto out;
} }
@ -6553,7 +6585,12 @@ parse_units (ClutterActor *self,
} }
else if (G_VALUE_HOLDS (&value, G_TYPE_DOUBLE)) 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) if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)
{ {
@ -6566,14 +6603,18 @@ parse_units (ClutterActor *self,
goto out; goto out;
} }
val = CLAMP (g_value_get_double (&value) * 100, 0, 100); val = g_value_get_double (&value);
if (dimension == PARSE_X || if (dimension == PARSE_X ||
dimension == PARSE_WIDTH || dimension == PARSE_WIDTH ||
dimension == PARSE_ANCHOR_X) dimension == PARSE_ANCHOR_X)
retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val); {
retval = clutter_actor_get_widthu (stage) * val;
}
else else
retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val); {
retval = clutter_actor_get_heightu (stage) * val;
}
} }
else else
{ {
@ -6612,7 +6653,7 @@ parse_rotation_array (ClutterActor *actor,
/* angle */ /* angle */
element = json_array_get_element (array, 0); element = json_array_get_element (array, 0);
if (JSON_NODE_TYPE (element) == JSON_NODE_VALUE) 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 else
return FALSE; return FALSE;
@ -6918,12 +6959,12 @@ clutter_actor_transform_stage_point (ClutterActor *self,
if (!du || !dv) if (!du || !dv)
return FALSE; return FALSE;
#define FP2FX COGL_FIXED_FROM_FLOAT #define FP2FX CLUTTER_FLOAT_TO_FIXED
#define FX2FP COGL_FIXED_TO_DOUBLE #define FX2FP CLUTTER_FIXED_TO_DOUBLE
#define UX2FP CLUTTER_UNITS_TO_FLOAT #define UX2FP CLUTTER_UNITS_TO_FLOAT
#define UX2FX CLUTTER_UNITS_TO_FIXED #define UX2FX CLUTTER_UNITS_TO_FIXED
#define FP2INT CLUTTER_FLOAT_TO_INT #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)) #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[2][1] = UX2FX (v[0].y);
RQ[0][2] = 0; RQ[0][2] = 0;
RQ[1][2] = 0; RQ[1][2] = 0;
RQ[2][2] = COGL_FIXED_1; RQ[2][2] = 1.0;
} }
else 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[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[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) 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) 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[2][0] = UX2FX (v[0].x);
RQ[0][1] = UX2FX (v[1].y - v[0].y) 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) 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); RQ[2][1] = UX2FX (v[0].y);
} }
@ -7017,9 +7058,9 @@ clutter_actor_transform_stage_point (ClutterActor *self,
/* /*
* Check the resutling martix is OK. * Check the resutling martix is OK.
*/ */
det = COGL_FIXED_MUL (RQ[0][0], ST[0][0]) det = CLUTTER_FIXED_MUL (RQ[0][0], ST[0][0])
+ COGL_FIXED_MUL (RQ[0][1], ST[0][1]) + CLUTTER_FIXED_MUL (RQ[0][1], ST[0][1])
+ COGL_FIXED_MUL (RQ[0][2], ST[0][2]); + CLUTTER_FIXED_MUL (RQ[0][2], ST[0][2]);
if (!det) if (!det)
return FALSE; return FALSE;
@ -7481,7 +7522,7 @@ clutter_actor_is_scaled (ClutterActor *self)
priv = self->priv; 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 TRUE;
return FALSE; return FALSE;

View File

@ -74,10 +74,10 @@ G_BEGIN_DECLS
*/ */
#define CLUTTER_ACTOR_UNSET_FLAGS(a,f) (((ClutterActor*)(a))->flags &= ~(f)) #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_MAPPED(e) ((((ClutterActor*)(e))->flags & CLUTTER_ACTOR_MAPPED) != FALSE)
#define CLUTTER_ACTOR_IS_REALIZED(e) (((ClutterActor*)(e))->flags & CLUTTER_ACTOR_REALIZED) #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_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 _ClutterActorClass ClutterActorClass;
typedef struct _ClutterActorBox ClutterActorBox; typedef struct _ClutterActorBox ClutterActorBox;

View File

@ -40,11 +40,15 @@
* alpha value into something meaningful for a #ClutterActor. * alpha value into something meaningful for a #ClutterActor.
* *
* You should provide a #ClutterTimeline and bind it to the #ClutterAlpha * You should provide a #ClutterTimeline and bind it to the #ClutterAlpha
* instance using clutter_alpha_set_timeline(); you should also provide a * instance using clutter_alpha_set_timeline(). You should also set an
* function returning the alpha value depending on the progress of the * "animation mode", either by using the #ClutterAnimatioMode values that
* timeline, using clutter_alpha_set_func() or clutter_alpha_set_closure(). * Clutter itself provides or by registering custom functions.
* The alpha function will be executed each time a new frame in the *
* #ClutterTimeline is reached. * 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 * Since the alpha function is controlled by the timeline instance, you can
* pause, stop or resume the #ClutterAlpha from calling the alpha function by * pause, stop or resume the #ClutterAlpha from calling the alpha function by
@ -85,7 +89,7 @@ struct _ClutterAlphaPrivate
GClosure *closure; GClosure *closure;
ClutterAnimationMode mode; gulong mode;
}; };
enum enum
@ -126,9 +130,11 @@ clutter_alpha_set_property (GObject *object,
case PROP_TIMELINE: case PROP_TIMELINE:
clutter_alpha_set_timeline (alpha, g_value_get_object (value)); clutter_alpha_set_timeline (alpha, g_value_get_object (value));
break; break;
case PROP_MODE: case PROP_MODE:
clutter_alpha_set_mode (alpha, g_value_get_enum (value)); clutter_alpha_set_mode (alpha, g_value_get_ulong (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -152,12 +158,15 @@ clutter_alpha_get_property (GObject *object,
case PROP_TIMELINE: case PROP_TIMELINE:
g_value_set_object (value, priv->timeline); g_value_set_object (value, priv->timeline);
break; break;
case PROP_ALPHA: case PROP_ALPHA:
g_value_set_uint (value, priv->alpha); g_value_set_uint (value, priv->alpha);
break; break;
case PROP_MODE: case PROP_MODE:
g_value_set_enum (value, priv->mode); g_value_set_ulong (value, priv->mode);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -231,22 +240,25 @@ clutter_alpha_class_init (ClutterAlphaClass *klass)
/** /**
* ClutterAlpha:mode: * ClutterAlpha:mode:
* *
* The progress function as a #ClutterAnimationMode enumeration * The progress function logical id - either a value from the
* value. If %CLUTTER_CUSTOM_MODE is used then the function set * #ClutterAnimationMode enumeration or a value returned by
* using clutter_alpha_set_closure() or clutter_alpha_set_func() * 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. * will be used.
* *
* Since: 1.0 * Since: 1.0
*/ */
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
PROP_MODE, PROP_MODE,
g_param_spec_enum ("mode", g_param_spec_ulong ("mode",
"Mode", "Mode",
"Progress mode", "Progress mode",
CLUTTER_TYPE_ANIMATION_MODE, 0, G_MAXULONG,
CLUTTER_CUSTOM_MODE, CLUTTER_CUSTOM_MODE,
G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT |
CLUTTER_PARAM_READWRITE)); CLUTTER_PARAM_READWRITE));
} }
static void static void
@ -313,9 +325,8 @@ clutter_alpha_get_alpha (ClutterAlpha *alpha)
* @alpha: A #ClutterAlpha * @alpha: A #ClutterAlpha
* @closure: A #GClosure * @closure: A #GClosure
* *
* Sets the #GClosure used to compute * Sets the #GClosure used to compute the alpha value at each
* the alpha value at each frame of the #ClutterTimeline * frame of the #ClutterTimeline bound to @alpha.
* bound to @alpha.
* *
* Since: 0.8 * Since: 0.8
*/ */
@ -358,6 +369,8 @@ clutter_alpha_set_closure (ClutterAlpha *alpha,
* the alpha value at each frame of the #ClutterTimeline * the alpha value at each frame of the #ClutterTimeline
* bound to @alpha. * bound to @alpha.
* *
* This function will not register @func as a global alpha function.
*
* Since: 0.2 * Since: 0.2
*/ */
void void
@ -462,22 +475,53 @@ clutter_alpha_new (void)
/** /**
* clutter_alpha_new_full: * clutter_alpha_new_full:
* @timeline: #ClutterTimeline timeline * @timeline: #ClutterTimeline timeline
* @func: #ClutterAlphaFunc alpha function * @mode: animation mode
* @data: data to be passed to the alpha function
* @destroy: notify to be called when removing the alpha function
* *
* Creates a new #ClutterAlpha instance and sets the timeline * 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 * Return Value: the newly created #ClutterAlpha
* *
* Since: 0.2 * Since: 1.0
*/ */
ClutterAlpha * ClutterAlpha *
clutter_alpha_new_full (ClutterTimeline *timeline, clutter_alpha_new_full (ClutterTimeline *timeline,
ClutterAlphaFunc func, gulong mode)
gpointer data, {
GDestroyNotify destroy) 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; ClutterAlpha *retval;
@ -485,32 +529,12 @@ clutter_alpha_new_full (ClutterTimeline *timeline,
g_return_val_if_fail (func != NULL, NULL); g_return_val_if_fail (func != NULL, NULL);
retval = clutter_alpha_new (); retval = clutter_alpha_new ();
clutter_alpha_set_timeline (retval, timeline); clutter_alpha_set_timeline (retval, timeline);
clutter_alpha_set_func (retval, func, data, destroy); clutter_alpha_set_func (retval, func, data, destroy);
return retval; 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: * clutter_alpha_get_mode:
* @alpha: a #ClutterAlpha * @alpha: a #ClutterAlpha
@ -521,7 +545,7 @@ clutter_alpha_new_for_mode (ClutterAnimationMode mode)
* *
* Since: 1.0 * Since: 1.0
*/ */
ClutterAnimationMode gulong
clutter_alpha_get_mode (ClutterAlpha *alpha) clutter_alpha_get_mode (ClutterAlpha *alpha)
{ {
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), CLUTTER_CUSTOM_MODE); 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; 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 { static const struct {
ClutterAnimationMode mode; gulong mode;
ClutterAlphaFunc func; ClutterAlphaFunc func;
} animation_modes[] = { } animation_modes[] = {
{ CLUTTER_CUSTOM_MODE, NULL }, { CLUTTER_CUSTOM_MODE, NULL },
@ -545,46 +573,161 @@ static const struct {
{ CLUTTER_EXPO_IN, clutter_exp_in_func }, { CLUTTER_EXPO_IN, clutter_exp_in_func },
{ CLUTTER_EXPO_OUT, clutter_exp_out_func }, { CLUTTER_EXPO_OUT, clutter_exp_out_func },
{ CLUTTER_EXPO_IN_OUT, clutter_exp_in_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: * clutter_alpha_set_mode:
* @alpha: a #ClutterAlpha * @alpha: a #ClutterAlpha
* @mode: a #ClutterAnimationMode * @mode: a #ClutterAnimationMode
* *
* Sets the progress function of @alpha using the symbolic value * 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 * Since: 1.0
*/ */
void void
clutter_alpha_set_mode (ClutterAlpha *alpha, clutter_alpha_set_mode (ClutterAlpha *alpha,
ClutterAnimationMode mode) gulong mode)
{ {
ClutterAlphaPrivate *priv; ClutterAlphaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ALPHA (alpha)); g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
g_return_if_fail (mode != CLUTTER_ANIMATION_LAST);
priv = alpha->priv; priv = alpha->priv;
/* sanity check to avoid getting an out of sync enum/function mapping */ if (mode < CLUTTER_ANIMATION_LAST)
g_assert (animation_modes[mode].mode == mode); {
if (G_LIKELY (animation_modes[mode].func != NULL)) /* sanity check to avoid getting an out of sync
clutter_alpha_set_func (alpha, animation_modes[mode].func, NULL, NULL); * 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"); 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: * 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 static guint32
sincx1024_func (ClutterAlpha *alpha, sincx1024_func (ClutterAlpha *alpha,
ClutterAngle angle, float angle,
ClutterFixed offset) ClutterFixed offset)
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
gint current_frame_num, n_frames; gint current_frame_num, n_frames;
ClutterAngle x; float x;
ClutterFixed sine; ClutterFixed sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
@ -724,11 +872,6 @@ sincx1024_func (ClutterAlpha *alpha,
return sine; return sine;
} }
#if 0
/*
* The following two functions are left in place for reference
* purposes.
*/
static guint32 static guint32
sincx_func (ClutterAlpha *alpha, sincx_func (ClutterAlpha *alpha,
ClutterFixed angle, ClutterFixed angle,
@ -744,14 +887,14 @@ sincx_func (ClutterAlpha *alpha,
n_frames = clutter_timeline_get_n_frames (timeline); n_frames = clutter_timeline_get_n_frames (timeline);
x = angle * current_frame_num / n_frames; x = angle * current_frame_num / n_frames;
x = COGL_FIXED_FAST_MUL (x, COGL_FIXED_PI) x = CLUTTER_FIXED_MUL (x, CFX_PI)
- COGL_FIXED_FAST_DIV (COGL_FIXED_PI, angle); - 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 /* 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, clutter_sine_func (ClutterAlpha *alpha,
gpointer dummy) 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); return sinc_func (alpha, 2.0, 1.0);
#else #elif 0
/* 2.0 above represents full circle */ /* 2.0 above represents full circle */
return sincx1024_func (alpha, 1024, COGL_FIXED_1); return sincx1024_func (alpha, 1024, 1.0);
#endif #endif
} }
@ -842,18 +1004,17 @@ clutter_sine_inc_func (ClutterAlpha *alpha,
ClutterTimeline * timeline; ClutterTimeline * timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
ClutterAngle x; float radians;
ClutterFixed sine; float sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (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 * CLUTTER_ALPHA_MAX_ALPHA);
return ((guint32) sine) >> COGL_FIXED_Q;
} }
/** /**
@ -884,18 +1045,17 @@ clutter_sine_dec_func (ClutterAlpha *alpha,
ClutterTimeline * timeline; ClutterTimeline * timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
ClutterAngle x; float radians;
ClutterFixed sine; float sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (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 * CLUTTER_ALPHA_MAX_ALPHA);
return ((guint32) sine) >> COGL_FIXED_Q;
} }
/** /**
@ -926,18 +1086,17 @@ clutter_sine_half_func (ClutterAlpha *alpha,
ClutterTimeline *timeline; ClutterTimeline *timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
ClutterAngle x; float radians;
ClutterFixed sine; float sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (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 * CLUTTER_ALPHA_MAX_ALPHA);
return ((guint32) sine) >> COGL_FIXED_Q;
} }
/** /**
@ -962,19 +1121,20 @@ clutter_sine_in_func (ClutterAlpha *alpha,
ClutterTimeline *timeline; ClutterTimeline *timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
ClutterAngle x; float radians;
ClutterFixed sine; float sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (timeline); n_frames = clutter_timeline_get_n_frames (timeline);
/* XXX- if we use 768 we overflow */ radians = ((float)frame / n_frames) * (G_PI / 2);
x = 256 * frame / n_frames + 767; 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; ClutterTimeline *timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
ClutterAngle x; float radians;
ClutterFixed sine; float sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (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 * CLUTTER_ALPHA_MAX_ALPHA);
return ((guint32) sine) >> COGL_FIXED_Q;
} }
/** /**
@ -1034,18 +1193,20 @@ clutter_sine_in_out_func (ClutterAlpha *alpha,
ClutterTimeline *timeline; ClutterTimeline *timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
ClutterAngle x; float radians;
ClutterFixed sine; float sine;
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (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; ClutterTimeline *timeline;
gint frame; gint frame;
gint n_frames; gint n_frames;
guint32 r; float r;
guint32 x; float x;
/* /*
* The smoothstep function uses f(x) = -2x^3 + 3x^2 where x is from <0,1>, * 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. * and precission is critical.
* The earlier operations involve division, which we cannot do in 8.24 for
* numbers in <0,1> we use ClutterFixed.
*/ */
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (timeline); n_frames = clutter_timeline_get_n_frames (timeline);
/* x = (float)frame / n_frames;
* Convert x to 8.24 for next step.
*/
x = COGL_FIXED_FAST_DIV (frame, n_frames) << 8;
/* /*
* f(x) = -2x^3 + 3x^2 * 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 * (2^x_alpha_max) - 1 == CLUTTER_ALPHA_MAX_ALPHA
*/ */
#if CLUTTER_ALPHA_MAX_ALPHA != 0xffff /* XXX: If this fails:
#error Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA * Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA */
#endif g_assert (CLUTTER_ALPHA_MAX_ALPHA == 65535.0);
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); frame = clutter_timeline_get_current_frame (timeline);
@ -1214,7 +1368,7 @@ clutter_exp_inc_func (ClutterAlpha *alpha,
x = x_alpha_max * frame / n_frames; 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; return result;
} }
@ -1255,9 +1409,9 @@ clutter_exp_dec_func (ClutterAlpha *alpha,
* *
* (2^x_alpha_max) - 1 == CLUTTER_ALPHA_MAX_ALPHA * (2^x_alpha_max) - 1 == CLUTTER_ALPHA_MAX_ALPHA
*/ */
#if CLUTTER_ALPHA_MAX_ALPHA != 0xffff /* XXX: If this fails:
#error Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA * Adjust x_alpha_max to match CLUTTER_ALPHA_MAX_ALPHA */
#endif g_assert (CLUTTER_ALPHA_MAX_ALPHA == 65535.0);
timeline = clutter_alpha_get_timeline (alpha); timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline); 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; 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; return result;
} }

View File

@ -31,7 +31,6 @@
#ifndef __CLUTTER_ALPHA_H__ #ifndef __CLUTTER_ALPHA_H__
#define __CLUTTER_ALPHA_H__ #define __CLUTTER_ALPHA_H__
#include <clutter/clutter-fixed.h>
#include <clutter/clutter-timeline.h> #include <clutter/clutter-timeline.h>
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
@ -106,31 +105,35 @@ struct _ClutterAlphaClass
* *
* Since: 0.2 * 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; GType clutter_alpha_get_type (void) G_GNUC_CONST;
ClutterAlpha * clutter_alpha_new (void); ClutterAlpha * clutter_alpha_new (void);
ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline, ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline,
ClutterAlphaFunc func, gulong mode);
gpointer data, ClutterAlpha * clutter_alpha_new_with_func (ClutterTimeline *timeline,
GDestroyNotify destroy); 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); gulong clutter_alpha_register_func (ClutterAlphaFunc func,
void clutter_alpha_set_func (ClutterAlpha *alpha, gpointer data);
ClutterAlphaFunc func, gulong clutter_alpha_register_closure (GClosure *closure);
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);
/* convenience functions */ /* convenience functions */
guint32 clutter_ramp_inc_func (ClutterAlpha *alpha, guint32 clutter_ramp_inc_func (ClutterAlpha *alpha,

View File

@ -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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* 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 #GValue<!-- -->s 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);
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_ANIMATABLE_H__
#define __CLUTTER_ANIMATABLE_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-animation.h>
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 #GObject<!-- -->s 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__ */

View File

@ -27,12 +27,12 @@
* @short_description: Simple implicit animations * @short_description: Simple implicit animations
* *
* #ClutterAnimation is an object providing simple, implicit animations * #ClutterAnimation is an object providing simple, implicit animations
* for #ClutterActor<!-- -->s. * for #GObject<!-- -->s.
* *
* #ClutterAnimation instances will bind a #GObject property belonging * #ClutterAnimation instances will bind a #GObject property belonging
* to a #ClutterActor to a #ClutterInterval, and will then use a * to a #GObject to a #ClutterInterval, and will then use a #ClutterTimeline
* #ClutterTimeline to interpolate the property between the initial * to interpolate the property between the initial and final values of the
* and final values of the interval. * interval.
* *
* For convenience, it is possible to use the clutter_actor_animate() * For convenience, it is possible to use the clutter_actor_animate()
* function call which will take care of setting up and tearing down * function call which will take care of setting up and tearing down
@ -50,6 +50,7 @@
#include <gobject/gvaluecollector.h> #include <gobject/gvaluecollector.h>
#include "clutter-alpha.h" #include "clutter-alpha.h"
#include "clutter-animatable.h"
#include "clutter-animation.h" #include "clutter-animation.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
@ -60,7 +61,7 @@ enum
{ {
PROP_0, PROP_0,
PROP_ACTOR, PROP_OBJECT,
PROP_MODE, PROP_MODE,
PROP_DURATION, PROP_DURATION,
PROP_LOOP, PROP_LOOP,
@ -79,11 +80,11 @@ enum
struct _ClutterAnimationPrivate struct _ClutterAnimationPrivate
{ {
ClutterActor *actor; GObject *object;
GHashTable *properties; GHashTable *properties;
ClutterAnimationMode mode; gulong mode;
guint loop : 1; guint loop : 1;
guint duration; guint duration;
@ -96,7 +97,7 @@ struct _ClutterAnimationPrivate
static guint animation_signals[LAST_SIGNAL] = { 0, }; 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); 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; ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv;
if (priv->actor) if (priv->object)
{ {
g_object_weak_unref (G_OBJECT (gobject), g_object_weak_unref (G_OBJECT (gobject),
on_animation_weak_notify, on_animation_weak_notify,
priv->actor); priv->object);
g_object_set_qdata (G_OBJECT (priv->actor), g_object_set_qdata (priv->object, quark_object_animation, NULL);
quark_actor_animation, g_object_unref (priv->object);
NULL); priv->object = NULL;
g_object_unref (priv->actor);
priv->actor = NULL;
} }
if (priv->timeline) if (priv->timeline)
@ -168,12 +167,12 @@ clutter_animation_set_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_ACTOR: case PROP_OBJECT:
clutter_animation_set_actor (animation, g_value_get_object (value)); clutter_animation_set_object (animation, g_value_get_object (value));
break; break;
case PROP_MODE: case PROP_MODE:
clutter_animation_set_mode (animation, g_value_get_enum (value)); clutter_animation_set_mode (animation, g_value_get_ulong (value));
break; break;
case PROP_DURATION: case PROP_DURATION:
@ -208,12 +207,12 @@ clutter_animation_get_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_ACTOR: case PROP_OBJECT:
g_value_set_object (value, priv->actor); g_value_set_object (value, priv->object);
break; break;
case PROP_MODE: case PROP_MODE:
g_value_set_enum (value, priv->mode); g_value_set_ulong (value, priv->mode);
break; break;
case PROP_DURATION: case PROP_DURATION:
@ -253,7 +252,7 @@ clutter_animation_class_init (ClutterAnimationClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
quark_actor_animation = quark_object_animation =
g_quark_from_static_string ("clutter-actor-animation"); g_quark_from_static_string ("clutter-actor-animation");
g_type_class_add_private (klass, sizeof (ClutterAnimationPrivate)); g_type_class_add_private (klass, sizeof (ClutterAnimationPrivate));
@ -266,32 +265,34 @@ clutter_animation_class_init (ClutterAnimationClass *klass)
gobject_class->finalize = clutter_animation_finalize; 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 * Since: 1.0
*/ */
pspec = g_param_spec_object ("actor", pspec = g_param_spec_object ("object",
"Actor", "Object",
"Actor to which the animation applies", "Object to which the animation applies",
CLUTTER_TYPE_ACTOR, G_TYPE_OBJECT,
CLUTTER_PARAM_READWRITE); 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: * 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 * Since: 1.0
*/ */
pspec = g_param_spec_enum ("mode", pspec = g_param_spec_ulong ("mode",
"Mode", "Mode",
"The mode of the animation", "The mode of the animation",
CLUTTER_TYPE_ANIMATION_MODE, 0, G_MAXULONG,
CLUTTER_LINEAR, CLUTTER_LINEAR,
CLUTTER_PARAM_READWRITE); CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_MODE, pspec); 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 * @property_name: the property to control
* @interval: a #ClutterInterval * @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 * attached to @animation. The #ClutterAnimation will take
* ownership of the passed #ClutterInterval. * ownership of the passed #ClutterInterval.
* *
@ -451,10 +452,10 @@ clutter_animation_bind_property (ClutterAnimation *animation,
priv = animation->priv; priv = animation->priv;
if (G_UNLIKELY (!priv->actor)) if (G_UNLIKELY (!priv->object))
{ {
g_warning ("Cannot bind property `%s': the animation has no " 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", "first to be able to bind a property",
property_name); property_name);
return; return;
@ -468,14 +469,14 @@ clutter_animation_bind_property (ClutterAnimation *animation,
return; return;
} }
klass = G_OBJECT_GET_CLASS (priv->actor); klass = G_OBJECT_GET_CLASS (priv->object);
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec) 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", "no such property",
property_name, property_name,
g_type_name (G_OBJECT_TYPE (priv->actor))); g_type_name (G_OBJECT_TYPE (priv->object)));
return; return;
} }
@ -592,14 +593,14 @@ clutter_animation_update_property (ClutterAnimation *animation,
return; return;
} }
klass = G_OBJECT_GET_CLASS (priv->actor); klass = G_OBJECT_GET_CLASS (priv->object);
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec) 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", "no such property",
property_name, property_name,
g_type_name (G_OBJECT_TYPE (priv->actor))); g_type_name (G_OBJECT_TYPE (priv->object)));
return; return;
} }
@ -664,10 +665,18 @@ on_alpha_notify (GObject *gobject,
ClutterAnimationPrivate *priv = animation->priv; ClutterAnimationPrivate *priv = animation->priv;
GList *properties, *p; GList *properties, *p;
guint32 alpha_value; guint32 alpha_value;
gboolean is_animatable = FALSE;
ClutterAnimatable *animatable = NULL;
alpha_value = clutter_alpha_get_alpha (CLUTTER_ALPHA (gobject)); 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); properties = g_hash_table_get_keys (priv->properties);
for (p = properties; p != NULL; p = p->next) 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)); g_value_init (&value, clutter_interval_get_value_type (interval));
factor = (gdouble) alpha_value / CLUTTER_ALPHA_MAX_ALPHA; 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_value_unset (&value);
} }
g_list_free (properties); 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)), clutter_actor_get_gid (CLUTTER_ACTOR (actor)),
actor); actor);
g_object_set_qdata (actor, quark_actor_animation, NULL); g_object_set_qdata (actor, quark_object_animation, NULL);
} }
ClutterAnimation * ClutterAnimation *
@ -719,66 +749,64 @@ clutter_animation_new (void)
} }
/** /**
* clutter_animation_set_actor: * clutter_animation_set_object:
* @animation: a #ClutterAnimation * @animation: a #ClutterAnimation
* @actor: a #ClutterActor * @object: a #GObject
* *
* Attaches @animation to @actor. The #ClutterAnimation will take a * Attaches @animation to @object. The #ClutterAnimation will take a
* reference on @actor. * reference on @object.
* *
* Since: 1.0 * Since: 1.0
*/ */
void void
clutter_animation_set_actor (ClutterAnimation *animation, clutter_animation_set_object (ClutterAnimation *animation,
ClutterActor *actor) GObject *object)
{ {
ClutterAnimationPrivate *priv; ClutterAnimationPrivate *priv;
g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); 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; priv = animation->priv;
g_object_ref (actor); g_object_ref (object);
if (priv->actor) if (priv->object)
{ {
g_object_weak_unref (G_OBJECT (animation), g_object_weak_unref (G_OBJECT (animation),
on_animation_weak_notify, on_animation_weak_notify,
priv->actor); priv->object);
g_object_set_qdata (G_OBJECT (priv->actor), g_object_set_qdata (priv->object, quark_object_animation, NULL);
quark_actor_animation, g_object_unref (priv->object);
NULL);
g_object_unref (priv->actor);
} }
priv->actor = actor; priv->object = object;
g_object_weak_ref (G_OBJECT (animation), g_object_weak_ref (G_OBJECT (animation),
on_animation_weak_notify, on_animation_weak_notify,
priv->actor); priv->object);
g_object_set_qdata (G_OBJECT (priv->actor), g_object_set_qdata (G_OBJECT (priv->object),
quark_actor_animation, quark_object_animation,
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 * @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 * Since: 1.0
*/ */
ClutterActor * GObject *
clutter_animation_get_actor (ClutterAnimation *animation) clutter_animation_get_object (ClutterAnimation *animation)
{ {
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL);
return animation->priv->actor; return animation->priv->object;
} }
static inline void static inline void
@ -794,15 +822,17 @@ clutter_animation_set_mode_internal (ClutterAnimation *animation,
/** /**
* clutter_animation_set_mode: * clutter_animation_set_mode:
* @animation: a #ClutterAnimation * @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 * Since: 1.0
*/ */
void void
clutter_animation_set_mode (ClutterAnimation *animation, clutter_animation_set_mode (ClutterAnimation *animation,
ClutterAnimationMode mode) gulong mode)
{ {
ClutterAnimationPrivate *priv; ClutterAnimationPrivate *priv;
@ -820,13 +850,14 @@ clutter_animation_set_mode (ClutterAnimation *animation,
* clutter_animation_get_mode: * clutter_animation_get_mode:
* @animation: a #ClutterAnimation * @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 * Since: 1.0
*/ */
ClutterAnimationMode gulong
clutter_animation_get_mode (ClutterAnimation *animation) clutter_animation_get_mode (ClutterAnimation *animation)
{ {
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), CLUTTER_LINEAR); g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), CLUTTER_LINEAR);
@ -1125,7 +1156,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
GObjectClass *klass; GObjectClass *klass;
const gchar *property_name; const gchar *property_name;
klass = G_OBJECT_GET_CLASS (priv->actor); klass = G_OBJECT_GET_CLASS (priv->object);
property_name = first_property_name; property_name = first_property_name;
while (property_name != NULL) while (property_name != NULL)
@ -1145,10 +1176,10 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec) 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", "not have this property",
property_name, property_name,
g_type_name (G_OBJECT_TYPE (priv->actor))); g_type_name (G_OBJECT_TYPE (priv->object)));
break; break;
} }
@ -1178,9 +1209,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
GValue initial = { 0, }; GValue initial = { 0, };
g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_object_get_property (G_OBJECT (priv->actor), g_object_get_property (priv->object, property_name, &initial);
property_name,
&initial);
interval = interval =
clutter_interval_new_with_values (G_PARAM_SPEC_VALUE_TYPE (pspec), 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); g_value_unset (&initial);
} }
else 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); g_value_unset (&final);
@ -1254,7 +1283,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
return NULL; 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)) if (G_LIKELY (!animation))
{ {
animation = clutter_animation_new (); animation = clutter_animation_new ();
@ -1265,7 +1294,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
clutter_animation_set_timeline (animation, timeline); clutter_animation_set_timeline (animation, timeline);
clutter_animation_set_alpha (animation, alpha); 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); va_start (args, first_property_name);
clutter_animation_setup_valist (animation, first_property_name, args); 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: * clutter_actor_animate_with_timeline:
* @actor: a #ClutterActor * @actor: a #ClutterActor
* @mode: a #ClutterAnimationMode value * @mode: an animation mode logical id
* @timeline: a #ClutterTimeline * @timeline: a #ClutterTimeline
* @first_property_name: the name of a property * @first_property_name: the name of a property
* @VarArgs: a %NULL terminated list of property names and * @VarArgs: a %NULL terminated list of property names and
@ -1298,10 +1327,10 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
* Since: 1.0 * Since: 1.0
*/ */
ClutterAnimation * ClutterAnimation *
clutter_actor_animate_with_timeline (ClutterActor *actor, clutter_actor_animate_with_timeline (ClutterActor *actor,
ClutterAnimationMode mode, gulong mode,
ClutterTimeline *timeline, ClutterTimeline *timeline,
const gchar *first_property_name, const gchar *first_property_name,
...) ...)
{ {
ClutterAnimation *animation; 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 (CLUTTER_IS_TIMELINE (timeline), NULL);
g_return_val_if_fail (first_property_name != NULL, 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 (G_LIKELY (!animation))
{ {
animation = clutter_animation_new (); animation = clutter_animation_new ();
@ -1323,7 +1352,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
clutter_animation_set_timeline (animation, timeline); clutter_animation_set_timeline (animation, timeline);
clutter_animation_set_alpha (animation, NULL); clutter_animation_set_alpha (animation, NULL);
clutter_animation_set_mode (animation, mode); 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); va_start (args, first_property_name);
clutter_animation_setup_valist (animation, first_property_name, args); clutter_animation_setup_valist (animation, first_property_name, args);
@ -1335,7 +1364,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
/** /**
* clutter_actor_animate: * clutter_actor_animate:
* @actor: a #ClutterActor * @actor: a #ClutterActor
* @mode: a #ClutterAnimationMode value * @mode: an animation mode logical id
* @duration: duration of the animation, in milliseconds * @duration: duration of the animation, in milliseconds
* @first_property_name: the name of a property * @first_property_name: the name of a property
* @VarArgs: a %NULL terminated list of property names and * @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" * will make width and height properties of the #ClutterActor "rectangle"
* grow linearly between the current value and 100 pixels, in 250 milliseconds. * 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 * 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 * 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 * 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 * Since: 1.0
*/ */
ClutterAnimation * ClutterAnimation *
clutter_actor_animate (ClutterActor *actor, clutter_actor_animate (ClutterActor *actor,
ClutterAnimationMode mode, gulong mode,
guint duration, guint duration,
const gchar *first_property_name, const gchar *first_property_name,
...) ...)
{ {
ClutterAnimation *animation; ClutterAnimation *animation;
@ -1406,7 +1438,7 @@ clutter_actor_animate (ClutterActor *actor,
g_return_val_if_fail (duration > 0, NULL); g_return_val_if_fail (duration > 0, NULL);
g_return_val_if_fail (first_property_name != NULL, 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 (G_LIKELY (!animation))
{ {
/* if there is no animation already attached to the actor, /* if there is no animation already attached to the actor,
@ -1416,7 +1448,7 @@ clutter_actor_animate (ClutterActor *actor,
animation = clutter_animation_new (); animation = clutter_animation_new ();
clutter_animation_set_timeline (animation, NULL); clutter_animation_set_timeline (animation, NULL);
clutter_animation_set_alpha (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); CLUTTER_NOTE (ANIMATION, "Created new Animation [%p]", animation);
} }

View File

@ -97,12 +97,12 @@ GType clutter_animation_get_type (void) G_GNUC_CONST;
ClutterAnimation * clutter_animation_new (void); ClutterAnimation * clutter_animation_new (void);
void clutter_animation_set_actor (ClutterAnimation *animation, void clutter_animation_set_object (ClutterAnimation *animation,
ClutterActor *actor); GObject *object);
ClutterActor * clutter_animation_get_actor (ClutterAnimation *animation); GObject * clutter_animation_get_object (ClutterAnimation *animation);
void clutter_animation_set_mode (ClutterAnimation *animation, void clutter_animation_set_mode (ClutterAnimation *animation,
ClutterAnimationMode mode); gulong mode);
ClutterAnimationMode clutter_animation_get_mode (ClutterAnimation *animation); gulong clutter_animation_get_mode (ClutterAnimation *animation);
void clutter_animation_set_duration (ClutterAnimation *animation, void clutter_animation_set_duration (ClutterAnimation *animation,
gint msecs); gint msecs);
guint clutter_animation_get_duration (ClutterAnimation *animation); guint clutter_animation_get_duration (ClutterAnimation *animation);
@ -130,12 +130,12 @@ ClutterInterval *clutter_animation_get_interval (ClutterAnimation *an
const gchar *property_name); const gchar *property_name);
ClutterAnimation * clutter_actor_animate (ClutterActor *actor, ClutterAnimation * clutter_actor_animate (ClutterActor *actor,
ClutterAnimationMode mode, gulong mode,
guint duration, guint duration,
const gchar *first_property_name, const gchar *first_property_name,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor, ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor,
ClutterAnimationMode mode, gulong mode,
ClutterTimeline *timeline, ClutterTimeline *timeline,
const gchar *first_property_name, const gchar *first_property_name,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;

View File

@ -60,7 +60,8 @@ struct _ClutterBackendPrivate
guint double_click_time; guint double_click_time;
guint double_click_distance; guint double_click_distance;
ClutterFixed resolution; gdouble resolution;
gdouble units_per_em;
cairo_font_options_t *font_options; cairo_font_options_t *font_options;
@ -87,7 +88,9 @@ clutter_backend_dispose (GObject *gobject)
if (clutter_context && clutter_context->events_queue) 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); g_queue_free (clutter_context->events_queue);
clutter_context->events_queue = NULL; clutter_context->events_queue = NULL;
} }
@ -99,6 +102,57 @@ clutter_backend_dispose (GObject *gobject)
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (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 static void
clutter_backend_class_init (ClutterBackendClass *klass) clutter_backend_class_init (ClutterBackendClass *klass)
{ {
@ -111,7 +165,7 @@ clutter_backend_class_init (ClutterBackendClass *klass)
backend_signals[RESOLUTION_CHANGED] = backend_signals[RESOLUTION_CHANGED] =
g_signal_new (I_("resolution-changed"), g_signal_new (I_("resolution-changed"),
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed), G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed),
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
@ -120,11 +174,14 @@ clutter_backend_class_init (ClutterBackendClass *klass)
backend_signals[FONT_CHANGED] = backend_signals[FONT_CHANGED] =
g_signal_new (I_("font-changed"), g_signal_new (I_("font-changed"),
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ClutterBackendClass, font_changed), G_STRUCT_OFFSET (ClutterBackendClass, font_changed),
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
klass->resolution_changed = clutter_backend_real_resolution_changed;
klass->font_changed = clutter_backend_real_font_changed;
} }
static void static void
@ -132,8 +189,10 @@ clutter_backend_init (ClutterBackend *backend)
{ {
ClutterBackendPrivate *priv; ClutterBackendPrivate *priv;
priv = backend->priv = CLUTTER_BACKEND_GET_PRIVATE(backend); priv = backend->priv = CLUTTER_BACKEND_GET_PRIVATE (backend);
priv->resolution = -1.0; priv->resolution = -1.0;
priv->units_per_em = -1.0;
} }
void void
@ -289,15 +348,30 @@ _clutter_backend_init_events (ClutterBackend *backend)
klass->init_events (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: * 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 * Return value: the default backend. You should not ref or
* unref the returned object. Applications should not rarely need * unref the returned object. Applications should rarely need
* to use this. * to use this.
* *
* Since: 0.4 * Since: 0.4
*/ */
@ -406,19 +480,16 @@ void
clutter_backend_set_resolution (ClutterBackend *backend, clutter_backend_set_resolution (ClutterBackend *backend,
gdouble dpi) gdouble dpi)
{ {
ClutterFixed fixed_dpi;
ClutterBackendPrivate *priv; ClutterBackendPrivate *priv;
g_return_if_fail (CLUTTER_IS_BACKEND (backend)); g_return_if_fail (CLUTTER_IS_BACKEND (backend));
priv = backend->priv;
if (dpi < 0) if (dpi < 0)
dpi = -1.0; dpi = -1.0;
priv = backend->priv; priv->resolution = dpi;
fixed_dpi = COGL_FIXED_FROM_FLOAT (dpi);
if (priv->resolution != fixed_dpi)
priv->resolution = fixed_dpi;
if (CLUTTER_CONTEXT ()->font_map) if (CLUTTER_CONTEXT ()->font_map)
cogl_pango_font_map_set_resolution (CLUTTER_CONTEXT ()->font_map, dpi); 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); g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), -1.0);
return COGL_FIXED_TO_FLOAT (backend->priv->resolution); return backend->priv->resolution;
} }
/** /**

View File

@ -83,9 +83,9 @@ clutter_behaviour_depth_alpha_notify (ClutterBehaviour *behaviour,
priv = CLUTTER_BEHAVIOUR_DEPTH (behaviour)->priv; priv = CLUTTER_BEHAVIOUR_DEPTH (behaviour)->priv;
/* Need to create factor as to avoid borking signedness */ /* 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 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); CLUTTER_NOTE (BEHAVIOUR, "alpha: %d, depth: %d", alpha_value, depth);

View File

@ -86,11 +86,11 @@ struct _ClutterBehaviourEllipsePrivate
gint a; gint a;
gint b; gint b;
ClutterAngle angle_start; float angle_start;
ClutterAngle angle_end; float angle_end;
ClutterAngle angle_tilt_x; float angle_tilt_x;
ClutterAngle angle_tilt_y; float angle_tilt_y;
ClutterAngle angle_tilt_z; float angle_tilt_z;
ClutterRotateDirection direction; ClutterRotateDirection direction;
}; };
@ -104,14 +104,14 @@ typedef struct _knot3d
static void static void
clutter_behaviour_ellipse_advance (ClutterBehaviourEllipse *e, clutter_behaviour_ellipse_advance (ClutterBehaviourEllipse *e,
ClutterAngle angle, float angle,
knot3d *knot) knot3d *knot)
{ {
ClutterBehaviourEllipsePrivate *priv = e->priv; ClutterBehaviourEllipsePrivate *priv = e->priv;
gint x, y, z; gint x, y, z;
x = COGL_FIXED_TO_INT (priv->a * cogl_angle_cos (angle)); x = (priv->a * cosf (angle * (G_PI/180.0)));
y = COGL_FIXED_TO_INT (priv->b * cogl_angle_sin (angle)); y = (priv->b * sinf (angle * (G_PI/180.0)));
z = 0; z = 0;
if (priv->angle_tilt_z) if (priv->angle_tilt_z)
@ -126,47 +126,47 @@ clutter_behaviour_ellipse_advance (ClutterBehaviourEllipse *e,
*/ */
ClutterFixed x2, y2; ClutterFixed x2, y2;
x2 = x * cogl_angle_cos (priv->angle_tilt_z) x2 = x * cosf (priv->angle_tilt_z * (G_PI/180.0))
- y * cogl_angle_sin (priv->angle_tilt_z); - y * sinf (priv->angle_tilt_z * (G_PI/180.0));
y2 = y * cogl_angle_cos (priv->angle_tilt_z) y2 = y * cosf (priv->angle_tilt_z * (G_PI/180.0))
+ x * cogl_angle_sin (priv->angle_tilt_z); + x * sinf (priv->angle_tilt_z * (G_PI/180.0));
x = COGL_FIXED_TO_INT (x2); x = (x2);
y = COGL_FIXED_TO_INT (y2); y = (y2);
} }
if (priv->angle_tilt_x) if (priv->angle_tilt_x)
{ {
ClutterFixed z2, y2; 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); z = (z2);
y = COGL_FIXED_TO_INT (y2); y = (y2);
} }
if (priv->angle_tilt_y) if (priv->angle_tilt_y)
{ {
ClutterFixed x2, z2; ClutterFixed x2, z2;
x2 = x * cogl_angle_cos (priv->angle_tilt_y) x2 = x * cosf (priv->angle_tilt_y * (G_PI/180.0))
- z * cogl_angle_sin (priv->angle_tilt_y); - z * sinf (priv->angle_tilt_y * (G_PI/180.0));
z2 = z * cogl_angle_cos (priv->angle_tilt_y) z2 = z * cosf (priv->angle_tilt_y * (G_PI/180.0))
+ x * cogl_angle_sin (priv->angle_tilt_y); + x * sinf (priv->angle_tilt_y * (G_PI/180.0));
x = COGL_FIXED_TO_INT (x2); x = (x2);
z = COGL_FIXED_TO_INT (z2); z = (z2);
} }
knot->x = x; knot->x = x;
knot->y = y; knot->y = y;
knot->z = z; 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, angle,
knot->x, knot->y, knot->x, knot->y,
priv->a, priv->b); priv->a, priv->b);
@ -187,20 +187,16 @@ actor_apply_knot_foreach (ClutterBehaviour *behave,
clutter_actor_set_depth (actor, knot->z); clutter_actor_set_depth (actor, knot->z);
} }
static inline ClutterAngle static inline float
clamp_angle (ClutterAngle a) clamp_angle (float a)
{ {
ClutterAngle a1, a2;
gint rounds; gint rounds;
/* Need to add the 256 offset here, since the user space 0 maps to our rounds = a / 360;
* -256 if (a < 0)
*/ rounds--;
rounds = (a + 256) / 1024;
a1 = rounds * 1024;
a2 = a - a1;
return a2; return a - 360 * rounds;
} }
static void static void
@ -209,20 +205,20 @@ clutter_behaviour_ellipse_alpha_notify (ClutterBehaviour *behave,
{ {
ClutterBehaviourEllipse *self = CLUTTER_BEHAVIOUR_ELLIPSE (behave); ClutterBehaviourEllipse *self = CLUTTER_BEHAVIOUR_ELLIPSE (behave);
ClutterBehaviourEllipsePrivate *priv = self->priv; ClutterBehaviourEllipsePrivate *priv = self->priv;
ClutterAngle start, end; float start, end;
knot3d knot; knot3d knot;
ClutterAngle angle = 0; float angle = 0;
start = priv->angle_start; start = priv->angle_start;
end = priv->angle_end; end = priv->angle_end;
if (priv->direction == CLUTTER_ROTATE_CW && start >= end) if (priv->direction == CLUTTER_ROTATE_CW && start >= end)
{ {
end += 1024; end += 360;
} }
else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end) else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end)
{ {
end -= 1024; end -= 360;
} }
angle = (end - start) * alpha / CLUTTER_ALPHA_MAX_ALPHA + start; angle = (end - start) * alpha / CLUTTER_ALPHA_MAX_ALPHA + start;
@ -247,30 +243,25 @@ clutter_behaviour_ellipse_set_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_ANGLE_START: case PROP_ANGLE_START:
priv->angle_start = priv->angle_start = g_value_get_double (value);
COGL_ANGLE_FROM_DEG (g_value_get_double (value)) - 256;
break; break;
case PROP_ANGLE_END: case PROP_ANGLE_END:
priv->angle_end = priv->angle_end = g_value_get_double (value);
COGL_ANGLE_FROM_DEG (g_value_get_double (value)) - 256;
break; break;
case PROP_ANGLE_TILT_X: case PROP_ANGLE_TILT_X:
priv->angle_tilt_x = priv->angle_tilt_x = g_value_get_double (value);
COGL_ANGLE_FROM_DEG (g_value_get_double (value));
break; break;
case PROP_ANGLE_TILT_Y: case PROP_ANGLE_TILT_Y:
priv->angle_tilt_y = priv->angle_tilt_y = g_value_get_double (value);
COGL_ANGLE_FROM_DEG (g_value_get_double (value));
break; break;
case PROP_ANGLE_TILT_Z: case PROP_ANGLE_TILT_Z:
priv->angle_tilt_z = priv->angle_tilt_z = g_value_get_double (value);
COGL_ANGLE_FROM_DEG (g_value_get_double (value));
break; break;
case PROP_WIDTH: case PROP_WIDTH:
priv->a = g_value_get_int (value) >> 1; priv->a = g_value_get_int (value) / 2;
break; break;
case PROP_HEIGHT: case PROP_HEIGHT:
priv->b = g_value_get_int (value) >> 1; priv->b = g_value_get_int (value) / 2;
break; break;
case PROP_CENTER: case PROP_CENTER:
{ {
@ -301,30 +292,25 @@ clutter_behaviour_ellipse_get_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_ANGLE_START: case PROP_ANGLE_START:
g_value_set_double (value, g_value_set_double (value, priv->angle_start);
COGL_ANGLE_TO_DEG (priv->angle_start + 256));
break; break;
case PROP_ANGLE_END: case PROP_ANGLE_END:
g_value_set_double (value, g_value_set_double (value, priv->angle_end);
COGL_ANGLE_TO_DEG (priv->angle_end + 256));
break; break;
case PROP_ANGLE_TILT_X: case PROP_ANGLE_TILT_X:
g_value_set_double (value, g_value_set_double (value, priv->angle_tilt_x);
COGL_ANGLE_TO_DEG (priv->angle_tilt_x));
break; break;
case PROP_ANGLE_TILT_Y: case PROP_ANGLE_TILT_Y:
g_value_set_double (value, g_value_set_double (value, priv->angle_tilt_y);
COGL_ANGLE_TO_DEG (priv->angle_tilt_y));
break; break;
case PROP_ANGLE_TILT_Z: case PROP_ANGLE_TILT_Z:
g_value_set_double (value, g_value_set_double (value, priv->angle_tilt_z);
COGL_ANGLE_TO_DEG (priv->angle_tilt_z));
break; break;
case PROP_WIDTH: case PROP_WIDTH:
g_value_set_int (value, (priv->a << 1)); g_value_set_int (value, (priv->a * 2));
break; break;
case PROP_HEIGHT: case PROP_HEIGHT:
g_value_set_int (value, (priv->b << 1)); g_value_set_int (value, (priv->b * 2));
break; break;
case PROP_CENTER: case PROP_CENTER:
g_value_set_boxed (value, &priv->center); g_value_set_boxed (value, &priv->center);
@ -513,12 +499,8 @@ clutter_behaviour_ellipse_init (ClutterBehaviourEllipse * self)
priv->direction = CLUTTER_ROTATE_CW; priv->direction = CLUTTER_ROTATE_CW;
/* The inital values have to reflect the 90 degree offset between the normal priv->angle_start = 0;
* mathematical space and the clutter clock-based space; the default end priv->angle_end = 0;
* value of 360 is clamped to 0.
*/
priv->angle_start = -256;
priv->angle_end = -256;
} }
/** /**
@ -611,8 +593,8 @@ clutter_behaviour_ellipse_newx (ClutterAlpha * alpha,
"width", width, "width", width,
"height", height, "height", height,
"direction", direction, "direction", direction,
"angle-start", COGL_ANGLE_FROM_DEGX (start), "angle-start", (double)CLUTTER_FIXED_TO_FLOAT (start),
"angle-end", COGL_ANGLE_FROM_DEGX (end), "angle-end", (double)CLUTTER_FIXED_TO_FLOAT (end),
NULL); NULL);
} }
@ -695,9 +677,9 @@ clutter_behaviour_ellipse_set_width (ClutterBehaviourEllipse * self,
priv = self->priv; 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"); 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); 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; 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"); 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); 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, clutter_behaviour_ellipse_set_angle_start (ClutterBehaviourEllipse *self,
gdouble angle_start) gdouble angle_start)
{ {
ClutterFixed new_angle = CLUTTER_FLOAT_TO_FIXED (angle_start);
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self));
clutter_behaviour_ellipse_set_angle_startx (self, clutter_behaviour_ellipse_set_angle_startx (self, new_angle);
COGL_FIXED_FROM_FLOAT (angle_start));
} }
/** /**
@ -802,10 +785,10 @@ clutter_behaviour_ellipse_set_angle_startx (ClutterBehaviourEllipse *self,
ClutterFixed angle_start) ClutterFixed angle_start)
{ {
ClutterBehaviourEllipsePrivate *priv; ClutterBehaviourEllipsePrivate *priv;
ClutterAngle new_angle; float new_angle;
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); 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; priv = self->priv;
if (priv->angle_start != new_angle) 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); 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); 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, clutter_behaviour_ellipse_set_angle_end (ClutterBehaviourEllipse *self,
gdouble angle_end) gdouble angle_end)
{ {
ClutterFixed new_angle = CLUTTER_FLOAT_TO_FIXED (angle_end);
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self));
clutter_behaviour_ellipse_set_angle_endx (self, clutter_behaviour_ellipse_set_angle_endx (self, new_angle);
COGL_FIXED_FROM_FLOAT (angle_end));
} }
/** /**
@ -887,11 +871,11 @@ clutter_behaviour_ellipse_set_angle_endx (ClutterBehaviourEllipse *self,
ClutterFixed angle_end) ClutterFixed angle_end)
{ {
ClutterBehaviourEllipsePrivate *priv; ClutterBehaviourEllipsePrivate *priv;
ClutterAngle new_angle; float new_angle;
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); 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; 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); 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); 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, ClutterRotateAxis axis,
gdouble angle_tilt) gdouble angle_tilt)
{ {
ClutterFixed new_angle = CLUTTER_FLOAT_TO_FIXED (angle_tilt);
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self));
clutter_behaviour_ellipse_set_angle_tiltx (self, clutter_behaviour_ellipse_set_angle_tiltx (self, axis, new_angle);
axis,
COGL_FIXED_FROM_FLOAT (angle_tilt));
} }
/** /**
@ -979,11 +963,11 @@ clutter_behaviour_ellipse_set_angle_tiltx (ClutterBehaviourEllipse *self,
ClutterFixed angle_tilt) ClutterFixed angle_tilt)
{ {
ClutterBehaviourEllipsePrivate *priv; ClutterBehaviourEllipsePrivate *priv;
ClutterAngle new_angle; float new_angle;
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); 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; priv = self->priv;
@ -1038,11 +1022,11 @@ clutter_behaviour_ellipse_get_angle_tilt (ClutterBehaviourEllipse *self,
switch (axis) switch (axis)
{ {
case CLUTTER_X_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: case CLUTTER_Y_AXIS:
return COGL_ANGLE_TO_DEG (self->priv->angle_tilt_y); return self->priv->angle_tilt_y;
case CLUTTER_Z_AXIS: case CLUTTER_Z_AXIS:
return COGL_ANGLE_TO_DEG (self->priv->angle_tilt_z); return self->priv->angle_tilt_z;
} }
return 0; return 0;
@ -1068,11 +1052,11 @@ clutter_behaviour_ellipse_get_angle_tiltx (ClutterBehaviourEllipse *self,
switch (axis) switch (axis)
{ {
case CLUTTER_X_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: 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: 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; return 0;
@ -1096,13 +1080,13 @@ clutter_behaviour_ellipse_set_tilt (ClutterBehaviourEllipse *self,
gdouble angle_tilt_z) gdouble angle_tilt_z)
{ {
ClutterBehaviourEllipsePrivate *priv; 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)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self));
new_angle_x = COGL_ANGLE_FROM_DEG (angle_tilt_x); new_angle_x = (float)angle_tilt_x;
new_angle_y = COGL_ANGLE_FROM_DEG (angle_tilt_y); new_angle_y = (float)angle_tilt_y;
new_angle_z = COGL_ANGLE_FROM_DEG (angle_tilt_z); new_angle_z = (float)angle_tilt_z;
priv = self->priv; priv = self->priv;
@ -1150,13 +1134,13 @@ clutter_behaviour_ellipse_set_tiltx (ClutterBehaviourEllipse *self,
ClutterFixed angle_tilt_z) ClutterFixed angle_tilt_z)
{ {
ClutterBehaviourEllipsePrivate *priv; 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)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self));
new_angle_x = COGL_ANGLE_FROM_DEGX (angle_tilt_x); new_angle_x = CLUTTER_FIXED_TO_FLOAT (angle_tilt_x);
new_angle_y = COGL_ANGLE_FROM_DEGX (angle_tilt_y); new_angle_y = CLUTTER_FIXED_TO_FLOAT (angle_tilt_y);
new_angle_z = COGL_ANGLE_FROM_DEGX (angle_tilt_z); new_angle_z = CLUTTER_FIXED_TO_FLOAT (angle_tilt_z);
priv = self->priv; priv = self->priv;
@ -1210,13 +1194,13 @@ clutter_behaviour_ellipse_get_tilt (ClutterBehaviourEllipse *self,
priv = self->priv; priv = self->priv;
if (angle_tilt_x) 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) 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) 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; priv = self->priv;
if (angle_tilt_x) 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) 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) if (angle_tilt_z)
*angle_tilt_z = COGL_ANGLE_TO_DEGX (priv->angle_tilt_z); *angle_tilt_z = priv->angle_tilt_z;
} }
/** /**

View File

@ -108,8 +108,8 @@ ClutterFixed clamp_angle (ClutterFixed a)
ClutterFixed a1, a2; ClutterFixed a1, a2;
gint rounds; gint rounds;
rounds = a / COGL_FIXED_360; rounds = a / 360.0;
a1 = rounds * COGL_FIXED_360; a1 = rounds * 360.0;
a2 = a - a1; a2 = a - a1;
return a2; return a2;
@ -126,7 +126,7 @@ clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour,
rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour);
priv = rotate_behaviour->priv; 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; angle = 0;
start = priv->angle_start; start = priv->angle_start;
@ -134,14 +134,14 @@ clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour,
if (priv->direction == CLUTTER_ROTATE_CW && start >= end) if (priv->direction == CLUTTER_ROTATE_CW && start >= end)
{ {
end += COGL_FIXED_360; end += 360.0;
} }
else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end) 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, clutter_behaviour_actors_foreach (behaviour,
alpha_notify_foreach, alpha_notify_foreach,
@ -163,10 +163,10 @@ clutter_behaviour_rotate_set_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_ANGLE_START: 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; break;
case PROP_ANGLE_END: 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; break;
case PROP_AXIS: case PROP_AXIS:
priv->axis = g_value_get_enum (value); priv->axis = g_value_get_enum (value);
@ -211,10 +211,10 @@ clutter_behaviour_rotate_get_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_ANGLE_START: 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; break;
case PROP_ANGLE_END: 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; break;
case PROP_AXIS: case PROP_AXIS:
g_value_set_enum (value, priv->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); rotate->priv = priv = CLUTTER_BEHAVIOUR_ROTATE_GET_PRIVATE (rotate);
priv->angle_start = COGL_FIXED_FROM_FLOAT (0.0); priv->angle_start = CLUTTER_FLOAT_TO_FIXED (0.0);
priv->angle_end = COGL_FIXED_FROM_FLOAT (0.0); priv->angle_end = CLUTTER_FLOAT_TO_FIXED (0.0);
priv->axis = CLUTTER_Z_AXIS; priv->axis = CLUTTER_Z_AXIS;
priv->direction = CLUTTER_ROTATE_CW; priv->direction = CLUTTER_ROTATE_CW;
priv->center_x = priv->center_y = priv->center_z = 0; priv->center_x = priv->center_y = priv->center_z = 0;
@ -568,10 +568,10 @@ clutter_behaviour_rotate_get_bounds (ClutterBehaviourRotate *rotate,
priv = rotate->priv; priv = rotate->priv;
if (angle_start) if (angle_start)
*angle_start = COGL_FIXED_TO_DOUBLE (priv->angle_start); *angle_start = CLUTTER_FIXED_TO_DOUBLE (priv->angle_start);
if (angle_end) 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)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate));
clutter_behaviour_rotate_set_boundsx (rotate, clutter_behaviour_rotate_set_boundsx (rotate,
COGL_FIXED_FROM_FLOAT (angle_start), CLUTTER_FLOAT_TO_FIXED (angle_start),
COGL_FIXED_FROM_FLOAT (angle_end)); CLUTTER_FLOAT_TO_FIXED (angle_end));
} }
/** /**

View File

@ -115,14 +115,14 @@ clutter_behaviour_scale_alpha_notify (ClutterBehaviour *behave,
{ {
ClutterFixed factor; ClutterFixed factor;
factor = COGL_FIXED_FROM_INT (alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; factor = (float)(alpha_value) / CLUTTER_ALPHA_MAX_ALPHA;
scale_x = 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_x += priv->x_scale_start;
scale_y = 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; scale_y += priv->y_scale_start;
} }
@ -147,16 +147,16 @@ clutter_behaviour_scale_set_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_X_SCALE_START: 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; break;
case PROP_X_SCALE_END: 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; break;
case PROP_Y_SCALE_START: 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; break;
case PROP_Y_SCALE_END: 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; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
@ -177,16 +177,16 @@ clutter_behaviour_scale_get_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_X_SCALE_START: 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; break;
case PROP_X_SCALE_END: 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; break;
case PROP_Y_SCALE_START: 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; break;
case PROP_Y_SCALE_END: 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; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); 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); self->priv = priv = CLUTTER_BEHAVIOUR_SCALE_GET_PRIVATE (self);
priv->x_scale_start = priv->x_scale_end = COGL_FIXED_1; priv->x_scale_start = priv->x_scale_end = 1.0;
priv->y_scale_start = priv->y_scale_end = COGL_FIXED_1; 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); g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL);
return clutter_behaviour_scale_newx (alpha, return clutter_behaviour_scale_newx (alpha,
COGL_FIXED_FROM_FLOAT (x_scale_start), CLUTTER_FLOAT_TO_FIXED (x_scale_start),
COGL_FIXED_FROM_FLOAT (y_scale_start), CLUTTER_FLOAT_TO_FIXED (y_scale_start),
COGL_FIXED_FROM_FLOAT (x_scale_end), CLUTTER_FLOAT_TO_FIXED (x_scale_end),
COGL_FIXED_FROM_FLOAT (y_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)); g_return_if_fail (CLUTTER_IS_BEHAVIOUR_SCALE (scale));
clutter_behaviour_scale_set_boundsx (scale, clutter_behaviour_scale_set_boundsx (scale,
COGL_FIXED_FROM_FLOAT (x_scale_start), CLUTTER_FLOAT_TO_FIXED (x_scale_start),
COGL_FIXED_FROM_FLOAT (y_scale_start), CLUTTER_FLOAT_TO_FIXED (y_scale_start),
COGL_FIXED_FROM_FLOAT (x_scale_end), CLUTTER_FLOAT_TO_FIXED (x_scale_end),
COGL_FIXED_FROM_FLOAT (y_scale_end)); CLUTTER_FLOAT_TO_FIXED (y_scale_end));
} }
/** /**
@ -403,16 +403,16 @@ clutter_behaviour_scale_get_bounds (ClutterBehaviourScale *scale,
priv = scale->priv; priv = scale->priv;
if (x_scale_start) 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) 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) 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) 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);
} }
/** /**

View File

@ -252,7 +252,7 @@ _clutter_bezier_init (ClutterBezier *b,
int x = _clutter_bezier_t2x (b, t); int x = _clutter_bezier_t2x (b, t);
int y = _clutter_bezier_t2y (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]; l += length[i-1];

View File

@ -104,6 +104,10 @@
#include "clutter-marshal.h" #include "clutter-marshal.h"
#include "clutter-private.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 | \ #define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \
CLUTTER_CONTROL_MASK | \ CLUTTER_CONTROL_MASK | \
CLUTTER_MOD1_MASK | \ CLUTTER_MOD1_MASK | \
@ -111,19 +115,27 @@
CLUTTER_HYPER_MASK | \ CLUTTER_HYPER_MASK | \
CLUTTER_META_MASK) | CLUTTER_RELEASE_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; static GQuark key_class_bindings = 0;
struct _ClutterBindingPool struct _ClutterBindingPool
{ {
GObject parent_instance;
gchar *name; /* interned string, do not free */ gchar *name; /* interned string, do not free */
GSList *entries; GSList *entries;
GHashTable *entries_hash; GHashTable *entries_hash;
}; };
struct _ClutterBindingPoolClass
{
GObjectClass parent_class;
};
struct _ClutterBindingEntry struct _ClutterBindingEntry
{ {
gchar *name; /* interned string, do not free */ gchar *name; /* interned string, do not free */
@ -136,6 +148,15 @@ struct _ClutterBindingEntry
guint is_blocked : 1; guint is_blocked : 1;
}; };
enum
{
PROP_0,
PROP_NAME
};
G_DEFINE_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT);
static guint static guint
binding_entry_hash (gconstpointer v) binding_entry_hash (gconstpointer v)
{ {
@ -204,24 +225,112 @@ binding_entry_free (gpointer data)
} }
static void 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 */ default:
binding_pools = g_slist_remove (binding_pools, pool); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
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);
} }
} }
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: * clutter_binding_pool_new:
* @name: the name of the binding pool * @name: the name of the binding pool
@ -232,8 +341,7 @@ binding_pool_free (gpointer data)
* be able to return the correct binding pool. * be able to return the correct binding pool.
* *
* Return value: the newly created binding pool with the given * Return value: the newly created binding pool with the given
* name. The binding pool is owned by Clutter and should not * name. Use g_object_unref() when done.
* be freed directly
* *
* Since: 1.0 * Since: 1.0
*/ */
@ -253,15 +361,7 @@ clutter_binding_pool_new (const gchar *name)
return NULL; return NULL;
} }
pool = g_slice_new (ClutterBindingPool); return g_object_new (CLUTTER_TYPE_BINDING_POOL, "name", name, NULL);
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;
} }
/** /**
@ -306,7 +406,7 @@ clutter_binding_pool_get_for_class (gpointer klass)
pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass)); pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass));
g_dataset_id_set_data_full (klass, key_class_bindings, g_dataset_id_set_data_full (klass, key_class_bindings,
pool, pool,
binding_pool_free); g_object_unref);
return pool; return pool;
} }
@ -328,7 +428,7 @@ clutter_binding_pool_find (const gchar *name)
g_return_val_if_fail (name != NULL, NULL); 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; ClutterBindingPool *pool = l->data;

View File

@ -33,6 +33,18 @@
G_BEGIN_DECLS 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; typedef struct _ClutterBindingPool ClutterBindingPool;
/** /**
@ -56,6 +68,8 @@ typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject,
guint key_val, guint key_val,
ClutterModifierType modifiers); ClutterModifierType modifiers);
GType clutter_binding_pool_get_type (void) G_GNUC_CONST;
ClutterBindingPool * clutter_binding_pool_new (const gchar *name); ClutterBindingPool * clutter_binding_pool_new (const gchar *name);
ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass); ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass);
ClutterBindingPool * clutter_binding_pool_find (const gchar *name); ClutterBindingPool * clutter_binding_pool_find (const gchar *name);

View File

@ -209,15 +209,15 @@ clutter_clone_texture_paint (ClutterActor *self)
tex_height = cogl_texture_get_height (cogl_texture); tex_height = cogl_texture_get_height (cogl_texture);
if (priv->repeat_x && tex_width > 0) if (priv->repeat_x && tex_width > 0)
t_w = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (x_2 - x_1), t_w = CLUTTER_FIXED_DIV ((float)(x_2 - x_1),
COGL_FIXED_FROM_INT (tex_width)); (float)(tex_width));
else else
t_w = COGL_FIXED_1; t_w = 1.0;
if (priv->repeat_y && tex_height > 0) if (priv->repeat_y && tex_height > 0)
t_h = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (y_2 - y_1), t_h = CLUTTER_FIXED_DIV ((float)(y_2 - y_1),
COGL_FIXED_FROM_INT (tex_height)); (float)(tex_height));
else else
t_h = COGL_FIXED_1; t_h = 1.0;
#if USE_COGL_MATERIAL #if USE_COGL_MATERIAL
cogl_set_source (cogl_material); cogl_set_source (cogl_material);
@ -234,8 +234,8 @@ clutter_clone_texture_paint (ClutterActor *self)
#else #else
/* Parent paint translated us into position */ /* Parent paint translated us into position */
cogl_texture_rectangle (cogl_texture, 0, 0, cogl_texture_rectangle (cogl_texture, 0, 0,
COGL_FIXED_FROM_INT (x_2 - x_1), (float)(x_2 - x_1),
COGL_FIXED_FROM_INT (y_2 - y_1), (float)(y_2 - y_1),
0, 0, t_w, t_h); 0, 0, t_w, t_h);
#endif #endif
} }

View File

@ -154,9 +154,9 @@ clutter_color_to_hlsx (const ClutterColor *src,
g_return_if_fail (src != NULL); g_return_if_fail (src != NULL);
red = COGL_FIXED_FROM_INT (src->red) / 255; red = (float)(src->red) / 255;
green = COGL_FIXED_FROM_INT (src->green) / 255; green = (float)(src->green) / 255;
blue = COGL_FIXED_FROM_INT (src->blue) / 255; blue = (float)(src->blue) / 255;
if (red > green) if (red > green)
{ {
@ -189,31 +189,31 @@ clutter_color_to_hlsx (const ClutterColor *src,
if (max != min) if (max != min)
{ {
if (l <= COGL_FIXED_0_5) if (l <= 0.5)
s = COGL_FIXED_FAST_DIV ((max - min), (max + min)); s = CLUTTER_FIXED_DIV ((max - min), (max + min));
else else
s = COGL_FIXED_FAST_DIV ((max - min), s = CLUTTER_FIXED_DIV ((max - min),
(COGL_FIXED_FROM_INT (2) - max - min)); ((float)(2) - max - min));
delta = max - min; delta = max - min;
if (red == max) if (red == max)
h = COGL_FIXED_FAST_DIV ((green - blue), delta); h = CLUTTER_FIXED_DIV ((green - blue), delta);
else if (green == max) else if (green == max)
{ {
h = COGL_FIXED_FROM_INT (2) h = (float)(2)
+ COGL_FIXED_FAST_DIV ((blue - red), delta); + CLUTTER_FIXED_DIV ((blue - red), delta);
} }
else if (blue == max) else if (blue == max)
{ {
h = COGL_FIXED_FROM_INT (4) h = (float)(4)
+ COGL_FIXED_FAST_DIV ((red - green), delta); + CLUTTER_FIXED_DIV ((red - green), delta);
} }
h *= 60; h *= 60;
if (h < 0) if (h < 0)
h += COGL_FIXED_360; h += 360.0;
} }
if (hue) if (hue)
@ -251,102 +251,102 @@ clutter_color_from_hlsx (ClutterColor *dest,
l = luminance; l = luminance;
s = saturation; s = saturation;
if (l <= COGL_FIXED_0_5) if (l <= 0.5)
m2 = COGL_FIXED_FAST_MUL (l, (COGL_FIXED_1 + s)); m2 = CLUTTER_FIXED_MUL (l, (1.0 + s));
else else
m2 = l + s - COGL_FIXED_FAST_MUL (l, s); m2 = l + s - CLUTTER_FIXED_MUL (l, s);
m1 = 2 * l - m2; m1 = 2 * l - m2;
if (s == 0) if (s == 0)
{ {
dest->red = (guint8) COGL_FIXED_TO_INT (l * 255); dest->red = (guint8) (l * 255);
dest->green = (guint8) COGL_FIXED_TO_INT (l * 255); dest->green = (guint8) (l * 255);
dest->blue = (guint8) COGL_FIXED_TO_INT (l * 255); dest->blue = (guint8) (l * 255);
} }
else else
{ {
h = hue + COGL_FIXED_120; h = hue + 120.0;
while (h > COGL_FIXED_360) while (h > 360.0)
h -= COGL_FIXED_360; h -= 360.0;
while (h < 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); tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), h) / 60);
dest->red = (guint8) COGL_FIXED_TO_INT (tmp * 255); dest->red = (guint8) (tmp * 255);
} }
else if (h < COGL_FIXED_180) else if (h < 180.0)
dest->red = (guint8) COGL_FIXED_TO_INT (m2 * 255); dest->red = (guint8) (m2 * 255);
else if (h < COGL_FIXED_240) 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; / 60;
dest->red = (guint8) COGL_FIXED_TO_INT (tmp * 255); dest->red = (guint8) (tmp * 255);
} }
else else
dest->red = (guint8) COGL_FIXED_TO_INT (m1 * 255); dest->red = (guint8) (m1 * 255);
h = hue; h = hue;
while (h > COGL_FIXED_360) while (h > 360.0)
h -= COGL_FIXED_360; h -= 360.0;
while (h < 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); tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), h) / 60);
dest->green = (guint8) COGL_FIXED_TO_INT (tmp * 255); dest->green = (guint8) (tmp * 255);
} }
else if (h < COGL_FIXED_180) else if (h < 180.0)
dest->green = (guint8) COGL_FIXED_TO_INT (m2 * 255); dest->green = (guint8) (m2 * 255);
else if (h < COGL_FIXED_240) 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; / 60;
dest->green = (guint8) COGL_FIXED_TO_INT (tmp * 255); dest->green = (guint8) (tmp * 255);
} }
else 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) while (h > 360.0)
h -= COGL_FIXED_360; h -= 360.0;
while (h < 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); tmp = (m1 + CLUTTER_FIXED_MUL ((m2 - m1), h) / 60);
dest->blue = (guint8) COGL_FIXED_TO_INT (tmp * 255); dest->blue = (guint8) (tmp * 255);
} }
else if (h < COGL_FIXED_180) else if (h < 180.0)
dest->blue = (guint8) COGL_FIXED_TO_INT (m2 * 255); dest->blue = (guint8) (m2 * 255);
else if (h < COGL_FIXED_240) 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; / 60;
dest->blue = (guint8) COGL_FIXED_TO_INT (tmp * 255); dest->blue = (guint8) (tmp * 255);
} }
else 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); clutter_color_to_hlsx (src, &h, &l, &s);
if (hue) if (hue)
*hue = (guint8) COGL_FIXED_TO_INT (h * 255) / 360; *hue = (guint8) (h * 255) / 360;
if (luminance) if (luminance)
*luminance = (guint8) COGL_FIXED_TO_INT (l * 255); *luminance = (guint8) (l * 255);
if (saturation) 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; ClutterFixed h, l, s;
h = COGL_FIXED_FROM_INT (hue * 360) / 255; h = (float)(hue * 360) / 255;
l = COGL_FIXED_FROM_INT (luminance) / 255; l = (float)(luminance) / 255;
s = COGL_FIXED_FROM_INT (saturation) / 255; s = (float)(saturation) / 255;
clutter_color_from_hlsx (dest, h, l, s); clutter_color_from_hlsx (dest, h, l, s);
} }
@ -420,7 +420,7 @@ clutter_color_shade (const ClutterColor *src,
ClutterColor *dest, ClutterColor *dest,
gdouble shade) 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); clutter_color_to_hlsx (src, &h, &l, &s);
l = COGL_FIXED_FAST_MUL (l, shade); l = CLUTTER_FIXED_MUL (l, shade);
if (l > COGL_FIXED_1) if (l > 1.0)
l = COGL_FIXED_1; l = 1.0;
else if (l < 0) else if (l < 0)
l = 0; l = 0;
s = COGL_FIXED_FAST_MUL (s, shade); s = CLUTTER_FIXED_MUL (s, shade);
if (s > COGL_FIXED_1) if (s > 1.0)
s = COGL_FIXED_1; s = 1.0;
else if (s < 0) else if (s < 0)
s = 0; s = 0;

View File

@ -1,848 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Jorn Baayen <jorn@openedhand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
*
* 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 <math.h>
#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;
}

View File

@ -1,162 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_EFFECT_H__
#define __CLUTTER_EFFECT_H__
#include <glib-object.h>
#include <clutter/clutter-actor.h>
#include <clutter/clutter-timeline.h>
#include <clutter/clutter-alpha.h>
#include <clutter/clutter-behaviour.h>
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__ */

View File

@ -264,8 +264,8 @@ struct _ClutterKeyEvent
* @flags: event flags * @flags: event flags
* @stage: event source stage * @stage: event source stage
* @source: event source actor * @source: event source actor
* @x: event X coordinate * @x: event X coordinate, relative to the stage
* @y: event Y coordinate * @y: event Y coordinate, relative to the stage
* @modifier_state: button modifiers * @modifier_state: button modifiers
* @button: event button * @button: event button
* @click_count: number of button presses within the default time * @click_count: number of button presses within the default time
@ -273,7 +273,11 @@ struct _ClutterKeyEvent
* @axes: reserved for future use * @axes: reserved for future use
* @device: 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 * Since: 0.2
*/ */
@ -447,7 +451,7 @@ ClutterModifierType clutter_event_get_state (ClutterEvent *event);
void clutter_event_get_coords (ClutterEvent *event, void clutter_event_get_coords (ClutterEvent *event,
gint *x, gint *x,
gint *y); 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); ClutterActor* clutter_event_get_source (ClutterEvent *event);
guint clutter_key_event_symbol (ClutterKeyEvent *keyev); 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); guint32 clutter_keysym_to_unicode (guint keyval);
ClutterStage* clutter_event_get_stage (ClutterEvent *event); ClutterStage* clutter_event_get_stage (ClutterEvent *event);
G_END_DECLS G_END_DECLS

View File

@ -130,42 +130,42 @@ static void
clutter_value_transform_fixed_int (const GValue *src, clutter_value_transform_fixed_int (const GValue *src,
GValue *dest) 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 static void
clutter_value_transform_fixed_double (const GValue *src, clutter_value_transform_fixed_double (const GValue *src,
GValue *dest) 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 static void
clutter_value_transform_fixed_float (const GValue *src, clutter_value_transform_fixed_float (const GValue *src,
GValue *dest) 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 static void
clutter_value_transform_int_fixed (const GValue *src, clutter_value_transform_int_fixed (const GValue *src,
GValue *dest) 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 static void
clutter_value_transform_double_fixed (const GValue *src, clutter_value_transform_double_fixed (const GValue *src,
GValue *dest) 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 static void
clutter_value_transform_float_fixed (const GValue *src, clutter_value_transform_float_fixed (const GValue *src,
GValue *dest) 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); ClutterParamSpecFixed *fspec = CLUTTER_PARAM_SPEC_FIXED (pspec);
fspec->minimum = COGL_FIXED_MIN; fspec->minimum = CLUTTER_MAXFIXED;
fspec->maximum = COGL_FIXED_MAX; fspec->maximum = CLUTTER_MINFIXED;
fspec->default_value = 0; fspec->default_value = 0;
} }
@ -268,7 +268,7 @@ param_fixed_validate (GParamSpec *pspec,
GValue *value) GValue *value)
{ {
ClutterParamSpecFixed *fspec = CLUTTER_PARAM_SPEC_FIXED (pspec); 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; gint min, max, val;
g_assert (CLUTTER_IS_PARAM_SPEC_FIXED (pspec)); g_assert (CLUTTER_IS_PARAM_SPEC_FIXED (pspec));
@ -279,7 +279,7 @@ param_fixed_validate (GParamSpec *pspec,
min = fspec->minimum; min = fspec->minimum;
max = fspec->maximum; max = fspec->maximum;
val = COGL_FIXED_TO_INT (value->data[0].v_int); val = (value->data[0].v_int);
val = CLAMP (val, min, max); val = CLAMP (val, min, max);
if (val != oval) if (val != oval)

View File

@ -39,126 +39,118 @@ G_BEGIN_DECLS
* *
* Fixed point number (16.16) * Fixed point number (16.16)
*/ */
typedef CoglFixed ClutterFixed; typedef float ClutterFixed;
/** /**
* ClutterAngle: * ClutterAngle:
* *
* Integer representation of an angle such that 1024 corresponds to * An abstract representation of an angle.
* full circle (i.e., 2*Pi).
*/ */
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_DEG(x) ((float)(x))
#define CLUTTER_ANGLE_FROM_DEGX(x) (COGL_ANGLE_FROM_DEGX (x)) #define CLUTTER_ANGLE_FROM_DEGX(x) (CLUTTER_FIXED_TO_FLOAT (x))
#define CLUTTER_ANGLE_TO_DEG(x) (COGL_ANGLE_TO_DEG (x)) #define CLUTTER_ANGLE_TO_DEG(x) ((float)(x))
#define CLUTTER_ANGLE_TO_DEGX(x) (COGL_ANGLE_TO_DEGX (x)) #define CLUTTER_ANGLE_TO_DEGX(x) (CLUTTER_FLOAT_TO_FIXED (x))
/* /*
* some commonly used constants * some commonly used constants
*/ */
/**
* CFX_Q:
*
* Size in bits of decimal part of floating point value.
*/
#define CFX_Q COGL_FIXED_Q
/** /**
* CFX_ONE: * CFX_ONE:
* *
* 1.0 represented as a fixed point value. * 1.0 represented as a fixed point value.
*/ */
#define CFX_ONE COGL_FIXED_1 #define CFX_ONE 1.0
/** /**
* CFX_HALF: * CFX_HALF:
* *
* 0.5 represented as a fixed point value. * 0.5 represented as a fixed point value.
*/ */
#define CFX_HALF COGL_FIXED_0_5 #define CFX_HALF 0.5
/** /**
* CFX_MAX: * CFX_MAX:
* *
* Maximum fixed point value. * Maximum fixed point value.
*/ */
#define CFX_MAX COGL_FIXED_MAX #define CFX_MAX G_MAXFLOAT
/** /**
* CFX_MIN: * CFX_MIN:
* *
* Minimum fixed point value. * Minimum fixed point value.
*/ */
#define CFX_MIN COGL_FIXED_MIN #define CFX_MIN (-G_MAXFLOAT)
/** /**
* CFX_PI: * CFX_PI:
* *
* Fixed point representation of Pi * Fixed point representation of Pi
*/ */
#define CFX_PI COGL_FIXED_PI #define CFX_PI G_PI
/** /**
* CFX_2PI: * CFX_2PI:
* *
* Fixed point representation of Pi*2 * Fixed point representation of Pi*2
*/ */
#define CFX_2PI COGL_FIXED_2_PI #define CFX_2PI (G_PI * 2)
/** /**
* CFX_PI_2: * CFX_PI_2:
* *
* Fixed point representation of 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: * CFX_PI_4:
* *
* Fixed point representation of 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: * CFX_360:
* *
* Fixed point representation of the number 360 * Fixed point representation of the number 360
*/ */
#define CFX_360 COGL_FIXED_360 #define CFX_360 360.0
/** /**
* CFX_240: * CFX_240:
* *
* Fixed point representation of the number 240 * Fixed point representation of the number 240
*/ */
#define CFX_240 COGL_FIXED_240 #define CFX_240 240.0
/** /**
* CFX_180: * CFX_180:
* *
* Fixed point representation of the number 180 * Fixed point representation of the number 180
*/ */
#define CFX_180 COGL_FIXED_180 #define CFX_180 180.0
/** /**
* CFX_120: * CFX_120:
* *
* Fixed point representation of the number 120 * Fixed point representation of the number 120
*/ */
#define CFX_120 COGL_FIXED_120 #define CFX_120 120.0
/** /**
* CFX_60: * CFX_60:
* *
* Fixed point representation of the number 60 * Fixed point representation of the number 60
*/ */
#define CFX_60 COGL_FIXED_60 #define CFX_60 60.0
/** /**
* CFX_RADIANS_TO_DEGREES: * CFX_RADIANS_TO_DEGREES:
* *
* Fixed point representation of the number 180 / pi * 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: * CFX_255:
* *
* Fixed point representation of the number 255 * Fixed point representation of the number 255
*/ */
#define CFX_255 COGL_FIXED_255 #define CFX_255 255.0
/** /**
* CLUTTER_FIXED_TO_FLOAT: * CLUTTER_FIXED_TO_FLOAT:
@ -166,7 +158,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Convert a fixed point value to float. * 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: * CLUTTER_FIXED_TO_DOUBLE:
@ -174,7 +166,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Convert a fixed point value to double. * 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: * CLUTTER_FLOAT_TO_FIXED:
@ -182,7 +174,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Convert a float value to fixed. * 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: * CLUTTER_FLOAT_TO_INT:
@ -190,7 +182,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Convert a float value to int. * 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: * CLUTTER_FLOAT_TO_UINT:
@ -198,7 +190,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Convert a float value to unsigned int. * 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: * CLUTTER_INT_TO_FIXED:
@ -206,7 +198,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Convert an integer value to fixed point. * 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: * CLUTTER_FIXED_TO_INT:
@ -216,7 +208,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Since: 0.6 * 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: * 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 * 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: * 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. * 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: * 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. * 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: * CLUTTER_FIXED_MUL:
@ -249,7 +241,7 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Multiply two fixed point values * 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: * CLUTTER_FIXED_DIV:
@ -258,54 +250,16 @@ typedef CoglAngle ClutterAngle; /* angle such that 1024 == 2*PI */
* *
* Divide two fixed point values * 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_qmulx(x,y) ((x) * (y))
#define clutter_qdivx(x,y) cogl_fixed_div ((x), (y)) #define clutter_qdivx(x,y) ((x) / (y))
#define clutter_sinx(a) cogl_fixed_sin ((a)) #define clutter_sinx(a) sinf (a * (G_PI/180.0))
#define clutter_sini(a) cogl_angle_sin ((a)) #define clutter_tanx(a) tanf (a * (G_PI/180.0))
#define clutter_tani(a) cogl_angle_tan ((a)) #define clutter_atanx(a) atanf (a * (G_PI/180.0))
#define clutter_atani(a) cogl_fixed_atan ((a)) #define clutter_atan2x(x,y) atan2f (x, y)
#define clutter_atan2i(x,y) cogl_fixed_atan2 ((x), (y)) #define clutter_cosx(a) cosf (a * (G_PI/180.0))
#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_TYPE_FIXED (clutter_fixed_get_type ()) #define CLUTTER_TYPE_FIXED (clutter_fixed_get_type ())
#define CLUTTER_TYPE_PARAM_FIXED (clutter_param_fixed_get_type ()) #define CLUTTER_TYPE_PARAM_FIXED (clutter_param_fixed_get_type ())
@ -331,7 +285,7 @@ typedef struct _ClutterParamSpecFixed ClutterParamSpecFixed;
* *
* Since: 0.8 * Since: 0.8
*/ */
#define CLUTTER_MAXFIXED COGL_FIXED_MAX #define CLUTTER_MAXFIXED G_MAXFLOAT
/** /**
* CLUTTER_MINFIXED: * CLUTTER_MINFIXED:
@ -340,7 +294,7 @@ typedef struct _ClutterParamSpecFixed ClutterParamSpecFixed;
* *
* Since: 0.8 * Since: 0.8
*/ */
#define CLUTTER_MINFIXED COGL_FIXED_MIN #define CLUTTER_MINFIXED (-G_MAXFLOAT)
/** /**
* ClutterParamSpecFixed * ClutterParamSpecFixed

View File

@ -57,9 +57,18 @@
#include <glib-object.h> #include <glib-object.h>
#include <gobject/gvaluecollector.h> #include <gobject/gvaluecollector.h>
#include "clutter-color.h"
#include "clutter-fixed.h"
#include "clutter-interval.h" #include "clutter-interval.h"
#include "clutter-units.h" #include "clutter-units.h"
#include "clutter-fixed.h"
typedef struct
{
GType value_type;
ClutterProgressFunc func;
} ProgressData;
static GHashTable *progress_funcs = NULL;
enum enum
{ {
@ -171,19 +180,39 @@ clutter_interval_real_validate (ClutterInterval *interval,
return TRUE; return TRUE;
} }
static void static gboolean
clutter_interval_real_compute_value (ClutterInterval *interval, clutter_interval_real_compute_value (ClutterInterval *interval,
gdouble factor, gdouble factor,
GValue *value) GValue *value)
{ {
GValue *initial, *final; GValue *initial, *final;
GType value_type; GType value_type;
gboolean retval = FALSE;
initial = clutter_interval_peek_initial_value (interval); initial = clutter_interval_peek_initial_value (interval);
final = clutter_interval_peek_final_value (interval); final = clutter_interval_peek_final_value (interval);
value_type = clutter_interval_get_value_type (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)) switch (G_TYPE_FUNDAMENTAL (value_type))
{ {
case G_TYPE_INT: case G_TYPE_INT:
@ -196,6 +225,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval,
res = (factor * (ib - ia)) + ia; res = (factor * (ib - ia)) + ia;
g_value_set_int (value, res); g_value_set_int (value, res);
retval = TRUE;
} }
break; break;
@ -209,6 +240,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval,
res = (factor * (ib - (gdouble) ia)) + ia; res = (factor * (ib - (gdouble) ia)) + ia;
g_value_set_uint (value, res); g_value_set_uint (value, res);
retval = TRUE;
} }
break; break;
@ -222,6 +255,8 @@ clutter_interval_real_compute_value (ClutterInterval *interval,
res = (factor * (ib - (gdouble) ia)) + ia; res = (factor * (ib - (gdouble) ia)) + ia;
g_value_set_uchar (value, res); g_value_set_uchar (value, res);
retval = TRUE;
} }
break; break;
@ -239,19 +274,45 @@ clutter_interval_real_compute_value (ClutterInterval *interval,
g_value_set_double (value, res); g_value_set_double (value, res);
else else
g_value_set_float (value, res); g_value_set_float (value, res);
retval = TRUE;
} }
break; break;
case G_TYPE_BOOLEAN: 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); g_value_set_boolean (value, TRUE);
else else
g_value_set_boolean (value, FALSE); 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; break;
default: default:
break; break;
} }
return retval;
} }
static void static void
@ -818,19 +879,99 @@ clutter_interval_validate (ClutterInterval *interval,
* Computes the value between the @interval boundaries given the * Computes the value between the @interval boundaries given the
* progress @factor and puts it into @value. * progress @factor and puts it into @value.
* *
* Return value: %TRUE if the operation was successful
*
* Since: 1.0 * Since: 1.0
*/ */
void gboolean
clutter_interval_compute_value (ClutterInterval *interval, clutter_interval_compute_value (ClutterInterval *interval,
gdouble factor, gdouble factor,
GValue *value) GValue *value)
{ {
g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE);
g_return_if_fail (value != NULL); g_return_val_if_fail (value != NULL, FALSE);
factor = CLAMP (factor, 0.0, 1.0); factor = CLAMP (factor, 0.0, 1.0);
CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval, return CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval,
factor, factor,
value); 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);
}
} }

View File

@ -44,6 +44,34 @@ typedef struct _ClutterInterval ClutterInterval;
typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate; typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate;
typedef struct _ClutterIntervalClass ClutterIntervalClass; 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: * ClutterInterval:
* *
@ -79,7 +107,7 @@ struct _ClutterIntervalClass
/*< public >*/ /*< public >*/
gboolean (* validate) (ClutterInterval *interval, gboolean (* validate) (ClutterInterval *interval,
GParamSpec *pspec); GParamSpec *pspec);
void (* compute_value) (ClutterInterval *interval, gboolean (* compute_value) (ClutterInterval *interval,
gdouble factor, gdouble factor,
GValue *value); GValue *value);
@ -122,10 +150,13 @@ void clutter_interval_get_interval (ClutterInterval *interval,
gboolean clutter_interval_validate (ClutterInterval *interval, gboolean clutter_interval_validate (ClutterInterval *interval,
GParamSpec *pspec); GParamSpec *pspec);
void clutter_interval_compute_value (ClutterInterval *interval, gboolean clutter_interval_compute_value (ClutterInterval *interval,
gdouble factor, gdouble factor,
GValue *value); GValue *value);
void clutter_interval_register_progress_func (GType value_type,
ClutterProgressFunc func);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_INTERVAL_H__ */ #endif /* __CLUTTER_INTERVAL_H__ */

View File

@ -3,9 +3,11 @@
* *
* An OpenGL based 'interactive canvas' library. * An OpenGL based 'interactive canvas' library.
* *
* Authored By Matthew Allum <mallum@openedhand.com> * Authored By: Matthew Allum <mallum@openedhand.com>
* Emmanuele Bassi <ebassi@linux.intel.com>
* *
* Copyright (C) 2006 OpenedHand * Copyright (C) 2006 OpenedHand
* Copyright (C) 2009 Intel Corp.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -18,22 +20,20 @@
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the * License along with this library. If not, see <http://www.gnu.org/licenses/>.
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/ */
/** /**
* SECTION:clutter-media * 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. * #ClutterMedia is an interface for controlling playback of media sources.
* *
* It is not implemented inside Clutter, but other integration libraries * Clutter core does not provide an implementation of this interface, but
* like Clutter-GStreamer, implement it to offer a uniform API for * other integration libraries like Clutter-GStreamer implement it to offer
* applications. * a uniform API for applications.
* *
* ClutterMedia is available since Clutter 0.2 * #ClutterMedia is available since Clutter 0.2
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -53,118 +53,119 @@ enum
LAST_SIGNAL LAST_SIGNAL
}; };
static void clutter_media_base_init (gpointer g_class);
static guint media_signals[LAST_SIGNAL] = { 0, }; 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 static void
clutter_media_base_init (gpointer g_iface) 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, * ClutterMedia:uri:
g_param_spec_string *
("uri", * The location of a media file, expressed as a valid URI.
"URI", *
"The loaded URI.", * Since: 0.2
NULL, */
G_PARAM_READWRITE | pspec = g_param_spec_string ("uri",
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | "URI",
G_PARAM_STATIC_BLURB)); "URI of a media file",
NULL,
CLUTTER_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
g_object_interface_install_property /**
(g_iface, * ClutterMedia:playing:
g_param_spec_boolean *
("playing", * Whether the #ClutterMedia actor is playing.
"Playing", *
"TRUE if playing.", * Since: 0.2
FALSE, */
G_PARAM_READWRITE | pspec = g_param_spec_boolean ("playing",
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | "Playing",
G_PARAM_STATIC_BLURB)); "Wheter the actor is playing",
FALSE,
CLUTTER_PARAM_READWRITE);
g_object_interface_install_property (g_iface, pspec);
g_object_interface_install_property /**
(g_iface, * ClutterMedia:progress:
g_param_spec_int *
("position", * The current progress of the playback, as a normalized
"Position", * value between 0.0 and 1.0.
"The position in the current stream in seconds.", *
0, G_MAXINT, 0, * Since: 1.0
G_PARAM_READWRITE | */
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | pspec = g_param_spec_double ("progress",
G_PARAM_STATIC_BLURB)); "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, * ClutterMedia:audio-volume:
g_param_spec_double *
("volume", * The volume of the audio, as a normalized value between
"Volume", * 0.0 and 1.0.
"The audio volume.", *
0, 100, 50, * Since: 1.0
G_PARAM_READWRITE | */
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | pspec = g_param_spec_double ("audio-volume",
G_PARAM_STATIC_BLURB)); "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, * ClutterMedia:can-seek:
g_param_spec_boolean *
("can-seek", * Whether the current stream is seekable.
"Can seek", *
"TRUE if the current stream is seekable.", * Since: 0.2
FALSE, */
G_PARAM_READABLE | pspec = g_param_spec_boolean ("can-seek",
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | "Can Seek",
G_PARAM_STATIC_BLURB)); "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, * ClutterMedia:buffer-fill:
g_param_spec_int *
("buffer-percent", * The fill level of the buffer for the current stream,
"Buffer percent", * as a value between 0.0 and 1.0.
"The percentage the current stream buffer is filled.", *
0, 100, 0, * Since: 1.0
G_PARAM_READABLE | */
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | pspec = g_param_spec_double ("buffer-fill",
G_PARAM_STATIC_BLURB)); "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, * ClutterMedia:duration:
g_param_spec_int *
("duration", * The duration of the current stream, in seconds
"Duration", *
"The duration of the current stream in seconds.", * Since: 0.2
0, G_MAXINT, 0, */
G_PARAM_READABLE | pspec = g_param_spec_uint ("duration",
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | "Duration",
G_PARAM_STATIC_BLURB)); "The duration of the stream, in seconds",
0, G_MAXUINT, 0,
CLUTTER_PARAM_READABLE);
g_object_interface_install_property (g_iface, pspec);
/** /**
* ClutterMedia::eos: * ClutterMedia::eos:
@ -178,7 +179,7 @@ clutter_media_base_init (gpointer g_iface)
g_signal_new ("eos", g_signal_new ("eos",
CLUTTER_TYPE_MEDIA, CLUTTER_TYPE_MEDIA,
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterMediaInterface, eos), G_STRUCT_OFFSET (ClutterMediaIface, eos),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
@ -195,7 +196,7 @@ clutter_media_base_init (gpointer g_iface)
g_signal_new ("error", g_signal_new ("error",
CLUTTER_TYPE_MEDIA, CLUTTER_TYPE_MEDIA,
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterMediaInterface, error), G_STRUCT_OFFSET (ClutterMediaIface, error),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__POINTER, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, 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: * clutter_media_set_uri:
* @media: #ClutterMedia object * @media: a #ClutterMedia
* @uri: URI * @uri: the URI of the media stream
* *
* Sets the URI of @media to @uri. * Sets the URI of @media to @uri.
* *
@ -214,37 +237,42 @@ clutter_media_base_init (gpointer g_iface)
*/ */
void void
clutter_media_set_uri (ClutterMedia *media, clutter_media_set_uri (ClutterMedia *media,
const char *uri) const gchar *uri)
{ {
g_return_if_fail (CLUTTER_IS_MEDIA(media)); 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: * clutter_media_get_uri:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* *
* Retrieves the URI from @media. * 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 * Since: 0.2
*/ */
const char* gchar *
clutter_media_get_uri (ClutterMedia *media) clutter_media_get_uri (ClutterMedia *media)
{ {
gchar *retval = NULL;
g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 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: * clutter_media_set_playing:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* @playing: TRUE to start playing, FALSE to stop. * @playing: %TRUE to start playing
* *
* Starts or stops @media playing. * Starts or stops playing of @media.
* *
* Since: 0.2 * Since: 0.2
*/ */
@ -254,7 +282,7 @@ clutter_media_set_playing (ClutterMedia *media,
{ {
g_return_if_fail (CLUTTER_IS_MEDIA(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 gboolean
clutter_media_get_playing (ClutterMedia *media) 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: * clutter_media_set_progress:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* @position: The desired position. * @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 void
clutter_media_set_position (ClutterMedia *media, clutter_media_set_progress (ClutterMedia *media,
int position) 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: * clutter_media_get_progress:
* @media: A #ClutterMedia object * @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 gdouble
clutter_media_get_position (ClutterMedia *media) 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: * clutter_media_set_audio_volume:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* @volume: The volume as a double between 0.0 and 1.0 * @volume: the volume as a double between 0.0 and 1.0
* *
* Sets the playback volume of @media to @volume. * Sets the playback volume of @media to @volume.
* *
* Since: 0.2 * Since: 1.0
*/ */
void void
clutter_media_set_volume (ClutterMedia *media, clutter_media_set_audio_volume (ClutterMedia *media,
double volume) gdouble volume)
{ {
g_return_if_fail (CLUTTER_IS_MEDIA(media)); 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: * clutter_media_get_audio_volume:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* *
* Retrieves the playback volume of @media. * Retrieves the playback volume of @media.
* *
* Return value: The playback volume between 0.0 and 1.0 * Return value: The playback volume between 0.0 and 1.0
* *
* Since: 0.2 * Since: 1.0
*/ */
double gdouble
clutter_media_get_volume (ClutterMedia *media) 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: * clutter_media_get_can_seek:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* *
* Retrieves whether @media is seekable or not. * Retrieves whether @media is seekable or not.
* *
@ -360,55 +401,67 @@ clutter_media_get_volume (ClutterMedia *media)
gboolean gboolean
clutter_media_get_can_seek (ClutterMedia *media) 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: * clutter_media_get_buffer_fill:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* *
* Retrieves the amount of the stream that is buffered. * 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 gdouble
clutter_media_get_buffer_percent (ClutterMedia *media) 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: * clutter_media_get_duration:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* *
* Retrieves the duration of the media stream that @media represents. * 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 * Since: 0.2
*/ */
int guint
clutter_media_get_duration (ClutterMedia *media) clutter_media_get_duration (ClutterMedia *media)
{ {
guint retval = 0;
g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 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 */ /* helper funcs */
/** /**
* clutter_media_set_filename: * clutter_media_set_filename:
* @media: A #ClutterMedia object * @media: a #ClutterMedia
* @filename: A filename to media file. * @filename: A filename
* *
* Sets the filename of the media source. * Sets the source of @media using a file path.
* *
* Since: 0.2 * Since: 0.2
*/ */

View File

@ -3,9 +3,11 @@
* *
* An OpenGL based 'interactive canvas' library. * An OpenGL based 'interactive canvas' library.
* *
* Authored By Matthew Allum <mallum@openedhand.com> * Authored By: Matthew Allum <mallum@openedhand.com>
* Emmanuele Bassi <ebassi@linux.intel.com>
* *
* Copyright (C) 2006 OpenedHand * Copyright (C) 2006 OpenedHand
* Copyright (C) 2009 Intel Corp.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * 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_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)) #define CLUTTER_MEDIA_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_MEDIA, ClutterMediaInterface))
typedef struct _ClutterMedia ClutterMedia; /* dummy typedef */ typedef struct _ClutterMedia ClutterMedia; /* dummy typedef */
typedef struct _ClutterMediaInterface ClutterMediaInterface; typedef struct _ClutterMediaIface ClutterMediaIface;
struct _ClutterMediaInterface struct _ClutterMediaIface
{ {
/*< private >*/ /*< private >*/
GTypeInterface base_iface; 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);
/* signals */ /* signals */
void (* eos) (ClutterMedia *media); void (* eos) (ClutterMedia *media);
void (* error) (ClutterMedia *media, void (* error) (ClutterMedia *media,
GError *error); 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 void clutter_media_set_playing (ClutterMedia *media,
clutter_media_set_uri (ClutterMedia *media, gboolean playing);
const char *uri); gboolean clutter_media_get_playing (ClutterMedia *media);
const char * void clutter_media_set_progress (ClutterMedia *media,
clutter_media_get_uri (ClutterMedia *media); gdouble progress);
gdouble clutter_media_get_progress (ClutterMedia *media);
void void clutter_media_set_audio_volume (ClutterMedia *media,
clutter_media_set_playing (ClutterMedia *media, gdouble volume);
gboolean playing); gdouble clutter_media_get_audio_volume (ClutterMedia *media);
gboolean clutter_media_get_can_seek (ClutterMedia *media);
gboolean gdouble clutter_media_get_buffer_fill (ClutterMedia *media);
clutter_media_get_playing (ClutterMedia *media); guint clutter_media_get_duration (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);
G_END_DECLS G_END_DECLS

View File

@ -1217,11 +1217,11 @@ clutter_path_node_distance (const ClutterKnot *start,
* If we are using limited precision sqrti implementation, fallback on * If we are using limited precision sqrti implementation, fallback on
* clib sqrt if the precission would be less than 10% * 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) if (t <= COGL_SQRTI_ARG_10_PERCENT)
return cogl_sqrti (t); return cogl_sqrti (t);
else else
return COGL_FLOAT_TO_INT (sqrt(t)); return COGL_FLOAT_TO_INT (sqrtf(t));
#else #else
return cogl_sqrti (t); return cogl_sqrti (t);
#endif #endif

View File

@ -194,6 +194,8 @@ void _clutter_backend_init_events (ClutterBackend *backend);
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend); ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
ClutterUnit _clutter_backend_get_units_per_em (ClutterBackend *backend);
void _clutter_feature_init (void); void _clutter_feature_init (void);
/* Picking code */ /* Picking code */

View File

@ -769,7 +769,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
stage_signals[QUEUE_REDRAW] = stage_signals[QUEUE_REDRAW] =
g_signal_new (I_("queue-redraw"), g_signal_new (I_("queue-redraw"),
G_TYPE_FROM_CLASS (gobject_class), G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, queue_redraw), G_STRUCT_OFFSET (ClutterStageClass, queue_redraw),
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
@ -815,15 +815,15 @@ clutter_stage_init (ClutterStage *self)
priv->color = default_stage_color; priv->color = default_stage_color;
priv->perspective.fovy = COGL_FIXED_60; /* 60 Degrees */ priv->perspective.fovy = 60.0; /* 60 Degrees */
priv->perspective.aspect = COGL_FIXED_1; priv->perspective.aspect = 1.0;
priv->perspective.z_near = COGL_FIXED_FROM_FLOAT (0.1); priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (0.1);
priv->perspective.z_far = COGL_FIXED_FROM_FLOAT (100.0); priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (100.0);
/* depth cueing */ /* depth cueing */
priv->fog.density = COGL_FIXED_FROM_FLOAT (0.1); priv->fog.density = CLUTTER_FLOAT_TO_FIXED (0.1);
priv->fog.z_near = COGL_FIXED_FROM_FLOAT (1.0); priv->fog.z_near = CLUTTER_FLOAT_TO_FIXED (1.0);
priv->fog.z_far = COGL_FIXED_FROM_FLOAT (2.0); priv->fog.z_far = CLUTTER_FLOAT_TO_FIXED (2.0);
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
clutter_stage_set_key_focus (self, NULL); clutter_stage_set_key_focus (self, NULL);
@ -979,10 +979,10 @@ clutter_stage_set_perspective (ClutterStage *stage,
priv = stage->priv; priv = stage->priv;
priv->perspective.fovy = COGL_FIXED_FROM_FLOAT (fovy); priv->perspective.fovy = CLUTTER_FLOAT_TO_FIXED (fovy);
priv->perspective.aspect = COGL_FIXED_FROM_FLOAT (aspect); priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED (aspect);
priv->perspective.z_near = COGL_FIXED_FROM_FLOAT (z_near); priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (z_near);
priv->perspective.z_far = COGL_FIXED_FROM_FLOAT (z_far); priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (z_far);
/* this will cause the viewport to be reset; see /* this will cause the viewport to be reset; see
* clutter_maybe_setup_viewport() inside clutter-main.c * clutter_maybe_setup_viewport() inside clutter-main.c
@ -1018,16 +1018,16 @@ clutter_stage_get_perspective (ClutterStage *stage,
priv = stage->priv; priv = stage->priv;
if (fovy) if (fovy)
*fovy = COGL_FIXED_TO_FLOAT (priv->perspective.fovy); *fovy = CLUTTER_FIXED_TO_FLOAT (priv->perspective.fovy);
if (aspect) if (aspect)
*aspect = COGL_FIXED_TO_FLOAT (priv->perspective.aspect); *aspect = CLUTTER_FIXED_TO_FLOAT (priv->perspective.aspect);
if (z_near) 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) 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; priv = stage->priv;
if (density) if (density)
*density = COGL_FIXED_TO_FLOAT (priv->fog.density); *density = CLUTTER_FIXED_TO_FLOAT (priv->fog.density);
if (z_near) 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) 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 = stage->priv;
priv->fog.density = COGL_FIXED_FROM_FLOAT (density); priv->fog.density = CLUTTER_FLOAT_TO_FIXED (density);
priv->fog.z_near = COGL_FIXED_FROM_FLOAT (z_near); priv->fog.z_near = CLUTTER_FLOAT_TO_FIXED (z_near);
priv->fog.z_far = COGL_FIXED_FROM_FLOAT (z_far); priv->fog.z_far = CLUTTER_FLOAT_TO_FIXED (z_far);
if (priv->use_fog && CLUTTER_ACTOR_IS_VISIBLE (stage)) if (priv->use_fog && CLUTTER_ACTOR_IS_VISIBLE (stage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (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); res = clutter_backend_get_resolution (context->backend);
return COGL_FIXED_FROM_FLOAT (res); return CLUTTER_FLOAT_TO_FIXED (res);
} }
/*** Perspective boxed type ******/ /*** Perspective boxed type ******/

View File

@ -202,31 +202,16 @@ static gint
offset_to_bytes (const gchar *text, offset_to_bytes (const gchar *text,
gint pos) gint pos)
{ {
gchar *c = NULL; const gchar *ptr;
gint i, j, len;
if (pos < 0) if (pos < 0)
return strlen (text); return strlen (text);
c = g_utf8_next_char (text); /* Loop over each character in the string until we either reach the
j = 1; end or the requested position */
len = strlen (text); for (ptr = text; *ptr && pos-- > 0; ptr = g_utf8_next_char (ptr));
for (i = 0; i < len; i++) return ptr - text;
{
if (&text[i] == c)
{
if (j == pos)
break;
else
{
c = g_utf8_next_char (c);
j++;
}
}
}
return i;
} }
#define bytes_to_offset(t,p) (g_utf8_pointer_to_offset ((t), (t) + (p))) #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') if (key_unichar == '\r')
key_unichar = '\n'; 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 /* truncate the eventual selection so that the
* Unicode character can replace it * Unicode character can replace it
@ -1291,7 +1278,7 @@ clutter_text_real_move_up (ClutterText *self,
PangoLayoutLine *layout_line; PangoLayoutLine *layout_line;
PangoLayout *layout; PangoLayout *layout;
gint line_no; gint line_no;
gint index_; gint index_, trailing;
gint x; gint x;
layout = clutter_text_get_layout (self); layout = clutter_text_get_layout (self);
@ -1311,21 +1298,23 @@ clutter_text_real_move_up (ClutterText *self,
if (priv->x_pos != -1) if (priv->x_pos != -1)
x = priv->x_pos; x = priv->x_pos;
else
priv->x_pos = x;
layout_line = pango_layout_get_line_readonly (layout, line_no); layout_line = pango_layout_get_line_readonly (layout, line_no);
if (!layout_line) if (!layout_line)
return FALSE; 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_); 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))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
@ -1342,7 +1331,7 @@ clutter_text_real_move_down (ClutterText *self,
PangoLayoutLine *layout_line; PangoLayoutLine *layout_line;
PangoLayout *layout; PangoLayout *layout;
gint line_no; gint line_no;
gint index_; gint index_, trailing;
gint x; gint x;
layout = clutter_text_get_layout (self); layout = clutter_text_get_layout (self);
@ -1358,21 +1347,23 @@ clutter_text_real_move_down (ClutterText *self,
if (priv->x_pos != -1) if (priv->x_pos != -1)
x = priv->x_pos; x = priv->x_pos;
else
priv->x_pos = x;
layout_line = pango_layout_get_line_readonly (layout, line_no + 1); layout_line = pango_layout_get_line_readonly (layout, line_no + 1);
if (!layout_line) if (!layout_line)
return FALSE; 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_); 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))) if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self); clutter_text_clear_selection (self);
@ -3314,6 +3305,10 @@ clutter_text_set_cursor_position (ClutterText *self,
else else
priv->position = position; 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)) if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
} }

View File

@ -101,6 +101,13 @@ struct _ClutterTexturePrivate
guint repeat_y : 1; guint repeat_y : 1;
guint in_dispose : 1; guint in_dispose : 1;
guint keep_aspect_ratio : 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 enum
@ -118,13 +125,17 @@ enum
PROP_COGL_MATERIAL, PROP_COGL_MATERIAL,
#endif #endif
PROP_FILENAME, PROP_FILENAME,
PROP_KEEP_ASPECT_RATIO PROP_KEEP_ASPECT_RATIO,
PROP_LOAD_ASYNC
}; };
enum enum
{ {
SIZE_CHANGE, SIZE_CHANGE,
PIXBUF_CHANGE, PIXBUF_CHANGE,
LOAD_SUCCESS,
LOAD_FINISHED,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -264,18 +275,25 @@ clutter_texture_realize (ClutterActor *actor)
if (priv->fbo_source) if (priv->fbo_source)
{ {
CoglTextureFlags flags = COGL_TEXTURE_NONE;
gint max_waste = -1;
/* Handle FBO's */ /* Handle FBO's */
if (priv->fbo_texture != COGL_INVALID_HANDLE) if (priv->fbo_texture != COGL_INVALID_HANDLE)
cogl_texture_unref (priv->fbo_texture); cogl_texture_unref (priv->fbo_texture);
priv->fbo_texture if (!priv->no_slice)
= cogl_texture_new_with_size max_waste = priv->max_tile_waste;
(priv->width,
priv->height, if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH)
priv->no_slice ? -1 : priv->max_tile_waste, flags |= COGL_TEXTURE_AUTO_MIPMAP;
priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH,
COGL_PIXEL_FORMAT_RGBA_8888); 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, cogl_texture_set_filters (priv->fbo_texture,
clutter_texture_quality_to_cogl_min_filter (priv->filter_quality), 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 */ /* Set the natural width so as to preserve the aspect ratio */
ClutterFixed ratio, height; ClutterFixed ratio, height;
ratio = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (priv->width), ratio = CLUTTER_FIXED_DIV ((float)(priv->width),
COGL_FIXED_FROM_INT (priv->height)); (float)(priv->height));
height = CLUTTER_UNITS_TO_FIXED (for_height); height = CLUTTER_UNITS_TO_FIXED (for_height);
*natural_width_p = *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 */ /* Set the natural height so as to preserve the aspect ratio */
ClutterFixed ratio, width; ClutterFixed ratio, width;
ratio = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (priv->height), ratio = CLUTTER_FIXED_DIV ((float)(priv->height),
COGL_FIXED_FROM_INT (priv->width)); (float)(priv->width));
width = CLUTTER_UNITS_TO_FIXED (for_width); width = CLUTTER_UNITS_TO_FIXED (for_width);
*natural_height_p = *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 */ /* Convert the coordinates back to [-1,1] range */
cogl_get_viewport (viewport); cogl_get_viewport (viewport);
tx_min = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_min), viewport[2]) tx_min = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_min), viewport[2])
* 2 - COGL_FIXED_1; * 2 - 1.0;
tx_max = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_max), viewport[2]) tx_max = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (x_max), viewport[2])
* 2 - COGL_FIXED_1; * 2 - 1.0;
ty_min = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_min), viewport[3]) ty_min = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_min), viewport[3])
* 2 - COGL_FIXED_1; * 2 - 1.0;
ty_max = COGL_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_max), viewport[3]) ty_max = CLUTTER_FIXED_DIV (CLUTTER_UNITS_TO_FIXED (y_max), viewport[3])
* 2 - COGL_FIXED_1; * 2 - 1.0;
/* Set up a projection matrix so that the actor will be projected as /* Set up a projection matrix so that the actor will be projected as
if it was drawn at its original location */ if it was drawn at its original location */
tan_angle = cogl_angle_tan (COGL_ANGLE_FROM_DEGX (perspective.fovy / 2)); tan_angle = tanf ((perspective.fovy / 2) * (G_PI/180.0));
near_size = COGL_FIXED_MUL (perspective.z_near, tan_angle); near_size = CLUTTER_FIXED_MUL (perspective.z_near, tan_angle);
cogl_frustum (COGL_FIXED_MUL (tx_min, near_size), cogl_frustum (CLUTTER_FIXED_MUL (tx_min, near_size),
COGL_FIXED_MUL (tx_max, near_size), CLUTTER_FIXED_MUL (tx_max, near_size),
COGL_FIXED_MUL (-ty_min, near_size), CLUTTER_FIXED_MUL (-ty_min, near_size),
COGL_FIXED_MUL (-ty_max, near_size), CLUTTER_FIXED_MUL (-ty_max, near_size),
perspective.z_near, perspective.z_far); perspective.z_near, perspective.z_far);
} }
@ -603,16 +621,16 @@ clutter_texture_paint (ClutterActor *self)
clutter_actor_get_opacity (self)); clutter_actor_get_opacity (self));
if (priv->repeat_x && priv->width > 0) if (priv->repeat_x && priv->width > 0)
t_w = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (x_2 - x_1), t_w = CLUTTER_FIXED_DIV ((float)(x_2 - x_1),
COGL_FIXED_FROM_INT (priv->width)); (float)(priv->width));
else else
t_w = COGL_FIXED_1; t_w = 1.0;
if (priv->repeat_y && priv->height > 0) if (priv->repeat_y && priv->height > 0)
t_h = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (y_2 - y_1), t_h = CLUTTER_FIXED_DIV ((float)(y_2 - y_1),
COGL_FIXED_FROM_INT (priv->height)); (float)(priv->height));
else else
t_h = COGL_FIXED_1; t_h = 1.0;
/* Paint will have translated us */ /* Paint will have translated us */
#if USE_COGL_MATERIAL #if USE_COGL_MATERIAL
@ -623,18 +641,57 @@ clutter_texture_paint (ClutterActor *self)
tex_coords[2] = t_w; tex_coords[2] = t_w;
tex_coords[3] = t_h; tex_coords[3] = t_h;
cogl_material_rectangle (0, 0, cogl_material_rectangle (0, 0,
COGL_FIXED_FROM_INT (x_2 - x_1), (float)(x_2 - x_1),
COGL_FIXED_FROM_INT (y_2 - y_1), (float)(y_2 - y_1),
4, 4,
tex_coords); tex_coords);
#else #else
cogl_texture_rectangle (priv->texture, 0, 0, cogl_texture_rectangle (priv->texture, 0, 0,
COGL_FIXED_FROM_INT (x_2 - x_1), (float)(x_2 - x_1),
COGL_FIXED_FROM_INT (y_2 - y_1), (float)(y_2 - y_1),
0, 0, t_w, t_h); 0, 0, t_w, t_h);
#endif #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 static void
clutter_texture_dispose (GObject *object) clutter_texture_dispose (GObject *object)
{ {
@ -659,7 +716,9 @@ clutter_texture_dispose (GObject *object)
g_free (priv->local_data); g_free (priv->local_data);
priv->local_data = NULL; priv->local_data = NULL;
} }
clutter_texture_async_load_cancel (texture);
G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
} }
@ -725,6 +784,9 @@ clutter_texture_set_property (GObject *object,
case PROP_KEEP_ASPECT_RATIO: case PROP_KEEP_ASPECT_RATIO:
priv->keep_aspect_ratio = g_value_get_boolean (value); priv->keep_aspect_ratio = g_value_get_boolean (value);
break; break;
case PROP_LOAD_ASYNC:
priv->load_async = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -782,6 +844,9 @@ clutter_texture_get_property (GObject *object,
case PROP_KEEP_ASPECT_RATIO: case PROP_KEEP_ASPECT_RATIO:
g_value_set_boolean (value, priv->keep_aspect_ratio); g_value_set_boolean (value, priv->keep_aspect_ratio);
break; break;
case PROP_LOAD_ASYNC:
g_value_set_boolean (value, priv->load_async);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -868,7 +933,7 @@ clutter_texture_class_init (ClutterTextureClass *klass)
"smaller values less texture memory.", "smaller values less texture memory.",
-1, -1,
G_MAXINT, G_MAXINT,
64, 63,
G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE)); G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
g_object_class_install_property g_object_class_install_property
@ -918,6 +983,29 @@ clutter_texture_class_init (ClutterTextureClass *klass)
FALSE, FALSE,
CLUTTER_PARAM_READWRITE)); 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: * ClutterTexture::size-change:
* @texture: the texture which received the signal * @texture: the texture which received the signal
@ -953,6 +1041,27 @@ clutter_texture_class_init (ClutterTextureClass *klass)
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, G_TYPE_NONE,
0); 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; static ClutterScriptableIface *parent_scriptable_iface = NULL;
@ -1016,7 +1125,7 @@ clutter_texture_init (ClutterTexture *self)
self->priv = priv = CLUTTER_TEXTURE_GET_PRIVATE (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->filter_quality = CLUTTER_TEXTURE_QUALITY_MEDIUM;
priv->repeat_x = FALSE; priv->repeat_x = FALSE;
priv->repeat_y = FALSE; priv->repeat_y = FALSE;
@ -1286,19 +1395,25 @@ clutter_texture_set_from_data (ClutterTexture *texture,
gint bpp, gint bpp,
GError **error) GError **error)
{ {
CoglHandle new_texture; ClutterTexturePrivate *priv = texture->priv;
ClutterTexturePrivate *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 if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH)
(width, height, flags |= COGL_TEXTURE_AUTO_MIPMAP;
priv->no_slice ? -1 : priv->max_tile_waste,
priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, new_texture = cogl_texture_new_from_data (width, height,
source_format, max_waste, flags,
COGL_PIXEL_FORMAT_ANY, source_format,
rowstride, COGL_PIXEL_FORMAT_ANY,
data)) == COGL_INVALID_HANDLE) rowstride,
data);
if (G_UNLIKELY (new_texture == COGL_INVALID_HANDLE))
{ {
g_set_error (error, CLUTTER_TEXTURE_ERROR, g_set_error (error, CLUTTER_TEXTURE_ERROR,
CLUTTER_TEXTURE_ERROR_BAD_FORMAT, CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
@ -1315,6 +1430,8 @@ clutter_texture_set_from_data (ClutterTexture *texture,
cogl_texture_unref (new_texture); cogl_texture_unref (new_texture);
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error);
return TRUE; return TRUE;
} }
@ -1409,14 +1526,14 @@ clutter_texture_set_from_rgb_data (ClutterTexture *texture,
* Return value: %TRUE if the texture was successfully updated * Return value: %TRUE if the texture was successfully updated
* *
* Since: 0.4 * Since: 0.4
**/ */
gboolean gboolean
clutter_texture_set_from_yuv_data (ClutterTexture *texture, clutter_texture_set_from_yuv_data (ClutterTexture *texture,
const guchar *data, const guchar *data,
gint width, gint width,
gint height, gint height,
ClutterTextureFlags flags, ClutterTextureFlags flags,
GError **error) GError **error)
{ {
ClutterTexturePrivate *priv; ClutterTexturePrivate *priv;
@ -1448,6 +1565,188 @@ clutter_texture_set_from_yuv_data (ClutterTexture *texture,
error); 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: * clutter_texture_set_from_file:
* @texture: A #ClutterTexture * @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 * Sets the #ClutterTexture image data from an image file. In case of
* failure, %FALSE is returned and @error is set. * 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 * Return value: %TRUE if the image was successfully loaded and set
* *
* Since: 0.8 * Since: 0.8
@ -1466,28 +1771,48 @@ clutter_texture_set_from_file (ClutterTexture *texture,
const gchar *filename, const gchar *filename,
GError **error) 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; priv = texture->priv;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if ((new_texture = cogl_texture_new_from_file if (priv->load_async)
(filename, {
priv->no_slice ? -1 : priv->max_tile_waste, clutter_texture_async_load_cancel (texture);
priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH,
COGL_PIXEL_FORMAT_ANY, priv->load_filename = g_strdup (filename);
error))
== COGL_INVALID_HANDLE) 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 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, g_set_error (error, CLUTTER_TEXTURE_ERROR,
CLUTTER_TEXTURE_ERROR_BAD_FORMAT, CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
"Failed to create COGL texture"); "Failed to create COGL texture");
} }
else
g_propagate_error (error, internal_error);
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error);
return FALSE; return FALSE;
} }
@ -1500,6 +1825,8 @@ clutter_texture_set_from_file (ClutterTexture *texture,
cogl_texture_unref (new_texture); cogl_texture_unref (new_texture);
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, error);
return TRUE; return TRUE;
} }
@ -1848,19 +2175,25 @@ on_fbo_source_size_change (GObject *object,
if (w != priv->width || h != priv->height) if (w != priv->width || h != priv->height)
{ {
CoglTextureFlags flags = COGL_TEXTURE_NONE;
/* tear down the FBO */ /* tear down the FBO */
cogl_offscreen_unref (priv->fbo_handle); cogl_offscreen_unref (priv->fbo_handle);
texture_free_gl_resources (texture); texture_free_gl_resources (texture);
priv->width = w; priv->width = w;
priv->height = h; priv->height = h;
priv->fbo_texture = cogl_texture_new_with_size (MAX (priv->width, 1), if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH)
MAX (priv->height, 1), flags |= COGL_TEXTURE_AUTO_MIPMAP;
-1,
priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH, priv->fdo_texture =
COGL_PIXEL_FORMAT_RGBA_8888); 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, cogl_texture_set_filters (priv->fbo_texture,
clutter_texture_quality_to_cogl_min_filter (priv->filter_quality), clutter_texture_quality_to_cogl_min_filter (priv->filter_quality),
@ -1876,7 +2209,7 @@ on_fbo_source_size_change (GObject *object,
return; 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->width = w;
priv->height = h; 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 static void

View File

@ -89,6 +89,8 @@ struct _ClutterTextureClass
gint width, gint width,
gint height); gint height);
void (*pixbuf_change) (ClutterTexture *texture); void (*pixbuf_change) (ClutterTexture *texture);
void (*load_finished) (ClutterTexture *texture,
GError *error);
/*< private >*/ /*< private >*/
/* padding, for future expansion */ /* padding, for future expansion */
@ -97,7 +99,6 @@ struct _ClutterTextureClass
void (*_clutter_texture3) (void); void (*_clutter_texture3) (void);
void (*_clutter_texture4) (void); void (*_clutter_texture4) (void);
void (*_clutter_texture5) (void); void (*_clutter_texture5) (void);
void (*_clutter_texture6) (void);
}; };
/** /**

View File

@ -1347,7 +1347,7 @@ clutter_timeline_get_progress (ClutterTimeline *timeline)
{ {
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0.); 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; priv = timeline->priv;
progress = COGL_FIXED_DIV (COGL_FIXED_FROM_INT (priv->current_frame_num), progress = CLUTTER_FIXED_DIV ((float)(priv->current_frame_num),
COGL_FIXED_FROM_INT (priv->n_frames)); (float)(priv->n_frames));
if (priv->direction == CLUTTER_TIMELINE_BACKWARD) if (priv->direction == CLUTTER_TIMELINE_BACKWARD)
progress = COGL_FIXED_1 - progress; progress = 1.0 - progress;
return progress; return progress;
} }

View File

@ -200,6 +200,7 @@ typedef enum {
* @CLUTTER_EXPO_OUT: exponential out progress * @CLUTTER_EXPO_OUT: exponential out progress
* @CLUTTER_EXPO_IN_OUT: exponential in-out progress * @CLUTTER_EXPO_IN_OUT: exponential in-out progress
* @CLUTTER_SMOOTH_IN_OUT: smoothstep 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 * The animation modes used by #ClutterAlpha and #ClutterAnimation. This
* enumeration can be expanded in later versions of Clutter. * enumeration can be expanded in later versions of Clutter.
@ -207,7 +208,7 @@ typedef enum {
* Since: 1.0 * Since: 1.0
*/ */
typedef enum { typedef enum {
CLUTTER_CUSTOM_MODE, CLUTTER_CUSTOM_MODE = 0,
CLUTTER_LINEAR, CLUTTER_LINEAR,
CLUTTER_SINE_IN, CLUTTER_SINE_IN,
@ -220,6 +221,8 @@ typedef enum {
CLUTTER_EXPO_OUT, CLUTTER_EXPO_OUT,
CLUTTER_EXPO_IN_OUT, CLUTTER_EXPO_IN_OUT,
CLUTTER_SMOOTH_IN_OUT, CLUTTER_SMOOTH_IN_OUT,
CLUTTER_ANIMATION_LAST
} ClutterAnimationMode; } ClutterAnimationMode;
G_END_DECLS G_END_DECLS

View File

@ -101,6 +101,81 @@
#include "clutter-units.h" #include "clutter-units.h"
#include "clutter-private.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 #ClutterUnit<!-- -->s 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 #ClutterUnit<!-- -->s
* 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 #ClutterUnit<!-- -->s 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 = { static GTypeInfo _info = {
0, 0,
NULL, NULL,
@ -119,14 +194,14 @@ static GTypeFundamentalInfo _finfo = { 0, };
static void static void
clutter_value_init_unit (GValue *value) clutter_value_init_unit (GValue *value)
{ {
value->data[0].v_int = 0; value->data[0].v_float = 0.0;
} }
static void static void
clutter_value_copy_unit (const GValue *src, clutter_value_copy_unit (const GValue *src,
GValue *dest) GValue *dest)
{ {
dest->data[0].v_int = src->data[0].v_int; dest->data[0].v_float = src->data[0].v_float;
} }
static gchar * static gchar *
@ -135,7 +210,7 @@ clutter_value_collect_unit (GValue *value,
GTypeCValue *collect_values, GTypeCValue *collect_values,
guint collect_flags) 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; return NULL;
} }
@ -146,13 +221,13 @@ clutter_value_lcopy_unit (const GValue *value,
GTypeCValue *collect_values, GTypeCValue *collect_values,
guint collect_flags) guint collect_flags)
{ {
gint32 *units_p = collect_values[0].v_pointer; gfloat *units_p = collect_values[0].v_pointer;
if (!units_p) if (!units_p)
return g_strdup_printf ("value location for `%s' passed as NULL", return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value)); G_VALUE_TYPE_NAME (value));
*units_p = value->data[0].v_int; *units_p = value->data[0].v_float;
return NULL; return NULL;
} }
@ -161,14 +236,14 @@ static void
clutter_value_transform_unit_int (const GValue *src, clutter_value_transform_unit_int (const GValue *src,
GValue *dest) 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 static void
clutter_value_transform_int_unit (const GValue *src, clutter_value_transform_int_unit (const GValue *src,
GValue *dest) 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 = { static const GTypeValueTable _clutter_unit_value_table = {
@ -176,7 +251,7 @@ static const GTypeValueTable _clutter_unit_value_table = {
NULL, NULL,
clutter_value_copy_unit, clutter_value_copy_unit,
NULL, NULL,
"i", "d",
clutter_value_collect_unit, clutter_value_collect_unit,
"p", "p",
clutter_value_lcopy_unit clutter_value_lcopy_unit
@ -219,7 +294,7 @@ clutter_value_set_unit (GValue *value,
{ {
g_return_if_fail (CLUTTER_VALUE_HOLDS_UNIT (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); 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 static void
@ -254,7 +329,7 @@ static void
param_unit_set_default (GParamSpec *pspec, param_unit_set_default (GParamSpec *pspec,
GValue *value) 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 static gboolean
@ -262,26 +337,15 @@ param_unit_validate (GParamSpec *pspec,
GValue *value) GValue *value)
{ {
ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec); ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec);
gint oval = CLUTTER_UNITS_TO_INT (value->data[0].v_int); gfloat oval = value->data[0].v_float;
gint min, max, val;
g_assert (CLUTTER_IS_PARAM_SPEC_UNIT (pspec)); g_assert (CLUTTER_IS_PARAM_SPEC_UNIT (pspec));
/* we compare the integer part of the value because the minimum value->data[0].v_float = CLAMP (value->data[0].v_float,
* and maximum values cover just that part of the representation uspec->minimum,
*/ uspec->maximum);
min = uspec->minimum;
max = uspec->maximum;
val = CLUTTER_UNITS_TO_INT (value->data[0].v_int);
val = CLAMP (val, min, max); return value->data[0].v_float != oval;
if (val != oval)
{
value->data[0].v_int = val;
return TRUE;
}
return FALSE;
} }
static gint static gint
@ -289,10 +353,12 @@ param_unit_values_cmp (GParamSpec *pspec,
const GValue *value1, const GValue *value1,
const GValue *value2) const GValue *value2)
{ {
if (value1->data[0].v_int < value2->data[0].v_int) gfloat epsilon = FLOAT_EPSILON;
return -1;
if (value1->data[0].v_float < value2->data[0].v_float)
return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
else 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 GType

View File

@ -4,9 +4,11 @@
* *
* An OpenGL based 'interactive canvas' library. * An OpenGL based 'interactive canvas' library.
* *
* Authored By Tomas Frydrych <tf@openedhand.com> * Authored By: Tomas Frydrych <tf@openedhand.com>
* Emmanuele Bassu <ebassi@linux.intel.com>
* *
* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -42,24 +44,32 @@ G_BEGIN_DECLS
* *
* Since: 0.4 * Since: 0.4
*/ */
typedef gint32 ClutterUnit; typedef float ClutterUnit;
/* #define CLUTTER_UNITS_FROM_INT(x) ((float)(x))
* Currently CLUTTER_UNIT maps directly onto ClutterFixed. Nevertheless, the #define CLUTTER_UNITS_TO_INT(x) ((int)(x))
* _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) (COGL_FIXED_FROM_INT ((x))) #define CLUTTER_UNITS_FROM_FLOAT(x) (x)
#define CLUTTER_UNITS_TO_INT(x) (COGL_FIXED_TO_INT ((x))) #define CLUTTER_UNITS_TO_FLOAT(x) (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_FIXED(x) (x) #define CLUTTER_UNITS_FROM_FIXED(x) (x)
#define CLUTTER_UNITS_TO_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: * 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_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: * CLUTTER_UNITS_FROM_PANGO_UNIT:
* @x: value in Pango units * @x: value in Pango units
@ -92,7 +99,7 @@ typedef gint32 ClutterUnit;
* *
* Since: 0.6 * 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: * CLUTTER_UNITS_TO_PANGO_UNIT:
@ -102,19 +109,7 @@ typedef gint32 ClutterUnit;
* *
* Since: 0.6 * Since: 0.6
*/ */
#define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((x) >> 6) #define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((int)((x) * 1024))
#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)
/** /**
* CLUTTER_UNITS_FROM_MM: * CLUTTER_UNITS_FROM_MM:
@ -124,11 +119,7 @@ typedef gint32 ClutterUnit;
* *
* Since: 0.6 * Since: 0.6
*/ */
#define CLUTTER_UNITS_FROM_MM(x) \ #define CLUTTER_UNITS_FROM_MM(x) (clutter_units_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))
/** /**
* CLUTTER_UNITS_FROM_POINTS: * CLUTTER_UNITS_FROM_POINTS:
@ -138,11 +129,21 @@ typedef gint32 ClutterUnit;
* *
* Since: 0.6 * Since: 0.6
*/ */
#define CLUTTER_UNITS_FROM_POINTS(x) \ #define CLUTTER_UNITS_FROM_POINTS(x) (clutter_units_pt (x))
CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 72.0))
#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 #ClutterUnit<!-- -->s
*
* 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_UNIT (clutter_unit_get_type ())
#define CLUTTER_TYPE_PARAM_UNIT (clutter_param_unit_get_type ()) #define CLUTTER_TYPE_PARAM_UNIT (clutter_param_unit_get_type ())
@ -156,7 +157,7 @@ typedef gint32 ClutterUnit;
* *
* Since: 0.8 * Since: 0.8
*/ */
#define CLUTTER_MAXUNIT (0x7fffffff) #define CLUTTER_MAXUNIT (G_MAXFLOAT)
/** /**
* CLUTTER_MINUNIT: * CLUTTER_MINUNIT:
@ -165,7 +166,7 @@ typedef gint32 ClutterUnit;
* *
* Since: 0.8 * Since: 0.8
*/ */
#define CLUTTER_MINUNIT (0x80000000) #define CLUTTER_MINUNIT (-G_MAXFLOAT)
/** /**
* CLUTTER_VALUE_HOLDS_UNIT: * CLUTTER_VALUE_HOLDS_UNIT:

View File

@ -30,6 +30,7 @@
#include "clutter-actor.h" #include "clutter-actor.h"
#include "clutter-alpha.h" #include "clutter-alpha.h"
#include "clutter-animatable.h"
#include "clutter-animation.h" #include "clutter-animation.h"
#include "clutter-backend.h" #include "clutter-backend.h"
#include "clutter-behaviour-depth.h" #include "clutter-behaviour-depth.h"
@ -46,7 +47,6 @@
#include "clutter-color.h" #include "clutter-color.h"
#include "clutter-container.h" #include "clutter-container.h"
#include "clutter-deprecated.h" #include "clutter-deprecated.h"
#include "clutter-effect.h"
#include "clutter-event.h" #include "clutter-event.h"
#include "clutter-feature.h" #include "clutter-feature.h"
#include "clutter-frame-source.h" #include "clutter-frame-source.h"

View File

@ -68,22 +68,22 @@ void cogl_color_set_from_4d (CoglColor *dest,
gdouble alpha); gdouble alpha);
/** /**
* cogl_color_set_from_4x: * cogl_color_set_from_4f:
* @dest: return location for a #CoglColor * @dest: return location for a #CoglColor
* @red: value of the red 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 %COGL_FIXED_1 * @green: value of the green channel, between 0 and %1.0
* @blue: value of the blue channel, between 0 and %COGL_FIXED_1 * @blue: value of the blue channel, between 0 and %1.0
* @alpha: value of the alpha channel, between 0 and %COGL_FIXED_1 * @alpha: value of the alpha channel, between 0 and %1.0
* *
* Sets the values of the passed channels into a #CoglColor * Sets the values of the passed channels into a #CoglColor
* *
* Since: 1.0 * Since: 1.0
*/ */
void cogl_color_set_from_4x (CoglColor *dest, void cogl_color_set_from_4f (CoglColor *dest,
CoglFixed red, float red,
CoglFixed green, float green,
CoglFixed blue, float blue,
CoglFixed alpha); float alpha);
/** /**
* cogl_color_get_red_byte: * cogl_color_get_red_byte:
@ -194,52 +194,52 @@ float cogl_color_get_alpha_float (const CoglColor *color);
* @color: a #CoglColor * @color: a #CoglColor
* *
* Retrieves the red channel of @color as a fixed point * 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 * Return value: the red channel of the passed color
* *
* Since: 1.0 * Since: 1.0
*/ */
CoglFixed cogl_color_get_red (const CoglColor *color); float cogl_color_get_red (const CoglColor *color);
/** /**
* cogl_color_get_green: * cogl_color_get_green:
* @color: a #CoglColor * @color: a #CoglColor
* *
* Retrieves the green channel of @color as a fixed point * 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 * Return value: the green channel of the passed color
* *
* Since: 1.0 * Since: 1.0
*/ */
CoglFixed cogl_color_get_green (const CoglColor *color); float cogl_color_get_green (const CoglColor *color);
/** /**
* cogl_color_get_blue: * cogl_color_get_blue:
* @color: a #CoglColor * @color: a #CoglColor
* *
* Retrieves the blue channel of @color as a fixed point * 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 * Return value: the blue channel of the passed color
* *
* Since: 1.0 * Since: 1.0
*/ */
CoglFixed cogl_color_get_blue (const CoglColor *color); float cogl_color_get_blue (const CoglColor *color);
/** /**
* cogl_color_get_alpha: * cogl_color_get_alpha:
* @color: a #CoglColor * @color: a #CoglColor
* *
* Retrieves the alpha channel of @color as a fixed point * 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 * Return value: the alpha channel of the passed color
* *
* Since: 1.0 * Since: 1.0
*/ */
CoglFixed cogl_color_get_alpha (const CoglColor *color); float cogl_color_get_alpha (const CoglColor *color);
/** /**
* cogl_set_source_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. * Sets the source color using normalized values for each component.
* This color will be used for any subsequent drawing operation. * 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. * if you already have the color components.
* *
* Since: 1.0 * Since: 1.0
@ -276,25 +276,25 @@ void cogl_set_source_color4ub (guint8 red,
guint8 alpha); guint8 alpha);
/** /**
* cogl_set_source_color4x: * cogl_set_source_color4f:
* @red: value of the red 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 %COGL_FIXED_1 * @green: value of the green channel, between 0 and %1.0
* @blue: value of the blue channel, between 0 and %COGL_FIXED_1 * @blue: value of the blue channel, between 0 and %1.0
* @alpha: value of the alpha channel, between 0 and %COGL_FIXED_1 * @alpha: value of the alpha channel, between 0 and %1.0
* *
* Sets the source color using normalized values for each component. * Sets the source color using normalized values for each component.
* This color will be used for any subsequent drawing operation. * This color will be used for any subsequent drawing operation.
* *
* The value for each component is a fixed point number in the range * 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. * range, they will be clamped.
* *
* Since: 1.0 * Since: 1.0
*/ */
void cogl_set_source_color4x (CoglFixed red, void cogl_set_source_color4f (float red,
CoglFixed green, float green,
CoglFixed blue, float blue,
CoglFixed alpha); float alpha);
G_END_DECLS G_END_DECLS

View File

@ -455,6 +455,18 @@ G_BEGIN_DECLS
*/ */
CoglFixed cogl_fixed_sin (CoglFixed angle); 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: * cogl_fixed_cos:
* @angle: a #CoglFixed number * @angle: a #CoglFixed number

View File

@ -60,24 +60,10 @@ G_BEGIN_DECLS
* Fills a rectangle at the given coordinates with the current * Fills a rectangle at the given coordinates with the current
* drawing color in a highly optimizied fashion. * drawing color in a highly optimizied fashion.
**/ **/
void cogl_rectangle (gint x, void cogl_rectangle (float x,
gint y, float y,
guint width, float width,
guint height); float 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);
/** /**
* cogl_path_fill: * 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 * Moves the pen to the given location. If there is an existing path
* this will start a new disjoint subpath. * this will start a new disjoint subpath.
**/ **/
void cogl_path_move_to (CoglFixed x, void cogl_path_move_to (float x,
CoglFixed y); 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 * location. If there is an existing path this will start a new
* disjoint subpath. * disjoint subpath.
**/ **/
void cogl_path_rel_move_to (CoglFixed x, void cogl_path_rel_move_to (float x,
CoglFixed y); float y);
/** /**
* cogl_path_line_to: * 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 * Adds a straight line segment to the current path that ends at the
* given coordinates. * given coordinates.
**/ **/
void cogl_path_line_to (CoglFixed x, void cogl_path_line_to (float x,
CoglFixed y); float y);
/** /**
* cogl_path_rel_line_to: * 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 * Adds a straight line segment to the current path that ends at the
* given coordinates relative to the current pen location. * given coordinates relative to the current pen location.
**/ **/
void cogl_path_rel_line_to (CoglFixed x, void cogl_path_rel_line_to (float x,
CoglFixed y); 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 * of the arc. If you perform a move_to to the arcs start just before
* drawing it you create a free standing arc. * drawing it you create a free standing arc.
**/ **/
void cogl_path_arc (CoglFixed center_x, void cogl_path_arc (float center_x,
CoglFixed center_y, float center_y,
CoglFixed radius_x, float radius_x,
CoglFixed radius_y, float radius_y,
CoglAngle angle_1, float angle_1,
CoglAngle angle_2); 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 * second, third and fourth control points and using current pen location
* as the first control point. * as the first control point.
**/ **/
void cogl_path_curve_to (CoglFixed x1, void cogl_path_curve_to (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed x3, float x3,
CoglFixed y3); float y3);
/** /**
* cogl_path_rel_curve_to: * 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 * as the first control point. The given coordinates are relative to the
* current pen location. * current pen location.
*/ */
void cogl_path_rel_curve_to (CoglFixed x1, void cogl_path_rel_curve_to (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed x3, float x3,
CoglFixed y3); float y3);
/** /**
* cogl_path_close: * cogl_path_close:
@ -258,10 +244,10 @@ void cogl_path_close (void);
* coordinates. If there is an existing path this will start a new * coordinates. If there is an existing path this will start a new
* disjoint sub-path. * disjoint sub-path.
**/ **/
void cogl_path_line (CoglFixed x1, void cogl_path_line (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2); float y2);
/** /**
* cogl_path_polyline: * 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 * fashion for the rest of the vertices. (num_points - 1) segments will
* be constructed. * be constructed.
**/ **/
void cogl_path_polyline (CoglFixed *coords, void cogl_path_polyline (float *coords,
gint num_points); 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 * represents the Y coordinate of the first vertex, continuing in the same
* fashion for the rest of the vertices. * fashion for the rest of the vertices.
**/ **/
void cogl_path_polygon (CoglFixed *coords, void cogl_path_polygon (float *coords,
gint num_points); gint num_points);
@ -313,10 +299,10 @@ void cogl_path_polygon (CoglFixed *coords,
* Constructs a rectangular shape at the given coordinates. If there * Constructs a rectangular shape at the given coordinates. If there
* is an existing path this will start a new disjoint sub-path. * is an existing path this will start a new disjoint sub-path.
**/ **/
void cogl_path_rectangle (CoglFixed x, void cogl_path_rectangle (float x,
CoglFixed y, float y,
CoglFixed width, float width,
CoglFixed height); float height);
/** /**
* cogl_path_ellipse: * 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 * Constructs an ellipse shape. If there is an existing path this will
* start a new disjoint sub-path. * start a new disjoint sub-path.
**/ **/
void cogl_path_ellipse (CoglFixed center_x, void cogl_path_ellipse (float center_x,
CoglFixed center_y, float center_y,
CoglFixed radius_x, float radius_x,
CoglFixed radius_y); float radius_y);
/** /**
* cogl_path_round_rectangle: * 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 * Constructs a rectangular shape with rounded corners. If there is an
* existing path this will start a new disjoint sub-path. * existing path this will start a new disjoint sub-path.
**/ **/
void cogl_path_round_rectangle (CoglFixed x, void cogl_path_round_rectangle (float x,
CoglFixed y, float y,
CoglFixed width, float width,
CoglFixed height, float height,
CoglFixed radius, float radius,
CoglAngle arc_step); float arc_step);
G_END_DECLS G_END_DECLS

View File

@ -41,73 +41,77 @@ G_BEGIN_DECLS
* cogl_texture_new_with_size: * cogl_texture_new_with_size:
* @width: width of texture in pixels. * @width: width of texture in pixels.
* @height: height of texture in pixels. * @height: height of texture in pixels.
* @max_waste: maximum extra horizontal and|or vertical margin pixels to make * @max_waste: maximum extra horizontal and|or vertical margin pixels
* texture fit GPU limitations. * to make the texture fit GPU limitations
* @auto_mipmap: enable or disable automatic generation of mipmap pyramid * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* from the base level image whenever it is updated.
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the * @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 * Return value: a #CoglHandle to the newly created texture or
* if texture creation failed. * %COGL_INVALID_HANDLE on failure
*
* Since: 0.8
*/ */
CoglHandle cogl_texture_new_with_size (guint width, CoglHandle cogl_texture_new_with_size (guint width,
guint height, guint height,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat internal_format); CoglPixelFormat internal_format);
/** /**
* cogl_texture_new_from_file: * cogl_texture_new_from_file:
* @filename: the file to load * @filename: the file to load
* @max_waste: maximum extra horizontal and|or vertical margin pixels to make * @max_waste: maximum extra horizontal and|or vertical margin pixels
* texture fit GPU limitations. * to make the texture fit GPU limitations
* @auto_mipmap: enable or disable automatic generation of mipmap pyramid * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* from the base level image whenever it is updated.
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
* texture. * texture
* @error: a #GError or NULL. * @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 * Return value: a #CoglHandle to the newly created texture or
* if creating the texture failed. * %COGL_INVALID_HANDLE on failure
*
* Since: 0.8
*/ */
CoglHandle cogl_texture_new_from_file (const gchar *filename, CoglHandle cogl_texture_new_from_file (const gchar *filename,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
GError **error); GError **error);
/** /**
* cogl_texture_new_from_data: * cogl_texture_new_from_data:
* @width: width of texture in pixels. * @width: width of texture in pixels
* @height: height of texture in pixels. * @height: height of texture in pixels
* @max_waste: maximum extra horizontal and|or vertical margin pixels to make * @max_waste: maximum extra horizontal and|or vertical margin pixels
* @auto_mipmap: enable or disable automatic generation of mipmap pyramid * to make the texture fit GPU limitations
* from the base level image whenever it is updated. * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
* @format: the #CoglPixelFormat the buffer is stored in in RAM * @format: the #CoglPixelFormat the buffer is stored in in RAM
* @internal_format: the #CoglPixelFormat that will be used for storing the * @internal_format: the #CoglPixelFormat that will be used for storing
* buffer on the GPU. * the buffer on the GPU
* @rowstride: the memory offset in bytes between the starts of scanlines in * @rowstride: the memory offset in bytes between the starts of
* @data. * scanlines in @data
* @data: pointer the memory region where the source buffer resides. * @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 * Return value: a #CoglHandle to the newly created texture or
* if creating the texture failed. * %COGL_INVALID_HANDLE on failure
*
* Since: 0.8
*/ */
CoglHandle cogl_texture_new_from_data (guint width, CoglHandle cogl_texture_new_from_data (guint width,
guint height, guint height,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat format, CoglPixelFormat format,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
guint rowstride, guint rowstride,
const guchar *data); const guchar *data);
/** /**
* cogl_texture_new_from_foreign: * cogl_texture_new_from_foreign:
@ -119,12 +123,14 @@ CoglHandle cogl_texture_new_from_data (guint width,
* @y_pot_waste: maximum vertical waste. * @y_pot_waste: maximum vertical waste.
* @format: format of the foreign texture. * @format: format of the foreign texture.
* *
* Create a cogl texture based on an existing OpenGL texture, the width, height * Creates a COGL texture based on an existing OpenGL texture; the
* and format are passed along since it is not possible to query this from a * width, height and format are passed along since it is not possible
* handle with GLES 1.0. * to query this from a handle with GLES 1.0.
* *
* Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE * Return value: a #CoglHandle to the newly created texture or
* if creating the texture failed. * %COGL_INVALID_HANDLE on failure
*
* Since: 0.8
*/ */
CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle, CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
GLenum gl_target, GLenum gl_target,
@ -134,6 +140,27 @@ CoglHandle cogl_texture_new_from_foreign (GLuint gl_handle,
GLuint y_pot_waste, GLuint y_pot_waste,
CoglPixelFormat format); 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: * cogl_is_texture:
* @handle: A CoglHandle * @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. * texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
*/ */
void cogl_texture_rectangle (CoglHandle handle, void cogl_texture_rectangle (CoglHandle handle,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2); float ty2);
/** /**
* cogl_texture_polygon: * cogl_texture_polygon:
@ -416,6 +443,45 @@ void cogl_material_rectangle (CoglFixed x1,
gint tex_coords_len, gint tex_coords_len,
const CoglFixed *tex_coords); 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: * cogl_texture_multiple_rectangles:
* @handle: a @CoglHandle. * @handle: a @CoglHandle.
@ -427,16 +493,16 @@ void cogl_material_rectangle (CoglFixed x1,
* significant performance boost to use this function rather than * significant performance boost to use this function rather than
* calling cogl_texture_rectangle() separately for each rectangle. * calling cogl_texture_rectangle() separately for each rectangle.
* *
* @verts should point to an array of #CoglFixed<!-- -->s with * @verts should point to an array of #float<!-- -->s with
* @n_rects * 8 elements. Each group of 8 values corresponds to the * @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 * parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same
* meaning as in cogl_texture_rectangle(). * meaning as in cogl_texture_rectangle().
* *
* Since: 1.0 * Since: 0.8.6
*/ */
void cogl_texture_multiple_rectangles void cogl_texture_multiple_rectangles
(CoglHandle handle, (CoglHandle handle,
const CoglFixed *verts, const float *verts,
guint n_rects); guint n_rects);
G_END_DECLS G_END_DECLS

View File

@ -28,6 +28,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/**
* CoglBitmap:
*
* Type used for storing image data.
*/
typedef struct _CoglBitmap CoglBitmap;
/** /**
* CoglHandle: * CoglHandle:
* *
@ -257,11 +264,26 @@ struct _CoglColor
*/ */
struct _CoglTextureVertex struct _CoglTextureVertex
{ {
CoglFixed x, y, z; float x, y, z;
CoglFixed tx, ty; float tx, ty;
CoglColor color; 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 G_END_DECLS
#endif /* __COGL_TYPES_H__ */ #endif /* __COGL_TYPES_H__ */

View File

@ -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. * Copyright (C) 2008 Intel Corporation.
* *
* Authored by: Robert Bragg <bob@o-hand.com> * Authored by: Robert Bragg <robert@linux.intel.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -23,8 +27,8 @@
#error "Only <cogl/cogl.h> can be included directly." #error "Only <cogl/cogl.h> can be included directly."
#endif #endif
#ifndef __COGL_MESH_H__ #ifndef __COGL_VERTEX_BUFFER_H__
#define __COGL_MESH_H__ #define __COGL_VERTEX_BUFFER_H__
#include <glib.h> #include <glib.h>
#include <cogl/cogl-types.h> #include <cogl/cogl-types.h>
@ -32,42 +36,42 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/** /**
* SECTION:cogl-mesh * SECTION:cogl-vertex-buffer
* @short_description: An API for submitting extensible arrays of vertex * @short_description: An API for submitting extensible arrays of vertex
* attributes to OpenGL in a way that aims to minimise * attributes to OpenGL in a way that aims to minimise
* copying or reformatting of the original data. * copying or reformatting of the original data.
* *
* The Mesh API is designed to be a fairly raw mechanism for developers * The Attributes Buffer API is designed to be a fairly raw mechanism for
* to be able to submit geometry to Cogl in a format that can be directly * developers to be able to submit geometry to Cogl in a format that can be
* consumed by an OpenGL driver and with awareness of the specific hardware * directly consumed by an OpenGL driver and with awareness of the specific
* being used then costly format conversion can also be avoided. * hardware being used then costly format conversion can also be avoided.
* *
* They are designed to work on top of buffer objects and developers should * 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 * understand that attribute buffers are not that cheap to create but once they
* have been submitted they are stored in GPU addressable memory and can * have been submitted they can be stored in GPU addressable memory and can
* be quickly reused. * be quickly reused.
* *
* Although this API does allow you to modify mesh objects after they have * Although this API does allow you to modify attribute buffers after they have
* been submitted to the GPU you must note that modification is still * been submitted to the GPU you must note that modification is also not that
* not cheap, so if at all possible think of tricks that let you reuse * cheap, so if at all possible think of tricks that let you reuse a static
* a static buffer. To help with this, it is possible to enable and disable * buffer. To help with this, it is possible to enable and disable individual
* individual attributes cheaply. * attributes cheaply.
* *
* Take for example a mesh representing an elipse. If you were to submit * Take for example attributes representing an elipse. If you were to submit
* a mesh with color attributes, texture coordinates and normals, then * color attributes, texture coordinates and normals, then you would be able
* you would be able to draw an elipses in the following different ways * to draw an elipses in the following different ways without modifying
* without creating a new mesh: * the vertex buffer, only by changing your source material.
* <itemizedlist> * <itemizedlist>
* <listitem>Flat colored elipse</listitem> * <listitem>Flat colored elipse</listitem>
* <listitem>Textured elipse</listitem> * <listitem>Textured elipse</listitem>
* <listitem>Smoothly lit textured elipse blended with the color.</listitem> * <listitem>Smoothly lit textured elipse blended with the color.</listitem>
* </itemizedlist> * </itemizedlist>
*
* 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 * 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. * 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 * If you then update some of your attributes; then these attributes will
@ -75,18 +79,18 @@ G_BEGIN_DECLS
*/ */
/** /**
* cogl_mesh_new: * cogl_vertex_buffer_new:
* @n_vertices: The number of vertices that will make up your mesh. * @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 * This creates a Cogl handle for a new vertex buffer that you can then start
* attributes too. * to add attributes too.
*/ */
CoglHandle CoglHandle
cogl_mesh_new (guint n_vertices); cogl_vertex_buffer_new (guint n_vertices);
/** /**
* cogl_mesh_add_attribute: * cogl_vertex_buffer_add:
* @handle: A Cogl mesh handle * @handle: A vertex buffer handle
* @attribute_name: The name of your attribute. It should be a valid GLSL * @attribute_name: The name of your attribute. It should be a valid GLSL
* variable name and standard attribute types must use one * variable name and standard attribute types must use one
* of following built-in names: (Note: they correspond to the * 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 * stride for both attributes is 6. The special value 0 means the
* values are stored sequentially in memory. * values are stored sequentially in memory.
* @pointer: This addresses the first attribute in the vertex array. (This * @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 * of the built-in names to add standard attributes, like positions, colors
* and normals or you can add custom attributes for use in shaders. * 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 * Note: The number of vertices declared when first creating the vertex
* determine how many attribute values will be read from the supplied pointer. * 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 * Note: the data supplied here isn't copied anywhere until you call
* cogl_mesh_submit, so the supplied pointer must remain valid until then. * cogl_vertex_buffer_submit, so the supplied pointer must remain valid
* (This is an important optimisation since we can't create a buffer * until then.
* object until we know about all the attributes, and repeatedly copying * (This is an important optimisation since we can't create the underlying
* large buffers of vertex data may be very costly) If you add attributes * OpenGL buffer object until we know about all the attributes, and repeatedly
* after submitting then you will need to re-call cogl_mesh_submit to * copying large buffers of vertex data may be very costly) If you add
* commit the changes to the GPU. (Be carefull to minimize the number of * attributes after submitting then you will need to re-call
* calls to cogl_mesh_submit though) * 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 * Note: If you are interleving attributes it is assumed that that each
* interleaved attribute starts no farther than +- stride bytes from * interleaved attribute starts no farther than +- stride bytes from the other
* the other attributes it is interleved with. I.e. this is ok: * attributes it is interleved with. I.e. this is ok:
* |-0-0-0-0-0-0-0-0-0-0| * |-0-0-0-0-0-0-0-0-0-0|
* This is not ok: * This is not ok:
* |- - - - -0-0-0-0-0-0 0 0 0 0| * |- - - - -0-0-0-0-0-0 0 0 0 0|
* (Though you can have multiple groups of interleved attributes) * (Though you can have multiple groups of interleved attributes)
*/ */
void void
cogl_mesh_add_attribute (CoglHandle handle, cogl_vertex_buffer_add (CoglHandle handle,
const char *attribute_name, const char *attribute_name,
guint8 n_components, guint8 n_components,
GLenum gl_type, GLenum gl_type,
gboolean normalized, gboolean normalized,
guint16 stride, guint16 stride,
const void *pointer); const void *pointer);
/** /**
* cogl_mesh_delete_attribute: * cogl_vertex_buffer_delete:
* @handle: A Cogl mesh handle * @handle: A vertex buffer handle
* @attribute_name: The name of a previously added attribute * @attribute_name: The name of a previously added attribute
* *
* This function deletes an attribute from a mesh. You will need to * This function deletes an attribute from a buffer. You will need to
* call cogl_mesh_submit to commit this change to the GPU. * call cogl_vertex_buffer_submit to commit this change to the GPU.
*/ */
void void
cogl_mesh_delete_attribute (CoglHandle handle, cogl_vertex_buffer_delete (CoglHandle handle,
const char *attribute_name); const char *attribute_name);
/** /**
* cogl_mesh_enable_attribute: * cogl_vertex_buffer_enable:
* @handle: A Cogl mesh handle * @handle: A vertex buffer handle
* @attribute_name: The name of the attribute you want to enable * @attribute_name: The name of the attribute you want to enable
* *
* This function enables a previosuly added attribute * This function enables a previosuly added attribute
* *
* Since it is costly to create new mesh objects, then to make individual mesh * Since it can be costly to add and remove new attributes to buffers; to make
* objects more reuseable it is possible to enable and disable attributes * individual buffers more reuseable it is possible to enable and disable
* before using a mesh for drawing. * 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 void
cogl_mesh_enable_attribute (CoglHandle handle, cogl_vertex_buffer_enable (CoglHandle handle,
const char *attribute_name); const char *attribute_name);
/** /**
* cogl_mesh_disable_attribute: * cogl_vertex_buffer_submit:
* @handle: A Cogl mesh handle * @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 * @attribute_name: The name of the attribute you want to disable
* *
* This function disables a previosuly added attribute * This function disables a previosuly added attribute
* *
* Since it is costly to create new mesh objects, then to make individual mesh * Since it can be costly to add and remove new attributes to buffers; to make
* objects more reuseable it is possible to enable and disable attributes * individual buffers more reuseable it is possible to enable and disable
* before using a mesh for drawing. * 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 void
cogl_mesh_disable_attribute (CoglHandle handle, cogl_vertex_buffer_disable (CoglHandle handle,
const char *attribute_name); const char *attribute_name);
/** /**
* cogl_mesh_draw_arrays: * cogl_vertex_buffer_draw:
* @handle: A Cogl mesh handle * @handle: A vertex buffer handle
* @mode: Specifies how the vertices should be interpreted, and should be * @mode: Specifies how the vertices should be interpreted, and should be
* a valid GL primitive type: * a valid GL primitive type:
* <itemizedlist> * <itemizedlist>
@ -215,17 +235,17 @@ cogl_mesh_disable_attribute (CoglHandle handle,
* @count: Specifies the number of vertices you want to draw. * @count: Specifies the number of vertices you want to draw.
* *
* This function lets you draw geometry using all or a subset of the * This function lets you draw geometry using all or a subset of the
* vertices in a mesh object. * vertices in a vertex buffer.
*/ */
void void
cogl_mesh_draw_arrays (CoglHandle handle, cogl_vertex_buffer_draw (CoglHandle handle,
GLenum mode, GLenum mode,
GLint first, GLint first,
GLsizei count); GLsizei count);
/** /**
* cogl_mesh_draw_range_elements: * cogl_vertex_buffer_draw_range_elements:
* @handle: A Cogl mesh handle * @handle: A vertex buffer handle
* @mode: Specifies how the vertices should be interpreted, and should be * @mode: Specifies how the vertices should be interpreted, and should be
* a valid GL primitive type: * a valid GL primitive type:
* <itemizedlist> * <itemizedlist>
@ -238,11 +258,11 @@ cogl_mesh_draw_arrays (CoglHandle handle,
* <listitem>GL_TRIANGLES</listitem> * <listitem>GL_TRIANGLES</listitem>
* </itemizedlist> * </itemizedlist>
* (Note: only types available in GLES are listed) * (Note: only types available in GLES are listed)
* @start: Specifies the minimum vertex index contained in indices * @min_index: Specifies the minimum vertex index contained in indices
* @end: Specifies the maximum 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. * @count: Specifies the number of vertices you want to draw.
* @type: Specifies the data type used for the indices, and must be * @indices_type: Specifies the data type used for the indices, and must be
* one of: * one of:
* <itemizedlist> * <itemizedlist>
* <listitem>GL_UNSIGNED_BYTE</listitem> * <listitem>GL_UNSIGNED_BYTE</listitem>
* <listitem>GL_UNSIGNED_SHORT</listitem> * <listitem>GL_UNSIGNED_SHORT</listitem>
@ -251,49 +271,38 @@ cogl_mesh_draw_arrays (CoglHandle handle,
* @indices: Specifies the address of your array of indices * @indices: Specifies the address of your array of indices
* *
* This function lets you use an array of indices to specify the vertices * 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 void
cogl_mesh_draw_range_elements (CoglHandle handle, cogl_vertex_buffer_draw_range_elements (CoglHandle handle,
GLenum mode, GLenum mode,
GLuint start, GLuint min_index,
GLuint end, GLuint max_index,
GLsizei count, GLsizei count,
GLenum type, GLenum indices_type,
const GLvoid *indices); const GLvoid *indices);
/** /**
* cogl_mesh_submit: * cogl_vertex_buffer_ref:
* @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:
* @handle: a @CoglHandle. * @handle: a @CoglHandle.
* *
* Increment the reference count for a cogl mesh. * Increment the reference count for a vertex buffer
* *
* Returns: the @handle. * 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. * @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 G_END_DECLS
#endif /* __COGL_MESH_H__ */ #endif /* __COGL_VERTEX_BUFFER_H__ */

View File

@ -34,6 +34,7 @@
#include <cogl/cogl-mesh.h> #include <cogl/cogl-mesh.h>
#include <cogl/cogl-matrix.h> #include <cogl/cogl-matrix.h>
#include <cogl/cogl-vertex-buffer.h>
#include <cogl/cogl-fixed.h> #include <cogl/cogl-fixed.h>
#include <cogl/cogl-color.h> #include <cogl/cogl-color.h>
#include <cogl/cogl-offscreen.h> #include <cogl/cogl-offscreen.h>
@ -145,10 +146,10 @@ void cogl_get_bitmasks (gint *red,
* Replaces the current projection matrix with a perspective matrix * Replaces the current projection matrix with a perspective matrix
* based on the provided values. * based on the provided values.
*/ */
void cogl_perspective (CoglFixed fovy, void cogl_perspective (float fovy,
CoglFixed aspect, float aspect,
CoglFixed z_near, float z_near,
CoglFixed z_far); float z_far);
/** /**
* cogl_frustum: * cogl_frustum:
@ -164,12 +165,12 @@ void cogl_perspective (CoglFixed fovy,
* *
* Since: 0.8.2 * Since: 0.8.2
*/ */
void cogl_frustum (CoglFixed left, void cogl_frustum (float left,
CoglFixed right, float right,
CoglFixed bottom, float bottom,
CoglFixed top, float top,
CoglFixed z_near, float z_near,
CoglFixed z_far); float z_far);
/** /**
* cogl_setup_viewport: * cogl_setup_viewport:
@ -189,10 +190,10 @@ void cogl_frustum (CoglFixed left,
*/ */
void cogl_setup_viewport (guint width, void cogl_setup_viewport (guint width,
guint height, guint height,
CoglFixed fovy, float fovy,
CoglFixed aspect, float aspect,
CoglFixed z_near, float z_near,
CoglFixed z_far); float z_far);
/** /**
* cogl_viewport: * cogl_viewport:
@ -229,21 +230,8 @@ void cogl_pop_matrix (void);
* Multiplies the current model-view matrix by one that scales the x * Multiplies the current model-view matrix by one that scales the x
* and y axes by the given values. * and y axes by the given values.
*/ */
void cogl_scale (CoglFixed x, void cogl_scale (float x,
CoglFixed y); float 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);
/** /**
* cogl_translate: * cogl_translate:
@ -251,16 +239,15 @@ void cogl_translatex (CoglFixed x,
* @y: Distance to translate along the y-axis * @y: Distance to translate along the y-axis
* @z: Distance to translate along the z-axis * @z: Distance to translate along the z-axis
* *
* Integer version of cogl_translatex(). Multiplies the current * Multiplies the current model-view matrix by one that translates the
* model-view matrix by one that translates the model along all three * model along all three axes according to the given values.
* axes according to the given values.
*/ */
void cogl_translate (gint x, void cogl_translate (float x,
gint y, float y,
gint z); float z);
/** /**
* cogl_rotatex: * cogl_rotate:
* @angle: Angle in degrees to rotate. * @angle: Angle in degrees to rotate.
* @x: X-component of vertex to rotate around. * @x: X-component of vertex to rotate around.
* @y: Y-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 * degrees about the vertex (0, 0, 1) causes a small counter-clockwise
* rotation. * rotation.
*/ */
void cogl_rotatex (CoglFixed angle, void cogl_rotate (float angle,
gint x, float x,
gint y, float y,
gint z); float 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);
/** /**
* cogl_get_modelview_matrix: * cogl_get_modelview_matrix:
* @m: pointer to a 4x4 array of #CoglFixed<!-- -->s to receive the matrix * @m: pointer to a 4x4 array of #float<!-- -->s to receive the matrix
* *
* Stores the current model-view matrix in @m. The matrix is in * Stores the current model-view matrix in @m. The matrix is in
* column-major order. * column-major order.
*/ */
void cogl_get_modelview_matrix (CoglFixed m[16]); void cogl_get_modelview_matrix (float m[16]);
/** /**
* cogl_get_projection_matrix: * cogl_get_projection_matrix:
* @m: pointer to a 4x4 array of #CoglFixed<!-- -->s to receive the matrix * @m: pointer to a 4x4 array of #float<!-- -->s to receive the matrix
* *
* Stores the current projection matrix in @m. The matrix is in * Stores the current projection matrix in @m. The matrix is in
* column-major order. * column-major order.
*/ */
void cogl_get_projection_matrix (CoglFixed m[16]); void cogl_get_projection_matrix (float m[16]);
/** /**
* cogl_get_viewport: * cogl_get_viewport:
* @v: pointer to a 4 element array of #CoglFixed<!-- -->s to * @v: pointer to a 4 element array of #float<!-- -->s to
* receive the viewport dimensions. * receive the viewport dimensions.
* *
* Stores the current viewport in @v. @v[0] and @v[1] get the x and y * 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 * position of the viewport and @v[2] and @v[3] get the width and
* height. * height.
*/ */
void cogl_get_viewport (CoglFixed v[4]); void cogl_get_viewport (float v[4]);
/** /**
* cogl_clip_set: * 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 rectangle is intersected with the current clip region. To undo
* the effect of this function, call cogl_clip_unset(). * the effect of this function, call cogl_clip_unset().
*/ */
void cogl_clip_set (CoglFixed x_offset, void cogl_clip_set (float x_offset,
CoglFixed y_offset, float y_offset,
CoglFixed width, float width,
CoglFixed height); float height);
/** /**
* cogl_clip_set_from_path: * 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 * comparing with the value in @ref. The default function is CGL_ALWAYS the
* initial reference value is 1.0. * initial reference value is 1.0.
*/ */
void cogl_alpha_func (COGLenum func, void cogl_alpha_func (COGLenum func,
CoglFixed ref); float ref);
/** /**
* cogl_fog_set: * cogl_fog_set:
@ -462,9 +433,9 @@ void cogl_alpha_func (COGLenum func,
* cogl_paint_init(). * cogl_paint_init().
*/ */
void cogl_fog_set (const CoglColor *fog_color, void cogl_fog_set (const CoglColor *fog_color,
CoglFixed density, float density,
CoglFixed z_near, float z_near,
CoglFixed z_far); float z_far);
/** /**
* cogl_paint_init: * cogl_paint_init:

View File

@ -30,6 +30,7 @@ libclutter_cogl_common_la_SOURCES = \
cogl-clip-stack.c \ cogl-clip-stack.c \
cogl-fixed.c \ cogl-fixed.c \
cogl-color.c \ cogl-color.c \
cogl-mesh.c \ cogl-vertex-buffer-private.h \
cogl-vertex-buffer.c \
cogl-matrix.c \ cogl-matrix.c \
cogl-material.c cogl-material.c

View File

@ -84,6 +84,20 @@ cogl_bitmap_error_quark (void)
return g_quark_from_static_string ("cogl-bitmap-error-quark"); 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 */ /* the error does not contain the filename as the caller already has it */
gboolean gboolean
_cogl_bitmap_from_file (CoglBitmap *bmp, _cogl_bitmap_from_file (CoglBitmap *bmp,
@ -177,9 +191,22 @@ _cogl_bitmap_from_file (CoglBitmap *bmp,
#elif defined(USE_GDKPIXBUF) #elif defined(USE_GDKPIXBUF)
gboolean gboolean
_cogl_bitmap_from_file (CoglBitmap *bmp, _cogl_bitmap_get_size_from_file (const gchar *filename,
const gchar *filename, gint *width,
GError **error) 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; GdkPixbuf *pixbuf;
gboolean has_alpha; gboolean has_alpha;
@ -198,11 +225,13 @@ _cogl_bitmap_from_file (CoglBitmap *bmp,
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 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 */ /* Load from file using GdkPixbuf */
pixbuf = gdk_pixbuf_new_from_file (filename, error); pixbuf = gdk_pixbuf_new_from_file (filename, error);
if (pixbuf == NULL) return FALSE; if (pixbuf == NULL)
return FALSE;
/* Get pixbuf properties */ /* Get pixbuf properties */
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
@ -278,6 +307,20 @@ _cogl_bitmap_from_file (CoglBitmap *bmp,
#include "stb_image.c" #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 gboolean
_cogl_bitmap_from_file (CoglBitmap *bmp, _cogl_bitmap_from_file (CoglBitmap *bmp,
const gchar *filename, const gchar *filename,
@ -290,11 +333,15 @@ _cogl_bitmap_from_file (CoglBitmap *bmp,
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); 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 */ /* Load from file using stb */
pixels = stbi_load (filename, &width, &height, &stb_pixel_format, STBI_rgb_alpha); pixels = stbi_load (filename,
if (pixels == NULL) return FALSE; &width, &height, &stb_pixel_format,
STBI_rgb_alpha);
if (pixels == NULL)
return FALSE;
/* Store bitmap info */ /* Store bitmap info */
bmp->data = g_memdup (pixels, height * width * 4); bmp->data = g_memdup (pixels, height * width * 4);

View File

@ -148,3 +148,42 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
dstdata += dst->rowstride; 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);
}

View File

@ -28,8 +28,6 @@
#include <glib.h> #include <glib.h>
typedef struct _CoglBitmap CoglBitmap;
struct _CoglBitmap struct _CoglBitmap
{ {
guchar *data; guchar *data;
@ -92,4 +90,9 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
gint width, gint width,
gint height); gint height);
gboolean
_cogl_bitmap_get_size_from_file (const gchar *filename,
gint *width,
gint *height);
#endif /* __COGL_BITMAP_H */ #endif /* __COGL_BITMAP_H */

View File

@ -35,24 +35,24 @@
/* These are defined in the particular backend (float in GL vs fixed /* These are defined in the particular backend (float in GL vs fixed
in GL ES) */ in GL ES) */
void _cogl_set_clip_planes (CoglFixed x, void _cogl_set_clip_planes (float x,
CoglFixed y, float y,
CoglFixed width, float width,
CoglFixed height); float height);
void _cogl_add_stencil_clip (CoglFixed x, void _cogl_add_stencil_clip (float x,
CoglFixed y, float y,
CoglFixed width, float width,
CoglFixed height, float height,
gboolean first); gboolean first);
void _cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, void _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
CoglFixedVec2 nodes_max, floatVec2 nodes_max,
guint path_size, guint path_size,
CoglPathNode *path, CoglPathNode *path,
gboolean merge); gboolean merge);
void _cogl_enable_clip_planes (void); void _cogl_enable_clip_planes (void);
void _cogl_disable_clip_planes (void); void _cogl_disable_clip_planes (void);
void _cogl_disable_stencil_buffer (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; typedef struct _CoglClipStack CoglClipStack;
@ -75,13 +75,13 @@ struct _CoglClipStackEntryRect
CoglClipStackEntryType type; CoglClipStackEntryType type;
/* The rectangle for this clip */ /* The rectangle for this clip */
CoglFixed x_offset; float x_offset;
CoglFixed y_offset; float y_offset;
CoglFixed width; float width;
CoglFixed height; float height;
/* The matrix that was current when the clip was set */ /* The matrix that was current when the clip was set */
CoglFixed matrix[16]; float matrix[16];
}; };
struct _CoglClipStackEntryPath struct _CoglClipStackEntryPath
@ -89,20 +89,20 @@ struct _CoglClipStackEntryPath
CoglClipStackEntryType type; CoglClipStackEntryType type;
/* The matrix that was current when the clip was set */ /* The matrix that was current when the clip was set */
CoglFixed matrix[16]; float matrix[16];
CoglFixedVec2 path_nodes_min; floatVec2 path_nodes_min;
CoglFixedVec2 path_nodes_max; floatVec2 path_nodes_max;
guint path_size; guint path_size;
CoglPathNode path[1]; CoglPathNode path[1];
}; };
void void
cogl_clip_set (CoglFixed x_offset, cogl_clip_set (float x_offset,
CoglFixed y_offset, float y_offset,
CoglFixed width, float width,
CoglFixed height) float height)
{ {
CoglClipStackEntryRect *entry; CoglClipStackEntryRect *entry;
CoglClipStack *stack; CoglClipStack *stack;

View File

@ -58,18 +58,18 @@ cogl_color_set_from_4d (CoglColor *dest,
} }
void void
cogl_color_set_from_4x (CoglColor *dest, cogl_color_set_from_4f (CoglColor *dest,
CoglFixed red, float red,
CoglFixed green, float green,
CoglFixed blue, float blue,
CoglFixed alpha) float alpha)
{ {
g_return_if_fail (dest != NULL); g_return_if_fail (dest != NULL);
dest->red = COGL_FIXED_TO_INT (red * 255); dest->red = (red * 255);
dest->green = COGL_FIXED_TO_INT (green * 255); dest->green = (green * 255);
dest->blue = COGL_FIXED_TO_INT (blue * 255); dest->blue = (blue * 255);
dest->alpha = COGL_FIXED_TO_INT (alpha * 255); dest->alpha = (alpha * 255);
} }
unsigned char unsigned char
@ -84,10 +84,10 @@ cogl_color_get_red_float (const CoglColor *color)
return (float) color->red / 255.0; return (float) color->red / 255.0;
} }
CoglFixed float
cogl_color_get_red (const CoglColor *color) 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 unsigned char
@ -102,10 +102,10 @@ cogl_color_get_green_float (const CoglColor *color)
return (float) color->green / 255.0; return (float) color->green / 255.0;
} }
CoglFixed float
cogl_color_get_green (const CoglColor *color) 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 unsigned char
@ -120,10 +120,10 @@ cogl_color_get_blue_float (const CoglColor *color)
return (float) color->blue / 255.0; return (float) color->blue / 255.0;
} }
CoglFixed float
cogl_color_get_blue (const CoglColor *color) 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 unsigned char
@ -138,10 +138,10 @@ cogl_color_get_alpha_float (const CoglColor *color)
return (float) color->alpha / 255.0; return (float) color->alpha / 255.0;
} }
CoglFixed float
cogl_color_get_alpha (const CoglColor *color) cogl_color_get_alpha (const CoglColor *color)
{ {
return COGL_FIXED_FROM_FLOAT ((float) color->alpha / 255.0); return ((float) color->alpha / 255.0);
} }
void void
@ -157,13 +157,13 @@ cogl_set_source_color4ub (guint8 red,
} }
void void
cogl_set_source_color4x (CoglFixed red, cogl_set_source_color4f (float red,
CoglFixed green, float green,
CoglFixed blue, float blue,
CoglFixed alpha) float alpha)
{ {
CoglColor c = { 0, }; 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); cogl_set_source_color (&c);
} }

View File

@ -10,10 +10,12 @@
* *
* Currently contains 257 entries. * Currently contains 257 entries.
* *
* The current error (compared to system sin) is about * The current maximum absolute error is about 1.9e-0.5
* 0.5% for values near the start of the table where the * and is greatest around pi/2 where the second derivative
* curve is steep, but improving rapidly. If this precision * of sin(x) is greatest. If greater accuracy is needed,
* is not enough, we can increase the size of the table * 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[] = 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 /* the difference of the angle for two adjacent values in the
* sin_tbl table, expressed as CoglFixed number * 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; static const double _magic = 68719476736.0 * 1.5;
@ -363,7 +365,9 @@ CoglFixed
cogl_fixed_sin (CoglFixed angle) cogl_fixed_sin (CoglFixed angle)
{ {
int sign = 1, indx1, indx2; 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 */ /* convert negative angle to positive + sign */
if ((int) angle < 0) if ((int) angle < 0)
@ -401,14 +405,17 @@ cogl_fixed_sin (CoglFixed angle)
} }
/* Calculate indices of the two nearest values in our table /* 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 * Handle the end of the table gracefully
*/ */
indx1 = COGL_FIXED_DIV (angle, COGL_SIN_STEP); indx1 = (angle * sin_tbl_size) / COGL_FIXED_PI_2;
indx1 = COGL_FIXED_TO_INT (indx1);
if (indx1 == (G_N_ELEMENTS (sin_tbl) - 1)) if (indx1 == sin_tbl_size)
{ {
indx2 = indx1; indx2 = indx1;
indx1 = indx2 - 1; indx1 = indx2 - 1;
@ -421,10 +428,13 @@ cogl_fixed_sin (CoglFixed angle)
low = sin_tbl[indx1]; low = sin_tbl[indx1];
high = sin_tbl[indx2]; high = sin_tbl[indx2];
d1 = angle - indx1 * COGL_SIN_STEP; /* Again multiply the divide; no danger of overflow */
d2 = indx2 * COGL_SIN_STEP - angle; 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) if (sign < 0)
angle = -angle; angle = -angle;
@ -481,6 +491,12 @@ cogl_angle_sin (CoglAngle angle)
return result; return result;
} }
CoglFixed
cogl_fixed_tan (CoglFixed angle)
{
return cogl_angle_tan (COGL_ANGLE_FROM_DEGX (angle));
}
CoglFixed CoglFixed
cogl_angle_tan (CoglAngle angle) cogl_angle_tan (CoglAngle angle)
{ {

View File

@ -1,143 +0,0 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Robert Bragg <bob@o-hand.com>
*
* 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 */

View File

@ -33,46 +33,31 @@
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
#include <math.h>
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 #define _COGL_MAX_BEZ_RECURSE_DEPTH 16
/* these are defined in the particular backend(float in gl vs fixed in gles)*/ /* these are defined in the particular backend(float in gl vs fixed in gles)*/
void _cogl_path_add_node (gboolean new_sub_path, void _cogl_path_add_node (gboolean new_sub_path,
CoglFixed x, float x,
CoglFixed y); float y);
void _cogl_path_fill_nodes (); void _cogl_path_fill_nodes ();
void _cogl_path_stroke_nodes (); void _cogl_path_stroke_nodes ();
void _cogl_rectangle (gint x, void _cogl_rectangle (float x,
gint y, float y,
guint width, float width,
guint height); float height);
void _cogl_rectanglex (CoglFixed x,
CoglFixed y,
CoglFixed width,
CoglFixed height);
void void
cogl_rectangle (gint x, cogl_rectangle (float x,
gint y, float y,
guint width, float width,
guint height) float height)
{ {
cogl_clip_ensure (); cogl_clip_ensure ();
_cogl_rectangle (x, y, width, height); _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 void
cogl_path_fill (void) cogl_path_fill (void)
{ {
@ -116,8 +101,8 @@ cogl_path_stroke_preserve (void)
} }
void void
cogl_path_move_to (CoglFixed x, cogl_path_move_to (float x,
CoglFixed y) float y)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -132,8 +117,8 @@ cogl_path_move_to (CoglFixed x,
} }
void void
cogl_path_rel_move_to (CoglFixed x, cogl_path_rel_move_to (float x,
CoglFixed y) float y)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -142,8 +127,8 @@ cogl_path_rel_move_to (CoglFixed x,
} }
void void
cogl_path_line_to (CoglFixed x, cogl_path_line_to (float x,
CoglFixed y) float y)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -154,8 +139,8 @@ cogl_path_line_to (CoglFixed x,
} }
void void
cogl_path_rel_line_to (CoglFixed x, cogl_path_rel_line_to (float x,
CoglFixed y) float y)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -181,17 +166,17 @@ cogl_path_new (void)
} }
void void
cogl_path_line (CoglFixed x1, cogl_path_line (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2) float y2)
{ {
cogl_path_move_to (x1, y1); cogl_path_move_to (x1, y1);
cogl_path_line_to (x2, y2); cogl_path_line_to (x2, y2);
} }
void void
cogl_path_polyline (CoglFixed *coords, cogl_path_polyline (float *coords,
gint num_points) gint num_points)
{ {
gint c = 0; gint c = 0;
@ -203,7 +188,7 @@ cogl_path_polyline (CoglFixed *coords,
} }
void void
cogl_path_polygon (CoglFixed *coords, cogl_path_polygon (float *coords,
gint num_points) gint num_points)
{ {
cogl_path_polyline (coords, num_points); cogl_path_polyline (coords, num_points);
@ -211,10 +196,10 @@ cogl_path_polygon (CoglFixed *coords,
} }
void void
cogl_path_rectangle (CoglFixed x, cogl_path_rectangle (float x,
CoglFixed y, float y,
CoglFixed width, float width,
CoglFixed height) float height)
{ {
cogl_path_move_to (x, y); cogl_path_move_to (x, y);
cogl_path_line_to (x + width, y); cogl_path_line_to (x + width, y);
@ -224,20 +209,20 @@ cogl_path_rectangle (CoglFixed x,
} }
static void static void
_cogl_path_arc (CoglFixed center_x, _cogl_path_arc (float center_x,
CoglFixed center_y, float center_y,
CoglFixed radius_x, float radius_x,
CoglFixed radius_y, float radius_y,
CoglAngle angle_1, float angle_1,
CoglAngle angle_2, float angle_2,
CoglAngle angle_step, float angle_step,
guint move_first) guint move_first)
{ {
CoglAngle a = 0x0; float a = 0x0;
CoglFixed cosa = 0x0; float cosa = 0x0;
CoglFixed sina = 0x0; float sina = 0x0;
CoglFixed px = 0x0; float px = 0x0;
CoglFixed py = 0x0; float py = 0x0;
/* Fix invalid angles */ /* Fix invalid angles */
@ -252,11 +237,11 @@ _cogl_path_arc (CoglFixed center_x,
a = angle_1; a = angle_1;
while (a != angle_2) while (a != angle_2)
{ {
cosa = cogl_angle_cos (a); cosa = cosf (a * (G_PI/180.0));
sina = cogl_angle_sin (a); sina = sinf (a * (G_PI/180.0));
px = center_x + COGL_FIXED_MUL (cosa, radius_x); px = center_x + (cosa * radius_x);
py = center_y + COGL_FIXED_MUL (sina, radius_y); py = center_y + (sina * radius_y);
if (a == angle_1 && move_first) if (a == angle_1 && move_first)
cogl_path_move_to (px, py); cogl_path_move_to (px, py);
@ -279,24 +264,24 @@ _cogl_path_arc (CoglFixed center_x,
/* Make sure the final point is drawn */ /* Make sure the final point is drawn */
cosa = cogl_angle_cos (angle_2); cosa = cosf (angle_2 * (G_PI/180.0));
sina = cogl_angle_sin (angle_2); sina = sinf (angle_2 * (G_PI/180.0));
px = center_x + COGL_FIXED_MUL (cosa, radius_x); px = center_x + (cosa * radius_x);
py = center_y + COGL_FIXED_MUL (sina, radius_y); py = center_y + (sina * radius_y);
cogl_path_line_to (px, py); cogl_path_line_to (px, py);
} }
void void
cogl_path_arc (CoglFixed center_x, cogl_path_arc (float center_x,
CoglFixed center_y, float center_y,
CoglFixed radius_x, float radius_x,
CoglFixed radius_y, float radius_y,
CoglAngle angle_1, float angle_1,
CoglAngle angle_2) float angle_2)
{ {
CoglAngle angle_step = 10; float angle_step = 10;
/* it is documented that a move to is needed to create a freestanding /* it is documented that a move to is needed to create a freestanding
* arc * arc
*/ */
@ -308,13 +293,13 @@ cogl_path_arc (CoglFixed center_x,
void void
cogl_path_arc_rel (CoglFixed center_x, cogl_path_arc_rel (float center_x,
CoglFixed center_y, float center_y,
CoglFixed radius_x, float radius_x,
CoglFixed radius_y, float radius_y,
CoglAngle angle_1, float angle_1,
CoglAngle angle_2, float angle_2,
CoglAngle angle_step) float angle_step)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -326,50 +311,50 @@ cogl_path_arc_rel (CoglFixed center_x,
} }
void void
cogl_path_ellipse (CoglFixed center_x, cogl_path_ellipse (float center_x,
CoglFixed center_y, float center_y,
CoglFixed radius_x, float radius_x,
CoglFixed radius_y) float radius_y)
{ {
CoglAngle angle_step = 10; float angle_step = 10;
/* FIXME: if shows to be slow might be optimized /* FIXME: if shows to be slow might be optimized
* by mirroring just a quarter of it */ * by mirroring just a quarter of it */
_cogl_path_arc (center_x, center_y, _cogl_path_arc (center_x, center_y,
radius_x, radius_y, radius_x, radius_y,
0, COGL_ANGLE_FROM_DEG (360), 0, 360,
angle_step, 1 /* move first */); angle_step, 1 /* move first */);
cogl_path_close(); cogl_path_close();
} }
void void
cogl_path_round_rectangle (CoglFixed x, cogl_path_round_rectangle (float x,
CoglFixed y, float y,
CoglFixed width, float width,
CoglFixed height, float height,
CoglFixed radius, float radius,
CoglAngle arc_step) float arc_step)
{ {
CoglFixed inner_width = width - (radius << 1); float inner_width = width - (radius * 2);
CoglFixed inner_height = height - (radius << 1); float inner_height = height - (radius * 2);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_path_move_to (x, y + radius); cogl_path_move_to (x, y + radius);
cogl_path_arc_rel (radius, 0, cogl_path_arc_rel (radius, 0,
radius, radius, radius, radius,
COGL_ANGLE_FROM_DEG (180), 180,
COGL_ANGLE_FROM_DEG (270), 270,
arc_step); arc_step);
cogl_path_line_to (ctx->path_pen.x + inner_width, cogl_path_line_to (ctx->path_pen.x + inner_width,
ctx->path_pen.y); ctx->path_pen.y);
cogl_path_arc_rel (0, radius, cogl_path_arc_rel (0, radius,
radius, radius, radius, radius,
COGL_ANGLE_FROM_DEG (-90), -90,
COGL_ANGLE_FROM_DEG (0), 0,
arc_step); arc_step);
cogl_path_line_to (ctx->path_pen.x, cogl_path_line_to (ctx->path_pen.x,
@ -377,16 +362,16 @@ cogl_path_round_rectangle (CoglFixed x,
cogl_path_arc_rel (-radius, 0, cogl_path_arc_rel (-radius, 0,
radius, radius, radius, radius,
COGL_ANGLE_FROM_DEG (0), 0,
COGL_ANGLE_FROM_DEG (90), 90,
arc_step); arc_step);
cogl_path_line_to (ctx->path_pen.x - inner_width, cogl_path_line_to (ctx->path_pen.x - inner_width,
ctx->path_pen.y); ctx->path_pen.y);
cogl_path_arc_rel (0, -radius, cogl_path_arc_rel (0, -radius,
radius, radius, radius, radius,
COGL_ANGLE_FROM_DEG (90), 90,
COGL_ANGLE_FROM_DEG (180), 180,
arc_step); arc_step);
cogl_path_close (); cogl_path_close ();
@ -400,14 +385,14 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic)
CoglBezCubic *cleft; CoglBezCubic *cleft;
CoglBezCubic *cright; CoglBezCubic *cright;
CoglBezCubic *c; CoglBezCubic *c;
CoglFixedVec2 dif1; floatVec2 dif1;
CoglFixedVec2 dif2; floatVec2 dif2;
CoglFixedVec2 mm; floatVec2 mm;
CoglFixedVec2 c1; floatVec2 c1;
CoglFixedVec2 c2; floatVec2 c2;
CoglFixedVec2 c3; floatVec2 c3;
CoglFixedVec2 c4; floatVec2 c4;
CoglFixedVec2 c5; floatVec2 c5;
gint cindex; gint cindex;
/* Put first curve on stack */ /* Put first curve on stack */
@ -418,16 +403,13 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic)
{ {
c = &cubics[cindex]; 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 /* Calculate distance of control points from their
* counterparts on the line between end points */ * counterparts on the line between end points */
dif1.x = CFX_MUL3 (c->p2.x) - CFX_MUL2 (c->p1.x) - c->p4.x; dif1.x = (c->p2.x * 3) - (c->p1.x * 2) - c->p4.x;
dif1.y = CFX_MUL3 (c->p2.y) - CFX_MUL2 (c->p1.y) - c->p4.y; dif1.y = (c->p2.y * 3) - (c->p1.y * 2) - c->p4.y;
dif2.x = CFX_MUL3 (c->p3.x) - CFX_MUL2 (c->p4.x) - c->p1.x; dif2.x = (c->p3.x * 3) - (c->p4.x * 2) - c->p1.x;
dif2.y = CFX_MUL3 (c->p3.y) - CFX_MUL2 (c->p4.y) - c->p1.y; dif2.y = (c->p3.y * 3) - (c->p4.y * 2) - c->p1.y;
if (dif1.x < 0) if (dif1.x < 0)
dif1.x = -dif1.x; dif1.x = -dif1.x;
@ -438,16 +420,13 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic)
if (dif2.y < 0) if (dif2.y < 0)
dif2.y = -dif2.y; dif2.y = -dif2.y;
#undef CFX_MUL2
#undef CFX_MUL3
#undef CFX_SQ
/* Pick the greatest of two distances */ /* Pick the greatest of two distances */
if (dif1.x < dif2.x) dif1.x = dif2.x; if (dif1.x < dif2.x) dif1.x = dif2.x;
if (dif1.y < dif2.y) dif1.y = dif2.y; if (dif1.y < dif2.y) dif1.y = dif2.y;
/* Cancel if the curve is flat enough */ /* 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) cindex == _COGL_MAX_BEZ_RECURSE_DEPTH-1)
{ {
/* Add subdivision point (skip last) */ /* Add subdivision point (skip last) */
@ -465,20 +444,20 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic)
cright = c; cleft = &cubics[++cindex]; cright = c; cleft = &cubics[++cindex];
/* Subdivide into 2 sub-curves */ /* Subdivide into 2 sub-curves */
c1.x = ((c->p1.x + c->p2.x) >> 1); c1.x = ((c->p1.x + c->p2.x) / 2);
c1.y = ((c->p1.y + c->p2.y) >> 1); c1.y = ((c->p1.y + c->p2.y) / 2);
mm.x = ((c->p2.x + c->p3.x) >> 1); mm.x = ((c->p2.x + c->p3.x) / 2);
mm.y = ((c->p2.y + c->p3.y) >> 1); mm.y = ((c->p2.y + c->p3.y) / 2);
c5.x = ((c->p3.x + c->p4.x) >> 1); c5.x = ((c->p3.x + c->p4.x) / 2);
c5.y = ((c->p3.y + c->p4.y) >> 1); c5.y = ((c->p3.y + c->p4.y) / 2);
c2.x = ((c1.x + mm.x) >> 1); c2.x = ((c1.x + mm.x) / 2);
c2.y = ((c1.y + mm.y) >> 1); c2.y = ((c1.y + mm.y) / 2);
c4.x = ((mm.x + c5.x) >> 1); c4.x = ((mm.x + c5.x) / 2);
c4.y = ((mm.y + c5.y) >> 1); c4.y = ((mm.y + c5.y) / 2);
c3.x = ((c2.x + c4.x) >> 1); c3.x = ((c2.x + c4.x) / 2);
c3.y = ((c2.y + c4.y) >> 1); c3.y = ((c2.y + c4.y) / 2);
/* Add left recursion to stack */ /* Add left recursion to stack */
cleft->p1 = c->p1; cleft->p1 = c->p1;
@ -495,12 +474,12 @@ _cogl_path_bezier3_sub (CoglBezCubic *cubic)
} }
void void
cogl_path_curve_to (CoglFixed x1, cogl_path_curve_to (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed x3, float x3,
CoglFixed y3) float y3)
{ {
CoglBezCubic cubic; CoglBezCubic cubic;
@ -524,12 +503,12 @@ cogl_path_curve_to (CoglFixed x1,
} }
void void
cogl_path_rel_curve_to (CoglFixed x1, cogl_path_rel_curve_to (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed x3, float x3,
CoglFixed y3) float y3)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -554,11 +533,11 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad)
CoglBezQuad *qleft; CoglBezQuad *qleft;
CoglBezQuad *qright; CoglBezQuad *qright;
CoglBezQuad *q; CoglBezQuad *q;
CoglFixedVec2 mid; floatVec2 mid;
CoglFixedVec2 dif; floatVec2 dif;
CoglFixedVec2 c1; floatVec2 c1;
CoglFixedVec2 c2; floatVec2 c2;
CoglFixedVec2 c3; floatVec2 c3;
gint qindex; gint qindex;
/* Put first curve on stack */ /* Put first curve on stack */
@ -573,15 +552,15 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad)
/* Calculate distance of control point from its /* Calculate distance of control point from its
* counterpart on the line between end points */ * counterpart on the line between end points */
mid.x = ((q->p1.x + q->p3.x) >> 1); mid.x = ((q->p1.x + q->p3.x) / 2);
mid.y = ((q->p1.y + q->p3.y) >> 1); mid.y = ((q->p1.y + q->p3.y) / 2);
dif.x = (q->p2.x - mid.x); dif.x = (q->p2.x - mid.x);
dif.y = (q->p2.y - mid.y); dif.y = (q->p2.y - mid.y);
if (dif.x < 0) dif.x = -dif.x; if (dif.x < 0) dif.x = -dif.x;
if (dif.y < 0) dif.y = -dif.y; if (dif.y < 0) dif.y = -dif.y;
/* Cancel if the curve is flat enough */ /* 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) qindex == _COGL_MAX_BEZ_RECURSE_DEPTH - 1)
{ {
/* Add subdivision point (skip last) */ /* Add subdivision point (skip last) */
@ -594,12 +573,12 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad)
qright = q; qleft = &quads[++qindex]; qright = q; qleft = &quads[++qindex];
/* Subdivide into 2 sub-curves */ /* Subdivide into 2 sub-curves */
c1.x = ((q->p1.x + q->p2.x) >> 1); c1.x = ((q->p1.x + q->p2.x) / 2);
c1.y = ((q->p1.y + q->p2.y) >> 1); c1.y = ((q->p1.y + q->p2.y) / 2);
c3.x = ((q->p2.x + q->p3.x) >> 1); c3.x = ((q->p2.x + q->p3.x) / 2);
c3.y = ((q->p2.y + q->p3.y) >> 1); c3.y = ((q->p2.y + q->p3.y) / 2);
c2.x = ((c1.x + c3.x) >> 1); c2.x = ((c1.x + c3.x) / 2);
c2.y = ((c1.y + c3.y) >> 1); c2.y = ((c1.y + c3.y) / 2);
/* Add left recursion onto stack */ /* Add left recursion onto stack */
qleft->p1 = q->p1; qleft->p1 = q->p1;
@ -614,10 +593,10 @@ _cogl_path_bezier2_sub (CoglBezQuad *quad)
} }
void void
cogl_path_curve2_to (CoglFixed x1, cogl_path_curve2_to (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2) float y2)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -639,10 +618,10 @@ cogl_path_curve2_to (CoglFixed x1,
} }
void void
cogl_rel_curve2_to (CoglFixed x1, cogl_rel_curve2_to (float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2) float y2)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);

View File

@ -26,15 +26,15 @@
#ifndef __COGL_PRIMITIVES_H #ifndef __COGL_PRIMITIVES_H
#define __COGL_PRIMITIVES_H #define __COGL_PRIMITIVES_H
typedef struct _CoglFixedVec2 CoglFixedVec2; typedef struct _floatVec2 floatVec2;
typedef struct _CoglBezQuad CoglBezQuad; typedef struct _CoglBezQuad CoglBezQuad;
typedef struct _CoglBezCubic CoglBezCubic; typedef struct _CoglBezCubic CoglBezCubic;
typedef struct _CoglPathNode CoglPathNode; typedef struct _CoglPathNode CoglPathNode;
struct _CoglFixedVec2 struct _floatVec2
{ {
CoglFixed x; float x;
CoglFixed y; float y;
}; };
#ifdef CLUTTER_COGL_HAS_GL #ifdef CLUTTER_COGL_HAS_GL
@ -67,17 +67,17 @@ struct _CoglPathNode
struct _CoglBezQuad struct _CoglBezQuad
{ {
CoglFixedVec2 p1; floatVec2 p1;
CoglFixedVec2 p2; floatVec2 p2;
CoglFixedVec2 p3; floatVec2 p3;
}; };
struct _CoglBezCubic struct _CoglBezCubic
{ {
CoglFixedVec2 p1; floatVec2 p1;
CoglFixedVec2 p2; floatVec2 p2;
CoglFixedVec2 p3; floatVec2 p3;
CoglFixedVec2 p4; floatVec2 p4;
}; };
#endif /* __COGL_PRIMITIVES_H */ #endif /* __COGL_PRIMITIVES_H */

View File

@ -0,0 +1,142 @@
/*
* Cogl.
*
* An OpenGL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2008 Intel Corporation.
*
* Authored By: Robert Bragg <robert@linux.intel.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 */

View File

@ -10,7 +10,7 @@ libclutterinclude_HEADERS = \
$(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-shader.h \
$(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \
$(top_builddir)/clutter/cogl/cogl-types.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-material.h \
$(top_builddir)/clutter/cogl/cogl-matrix.h $(top_builddir)/clutter/cogl/cogl-matrix.h

View File

@ -76,7 +76,7 @@ cogl_create_context ()
_context->program_handles = NULL; _context->program_handles = NULL;
_context->mesh_handles = NULL; _context->vertex_buffer_handles = NULL;
_context->pf_glGenRenderbuffersEXT = NULL; _context->pf_glGenRenderbuffersEXT = NULL;
_context->pf_glBindRenderbufferEXT = NULL; _context->pf_glBindRenderbufferEXT = NULL;

View File

@ -51,12 +51,12 @@ typedef struct
gboolean enable_backface_culling; gboolean enable_backface_culling;
/* Primitives */ /* Primitives */
CoglFixedVec2 path_start; floatVec2 path_start;
CoglFixedVec2 path_pen; floatVec2 path_pen;
GArray *path_nodes; GArray *path_nodes;
guint last_path; guint last_path;
CoglFixedVec2 path_nodes_min; floatVec2 path_nodes_min;
CoglFixedVec2 path_nodes_max; floatVec2 path_nodes_max;
/* Cache of inverse projection matrix */ /* Cache of inverse projection matrix */
GLfloat inverse_projection[16]; GLfloat inverse_projection[16];
@ -91,8 +91,8 @@ typedef struct
/* Clip stack */ /* Clip stack */
CoglClipStackState clip; CoglClipStackState clip;
/* Mesh */ /* Vertex buffers */
GArray *mesh_handles; GArray *vertex_buffer_handles;
/* Relying on glext.h to define these */ /* Relying on glext.h to define these */
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT; COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;

View File

@ -34,52 +34,35 @@
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
#include <math.h>
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 #define _COGL_MAX_BEZ_RECURSE_DEPTH 16
void void
_cogl_rectangle (gint x, _cogl_rectangle (float x,
gint y, float y,
guint width, float width,
guint height) float height)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_enable (ctx->color_alpha < 255 cogl_enable (ctx->color_alpha < 255
? COGL_ENABLE_BLEND : 0); ? COGL_ENABLE_BLEND : 0);
GE( glRecti (x, y, x + width, y + height) ); GE( glRectf (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)) );
} }
void void
_cogl_path_add_node (gboolean new_sub_path, _cogl_path_add_node (gboolean new_sub_path,
CoglFixed x, float x,
CoglFixed y) float y)
{ {
CoglPathNode new_node; CoglPathNode new_node;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
new_node.x = COGL_FIXED_TO_FLOAT (x); new_node.x = (x);
new_node.y = COGL_FIXED_TO_FLOAT (y); new_node.y = (y);
new_node.path_size = 0; new_node.path_size = 0;
if (new_sub_path || ctx->path_nodes->len == 0) if (new_sub_path || ctx->path_nodes->len == 0)
@ -129,34 +112,32 @@ _cogl_path_stroke_nodes ()
} }
static void static void
_cogl_path_get_bounds (CoglFixedVec2 nodes_min, _cogl_path_get_bounds (floatVec2 nodes_min,
CoglFixedVec2 nodes_max, floatVec2 nodes_max,
gint *bounds_x, float *bounds_x,
gint *bounds_y, float *bounds_y,
guint *bounds_w, float *bounds_w,
guint *bounds_h) float *bounds_h)
{ {
*bounds_x = COGL_FIXED_FLOOR (nodes_min.x); *bounds_x = nodes_min.x;
*bounds_y = COGL_FIXED_FLOOR (nodes_min.y); *bounds_y = nodes_min.y;
*bounds_w = COGL_FIXED_CEIL (nodes_max.x *bounds_w = nodes_max.x - *bounds_x;
- COGL_FIXED_FROM_INT (*bounds_x)); *bounds_h = nodes_max.y - *bounds_y;
*bounds_h = COGL_FIXED_CEIL (nodes_max.y
- COGL_FIXED_FROM_INT (*bounds_y));
} }
void void
_cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
CoglFixedVec2 nodes_max, floatVec2 nodes_max,
guint path_size, guint path_size,
CoglPathNode *path, CoglPathNode *path,
gboolean merge) gboolean merge)
{ {
guint path_start = 0; guint path_start = 0;
guint sub_path_num = 0; guint sub_path_num = 0;
gint bounds_x; float bounds_x;
gint bounds_y; float bounds_y;
guint bounds_w; float bounds_w;
guint bounds_h; float bounds_h;
_cogl_path_get_bounds (nodes_min, nodes_max, _cogl_path_get_bounds (nodes_min, nodes_max,
&bounds_x, &bounds_y, &bounds_w, &bounds_h); &bounds_x, &bounds_y, &bounds_w, &bounds_h);
@ -238,10 +219,10 @@ _cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min,
void void
_cogl_path_fill_nodes () _cogl_path_fill_nodes ()
{ {
gint bounds_x; float bounds_x;
gint bounds_y; float bounds_y;
guint bounds_w; float bounds_w;
guint bounds_h; float bounds_h;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);

View File

@ -38,6 +38,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
/* /*
#define COGL_DEBUG 1 #define COGL_DEBUG 1
@ -59,15 +60,15 @@ struct _CoglSpanIter
gint index; gint index;
GArray *array; GArray *array;
CoglTexSliceSpan *span; CoglTexSliceSpan *span;
CoglFixed pos; float pos;
CoglFixed next_pos; float next_pos;
CoglFixed origin; float origin;
CoglFixed cover_start; float cover_start;
CoglFixed cover_end; float cover_end;
CoglFixed intersect_start; float intersect_start;
CoglFixed intersect_end; float intersect_end;
CoglFixed intersect_start_local; float intersect_start_local;
CoglFixed intersect_end_local; float intersect_end_local;
gboolean intersects; gboolean intersects;
}; };
@ -102,7 +103,7 @@ _cogl_span_iter_update (CoglSpanIter *iter)
/* Offset next position by span size */ /* Offset next position by span size */
iter->next_pos = iter->pos + 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 */ /* Check if span intersects the area to cover */
if (iter->next_pos <= iter->cover_start || if (iter->next_pos <= iter->cover_start ||
@ -131,9 +132,9 @@ _cogl_span_iter_update (CoglSpanIter *iter)
static void static void
_cogl_span_iter_begin (CoglSpanIter *iter, _cogl_span_iter_begin (CoglSpanIter *iter,
GArray *array, GArray *array,
CoglFixed origin, float origin,
CoglFixed cover_start, float cover_start,
CoglFixed cover_end) float cover_end)
{ {
/* Copy info */ /* Copy info */
iter->index = 0; iter->index = 0;
@ -471,8 +472,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
/* Iterate vertical spans */ /* Iterate vertical spans */
for (source_y = src_y, for (source_y = src_y,
_cogl_span_iter_begin (&y_iter, tex->slice_y_spans, _cogl_span_iter_begin (&y_iter, tex->slice_y_spans,
0, COGL_FIXED_FROM_INT (dst_y), 0, (float)(dst_y),
COGL_FIXED_FROM_INT (dst_y + height)); (float)(dst_y + height));
!_cogl_span_iter_end (&y_iter); !_cogl_span_iter_end (&y_iter);
@ -492,8 +493,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
/* Iterate horizontal spans */ /* Iterate horizontal spans */
for (source_x = src_x, for (source_x = src_x,
_cogl_span_iter_begin (&x_iter, tex->slice_x_spans, _cogl_span_iter_begin (&x_iter, tex->slice_x_spans,
0, COGL_FIXED_FROM_INT (dst_x), 0, (float)(dst_x),
COGL_FIXED_FROM_INT (dst_x + width)); (float)(dst_x + width));
!_cogl_span_iter_end (&x_iter); !_cogl_span_iter_end (&x_iter);
@ -511,15 +512,15 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
x_iter.index); x_iter.index);
/* Pick intersection width and height */ /* 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); x_iter.intersect_start);
inter_h = COGL_FIXED_TO_INT (y_iter.intersect_end - inter_h = (y_iter.intersect_end -
y_iter.intersect_start); y_iter.intersect_start);
/* Localize intersection top-left corner to slice*/ /* 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); x_iter.pos);
local_y = COGL_FIXED_TO_INT (y_iter.intersect_start - local_y = (y_iter.intersect_start -
y_iter.pos); y_iter.pos);
/* Pick slice GL handle */ /* Pick slice GL handle */
@ -555,7 +556,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
guint wx, wy; guint wx, wy;
src = source_bmp->data src = source_bmp->data
+ (src_y + COGL_FIXED_TO_INT (y_iter.intersect_start) + (src_y + ((int)y_iter.intersect_start)
- dst_y) - dst_y)
* source_bmp->rowstride * source_bmp->rowstride
+ (src_x + x_span->start + x_span->size - x_span->waste + (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; guint copy_width;
src = source_bmp->data src = source_bmp->data
+ (src_x + COGL_FIXED_TO_INT (x_iter.intersect_start) + (src_x + ((int)x_iter.intersect_start)
- dst_x) - dst_x)
* bpp * bpp
+ (src_y + y_span->start + y_span->size - y_span->waste + (src_y + y_span->start + y_span->size - y_span->waste
@ -1188,11 +1189,11 @@ _cogl_texture_free (CoglTexture *tex)
} }
CoglHandle CoglHandle
cogl_texture_new_with_size (guint width, cogl_texture_new_with_size (guint width,
guint height, guint height,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat internal_format) CoglPixelFormat internal_format)
{ {
CoglTexture *tex; CoglTexture *tex;
gint bpp; gint bpp;
@ -1213,7 +1214,7 @@ cogl_texture_new_with_size (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex); COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = auto_mipmap; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0);
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1248,14 +1249,14 @@ cogl_texture_new_with_size (guint width,
} }
CoglHandle CoglHandle
cogl_texture_new_from_data (guint width, cogl_texture_new_from_data (guint width,
guint height, guint height,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat format, CoglPixelFormat format,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
guint rowstride, guint rowstride,
const guchar *data) const guchar *data)
{ {
CoglTexture *tex; CoglTexture *tex;
gint bpp; gint bpp;
@ -1277,7 +1278,7 @@ cogl_texture_new_from_data (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex); COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = auto_mipmap; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0);
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1323,30 +1324,13 @@ cogl_texture_new_from_data (guint width,
} }
CoglHandle CoglHandle
cogl_texture_new_from_file (const gchar *filename, cogl_texture_new_from_bitmap (CoglBitmap *bmp,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format)
GError **error)
{ {
CoglBitmap bmp;
CoglTexture *tex; 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 */ /* Create new texture and fill with loaded data */
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
@ -1354,10 +1338,11 @@ cogl_texture_new_from_file (const gchar *filename,
COGL_HANDLE_DEBUG_NEW (texture, tex); COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE; 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; tex->bitmap_owner = TRUE;
bmp->data = NULL;
tex->slice_x_spans = NULL; tex->slice_x_spans = NULL;
tex->slice_y_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); 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 CoglHandle
cogl_texture_new_from_foreign (GLuint gl_handle, cogl_texture_new_from_foreign (GLuint gl_handle,
GLenum gl_target, GLenum gl_target,
@ -2002,24 +2011,24 @@ _cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1,
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2) float ty2)
{ {
CoglSpanIter iter_x , iter_y; CoglSpanIter iter_x , iter_y;
CoglFixed tw , th; float tw , th;
CoglFixed tqx , tqy; float tqx , tqy;
CoglFixed first_tx , first_ty; float first_tx , first_ty;
CoglFixed first_qx , first_qy; float first_qx , first_qy;
CoglFixed slice_tx1 , slice_ty1; float slice_tx1 , slice_ty1;
CoglFixed slice_tx2 , slice_ty2; float slice_tx2 , slice_ty2;
CoglFixed slice_qx1 , slice_qy1; float slice_qx1 , slice_qy1;
CoglFixed slice_qx2 , slice_qy2; float slice_qx2 , slice_qy2;
GLuint gl_handle; GLuint gl_handle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -2042,7 +2051,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
slices */ slices */
if (tx2 < tx1) if (tx2 < tx1)
{ {
CoglFixed temp = x1; float temp = x1;
x1 = x2; x1 = x2;
x2 = temp; x2 = temp;
temp = tx1; temp = tx1;
@ -2051,7 +2060,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
} }
if (ty2 < ty1) if (ty2 < ty1)
{ {
CoglFixed temp = y1; float temp = y1;
y1 = y2; y1 = y2;
y2 = temp; y2 = temp;
temp = ty1; temp = ty1;
@ -2060,27 +2069,27 @@ _cogl_texture_quad_sw (CoglTexture *tex,
} }
/* Scale ratio from texture to quad widths */ /* Scale ratio from texture to quad widths */
tw = COGL_FIXED_FROM_INT (tex->bitmap.width); tw = (float)(tex->bitmap.width);
th = COGL_FIXED_FROM_INT (tex->bitmap.height); th = (float)(tex->bitmap.height);
tqx = COGL_FIXED_DIV (x2 - x1, COGL_FIXED_MUL (tw, (tx2 - tx1))); tqx = (x2 - x1) / (tw * (tx2 - tx1));
tqy = COGL_FIXED_DIV (y2 - y1, COGL_FIXED_MUL (th, (ty2 - ty1))); tqy = (y2 - y1) / (th * (ty2 - ty1));
/* Integral texture coordinate for first tile */ /* Integral texture coordinate for first tile */
first_tx = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (tx1)); first_tx = (float)(floorf (tx1));
first_ty = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (ty1)); first_ty = (float)(floorf (ty1));
/* Denormalize texture coordinates */ /* Denormalize texture coordinates */
first_tx = COGL_FIXED_MUL (first_tx, tw); first_tx = (first_tx * tw);
first_ty = COGL_FIXED_MUL (first_ty, th); first_ty = (first_ty * th);
tx1 = COGL_FIXED_MUL (tx1, tw); tx1 = (tx1 * tw);
ty1 = COGL_FIXED_MUL (ty1, th); ty1 = (ty1 * th);
tx2 = COGL_FIXED_MUL (tx2, tw); tx2 = (tx2 * tw);
ty2 = COGL_FIXED_MUL (ty2, th); ty2 = (ty2 * th);
/* Quad coordinate of the first tile */ /* Quad coordinate of the first tile */
first_qx = x1 - COGL_FIXED_MUL (tx1 - first_tx, tqx); first_qx = x1 - (tx1 - first_tx) * tqx;
first_qy = y1 - COGL_FIXED_MUL (ty1 - first_ty, tqy); first_qy = y1 - (ty1 - first_ty) * tqy;
/* Iterate until whole quad height covered */ /* Iterate until whole quad height covered */
@ -2093,11 +2102,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
if (!iter_y.intersects) continue; if (!iter_y.intersects) continue;
/* Span-quad intersection in quad coordinates */ /* Span-quad intersection in quad coordinates */
slice_qy1 = first_qy + slice_qy1 = first_qy + (iter_y.intersect_start - first_ty) * tqy;
COGL_FIXED_MUL (iter_y.intersect_start - first_ty, tqy);
slice_qy2 = first_qy + slice_qy2 = first_qy + (iter_y.intersect_end - first_ty) * tqy;
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_ty1 = iter_y.intersect_start - iter_y.pos; slice_ty1 = iter_y.intersect_start - iter_y.pos;
@ -2121,11 +2128,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
if (!iter_x.intersects) continue; if (!iter_x.intersects) continue;
/* Span-quad intersection in quad coordinates */ /* Span-quad intersection in quad coordinates */
slice_qx1 = first_qx + slice_qx1 = first_qx + (iter_x.intersect_start - first_tx) * tqx;
COGL_FIXED_MUL (iter_x.intersect_start - first_tx, tqx);
slice_qx2 = first_qx + slice_qx2 = first_qx + (iter_x.intersect_end - first_tx) * tqx;
COGL_FIXED_MUL (iter_x.intersect_end - first_tx, tqx);
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_tx1 = iter_x.intersect_start - iter_x.pos; slice_tx1 = iter_x.intersect_start - iter_x.pos;
@ -2141,14 +2146,14 @@ _cogl_texture_quad_sw (CoglTexture *tex,
#if COGL_DEBUG #if COGL_DEBUG
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); printf("qx1: %f\n", (slice_qx1));
printf("qy1: %f\n", COGL_FIXED_TO_FLOAT (slice_qy1)); printf("qy1: %f\n", (slice_qy1));
printf("qx2: %f\n", COGL_FIXED_TO_FLOAT (slice_qx2)); printf("qx2: %f\n", (slice_qx2));
printf("qy2: %f\n", COGL_FIXED_TO_FLOAT (slice_qy2)); printf("qy2: %f\n", (slice_qy2));
printf("tx1: %f\n", COGL_FIXED_TO_FLOAT (slice_tx1)); printf("tx1: %f\n", (slice_tx1));
printf("ty1: %f\n", COGL_FIXED_TO_FLOAT (slice_ty1)); printf("ty1: %f\n", (slice_ty1));
printf("tx2: %f\n", COGL_FIXED_TO_FLOAT (slice_tx2)); printf("tx2: %f\n", (slice_tx2));
printf("ty2: %f\n", COGL_FIXED_TO_FLOAT (slice_ty2)); printf("ty2: %f\n", (slice_ty2));
#endif #endif
/* Pick and bind opengl texture object */ /* Pick and bind opengl texture object */
@ -2164,28 +2169,28 @@ _cogl_texture_quad_sw (CoglTexture *tex,
ctx->texture_target = tex->gl_target; ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle; ctx->texture_current = gl_handle;
_cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1), _cogl_texture_add_quad_vertices ( (slice_qx1),
COGL_FIXED_TO_FLOAT (slice_qy1), (slice_qy1),
COGL_FIXED_TO_FLOAT (slice_qx2), (slice_qx2),
COGL_FIXED_TO_FLOAT (slice_qy2), (slice_qy2),
COGL_FIXED_TO_FLOAT (slice_tx1), (slice_tx1),
COGL_FIXED_TO_FLOAT (slice_ty1), (slice_ty1),
COGL_FIXED_TO_FLOAT (slice_tx2), (slice_tx2),
COGL_FIXED_TO_FLOAT (slice_ty2)); (slice_ty2));
} }
} }
} }
static void static void
_cogl_texture_quad_hw (CoglTexture *tex, _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2) float ty2)
{ {
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; 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 /* 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 clamp the coords to the edge otherwise it can pull in edge pixels
from the wrong side when scaled */ from the wrong side when scaled */
if (tx1 >= 0 && tx1 <= COGL_FIXED_1 if (tx1 >= 0 && tx1 <= 1.0
&& tx2 >= 0 && tx2 <= COGL_FIXED_1 && tx2 >= 0 && tx2 <= 1.0
&& ty1 >= 0 && ty1 <= COGL_FIXED_1 && ty1 >= 0 && ty1 <= 1.0
&& ty2 >= 0 && ty2 <= COGL_FIXED_1) && ty2 >= 0 && ty2 <= 1.0)
wrap_mode = GL_CLAMP_TO_EDGE; wrap_mode = GL_CLAMP_TO_EDGE;
else else
wrap_mode = GL_REPEAT; wrap_mode = GL_REPEAT;
@ -2243,19 +2248,19 @@ _cogl_texture_quad_hw (CoglTexture *tex,
ty2 *= y_span->size; ty2 *= y_span->size;
} }
_cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1), _cogl_texture_add_quad_vertices ( (x1),
COGL_FIXED_TO_FLOAT (y1), (y1),
COGL_FIXED_TO_FLOAT (x2), (x2),
COGL_FIXED_TO_FLOAT (y2), (y2),
COGL_FIXED_TO_FLOAT (tx1), (tx1),
COGL_FIXED_TO_FLOAT (ty1), (ty1),
COGL_FIXED_TO_FLOAT (tx2), (tx2),
COGL_FIXED_TO_FLOAT (ty2)); (ty2));
} }
void void
cogl_texture_multiple_rectangles (CoglHandle handle, cogl_texture_multiple_rectangles (CoglHandle handle,
const CoglFixed *verts, const float *verts,
guint n_rects) guint n_rects)
{ {
CoglTexture *tex; CoglTexture *tex;
@ -2306,10 +2311,10 @@ cogl_texture_multiple_rectangles (CoglHandle handle,
if (tex->slice_gl_handles->len == 1 if (tex->slice_gl_handles->len == 1
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D) && tex->gl_target == GL_TEXTURE_2D)
|| (verts[4] >= 0 && verts[4] <= COGL_FIXED_1 || (verts[4] >= 0 && verts[4] <= 1.0
&& verts[6] >= 0 && verts[6] <= COGL_FIXED_1 && verts[6] >= 0 && verts[6] <= 1.0
&& verts[5] >= 0 && verts[5] <= COGL_FIXED_1 && verts[5] >= 0 && verts[5] <= 1.0
&& verts[7] >= 0 && verts[7] <= COGL_FIXED_1))) && verts[7] >= 0 && verts[7] <= 1.0)))
_cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3], _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]); verts[4],verts[5], verts[6],verts[7]);
else else
@ -2325,16 +2330,16 @@ cogl_texture_multiple_rectangles (CoglHandle handle,
void void
cogl_texture_rectangle (CoglHandle handle, cogl_texture_rectangle (CoglHandle handle,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2) float ty2)
{ {
CoglFixed verts[8]; float verts[8];
verts[0] = x1; verts[0] = x1;
verts[1] = y1; verts[1] = y1;
@ -2447,16 +2452,16 @@ cogl_texture_polygon (CoglHandle handle,
OpenGL */ OpenGL */
for (i = 0; i < n_vertices; i++, p++) 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 tx = ((vertices[i].tx
- (COGL_FIXED_FROM_INT (x_span->start) - ((float)(x_span->start)
/ tex->bitmap.width)) / tex->bitmap.width))
* tex->bitmap.width / x_span->size); * tex->bitmap.width / x_span->size);
ty = ((vertices[i].ty ty = ((vertices[i].ty
- (COGL_FIXED_FROM_INT (y_span->start) - ((float)(y_span->start)
/ tex->bitmap.height)) / tex->bitmap.height))
* tex->bitmap.height / y_span->size); * tex->bitmap.height / y_span->size);

View File

@ -209,40 +209,23 @@ cogl_pop_matrix (void)
} }
void void
cogl_scale (CoglFixed x, CoglFixed y) cogl_scale (float x, float y)
{ {
glScaled (COGL_FIXED_TO_DOUBLE (x), glScalef ((float)(x),
COGL_FIXED_TO_DOUBLE (y), (float)(y),
1.0); 1.0);
} }
void void
cogl_translatex (CoglFixed x, CoglFixed y, CoglFixed z) cogl_translate (float x, float y, float z)
{ {
glTranslated (COGL_FIXED_TO_DOUBLE (x), glTranslatef (x, y, z);
COGL_FIXED_TO_DOUBLE (y),
COGL_FIXED_TO_DOUBLE (z));
} }
void 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); glRotatef (angle, x, y, 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);
} }
static inline gboolean static inline gboolean
@ -466,24 +449,24 @@ set_clip_plane (GLint plane_num,
} }
void void
_cogl_set_clip_planes (CoglFixed x_offset, _cogl_set_clip_planes (float x_offset,
CoglFixed y_offset, float y_offset,
CoglFixed width, float width,
CoglFixed height) float height)
{ {
GLfloat modelview[16], projection[16]; GLfloat modelview[16], projection[16];
GLfloat vertex_tl[4] = { COGL_FIXED_TO_FLOAT (x_offset), GLfloat vertex_tl[4] = { (x_offset),
COGL_FIXED_TO_FLOAT (y_offset), (y_offset),
0.0f, 1.0f }; 0.0f, 1.0f };
GLfloat vertex_tr[4] = { COGL_FIXED_TO_FLOAT (x_offset + width), GLfloat vertex_tr[4] = { (x_offset + width),
COGL_FIXED_TO_FLOAT (y_offset), (y_offset),
0.0f, 1.0f }; 0.0f, 1.0f };
GLfloat vertex_bl[4] = { COGL_FIXED_TO_FLOAT (x_offset), GLfloat vertex_bl[4] = { (x_offset),
COGL_FIXED_TO_FLOAT (y_offset + height), (y_offset + height),
0.0f, 1.0f }; 0.0f, 1.0f };
GLfloat vertex_br[4] = { COGL_FIXED_TO_FLOAT (x_offset + width), GLfloat vertex_br[4] = { (x_offset + width),
COGL_FIXED_TO_FLOAT (y_offset + height), (y_offset + height),
0.0f, 1.0f }; 0.0f, 1.0f };
GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) ); GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
@ -518,10 +501,10 @@ _cogl_set_clip_planes (CoglFixed x_offset,
} }
void void
_cogl_add_stencil_clip (CoglFixed x_offset, _cogl_add_stencil_clip (float x_offset,
CoglFixed y_offset, float y_offset,
CoglFixed width, float width,
CoglFixed height, float height,
gboolean first) gboolean first)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _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 */ /* Punch out a hole to allow the rectangle */
GE( glStencilFunc (GL_NEVER, 0x1, 0x1) ); GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) ); GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) );
GE( glRectf (COGL_FIXED_TO_FLOAT (x_offset), GE( glRectf ( (x_offset),
COGL_FIXED_TO_FLOAT (y_offset), (y_offset),
COGL_FIXED_TO_FLOAT (x_offset + width), (x_offset + width),
COGL_FIXED_TO_FLOAT (y_offset + height)) ); (y_offset + height)) );
} }
else else
{ {
@ -548,10 +531,10 @@ _cogl_add_stencil_clip (CoglFixed x_offset,
rectangle */ rectangle */
GE( glStencilFunc (GL_NEVER, 0x1, 0x3) ); GE( glStencilFunc (GL_NEVER, 0x1, 0x3) );
GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
GE( glRectf (COGL_FIXED_TO_FLOAT (x_offset), GE( glRectf ( (x_offset),
COGL_FIXED_TO_FLOAT (y_offset), (y_offset),
COGL_FIXED_TO_FLOAT (x_offset + width), (x_offset + width),
COGL_FIXED_TO_FLOAT (y_offset + height)) ); (y_offset + height)) );
/* Subtract one from all pixels in the stencil buffer so that /* Subtract one from all pixels in the stencil buffer so that
only pixels where both the original stencil buffer and the only pixels where both the original stencil buffer and the
@ -574,13 +557,13 @@ _cogl_add_stencil_clip (CoglFixed x_offset,
} }
void void
_cogl_set_matrix (const CoglFixed *matrix) _cogl_set_matrix (const float *matrix)
{ {
float float_matrix[16]; float float_matrix[16];
int i; int i;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
float_matrix[i] = COGL_FIXED_TO_FLOAT (matrix[i]); float_matrix[i] = (matrix[i]);
GE( glLoadIdentity () ); GE( glLoadIdentity () );
GE( glMultMatrixf (float_matrix) ); GE( glMultMatrixf (float_matrix) );
@ -612,20 +595,20 @@ _cogl_disable_clip_planes (void)
void void
cogl_alpha_func (COGLenum func, cogl_alpha_func (COGLenum func,
CoglFixed ref) float ref)
{ {
GE( glAlphaFunc (func, COGL_FIXED_TO_FLOAT(ref)) ); GE( glAlphaFunc (func, (ref)) );
} }
void void
cogl_perspective (CoglFixed fovy, cogl_perspective (float fovy,
CoglFixed aspect, float aspect,
CoglFixed zNear, float zNear,
CoglFixed zFar) float zFar)
{ {
CoglFixed xmax, ymax; float xmax, ymax;
CoglFixed x, y, c, d; float x, y, c, d;
CoglFixed fovy_rad_half = COGL_FIXED_MUL (fovy, COGL_FIXED_PI) / 360; float fovy_rad_half = (fovy * G_PI) / 360;
GLfloat m[16]; GLfloat m[16];
@ -645,23 +628,19 @@ cogl_perspective (CoglFixed fovy,
* 2) When working with small numbers, we are loosing significant * 2) When working with small numbers, we are loosing significant
* precision * precision
*/ */
ymax = ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
COGL_FIXED_MUL (zNear, xmax = (ymax * aspect);
COGL_FIXED_FAST_DIV (cogl_fixed_sin (fovy_rad_half),
cogl_fixed_cos (fovy_rad_half)));
xmax = COGL_FIXED_MUL (ymax, aspect); x = (zNear / xmax);
y = (zNear / ymax);
x = COGL_FIXED_FAST_DIV (zNear, xmax); c = (-(zFar + zNear) / ( zFar - zNear));
y = COGL_FIXED_FAST_DIV (zNear, ymax); d = (-(2 * zFar) * zNear) / (zFar - zNear);
c = COGL_FIXED_FAST_DIV (-(zFar + zNear), ( zFar - zNear));
d = cogl_fixed_mul_div (-(2 * zFar), zNear, (zFar - zNear));
#define M(row,col) m[col*4+row] #define M(row,col) m[col*4+row]
M(0,0) = COGL_FIXED_TO_FLOAT (x); M(0,0) = (x);
M(1,1) = COGL_FIXED_TO_FLOAT (y); M(1,1) = (y);
M(2,2) = COGL_FIXED_TO_FLOAT (c); M(2,2) = (c);
M(2,3) = COGL_FIXED_TO_FLOAT (d); M(2,3) = (d);
M(3,2) = -1.0F; M(3,2) = -1.0F;
GE( glMultMatrixf (m) ); GE( glMultMatrixf (m) );
@ -672,22 +651,22 @@ cogl_perspective (CoglFixed fovy,
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16); memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
#define m ctx->inverse_projection #define m ctx->inverse_projection
M(0, 0) = 1.0f / COGL_FIXED_TO_FLOAT (x); M(0, 0) = 1.0f / (x);
M(1, 1) = 1.0f / COGL_FIXED_TO_FLOAT (y); M(1, 1) = 1.0f / (y);
M(2, 3) = -1.0f; M(2, 3) = -1.0f;
M(3, 2) = 1.0f / COGL_FIXED_TO_FLOAT (d); M(3, 2) = 1.0f / (d);
M(3, 3) = COGL_FIXED_TO_FLOAT (c) / COGL_FIXED_TO_FLOAT (d); M(3, 3) = (c) / (d);
#undef m #undef m
#undef M #undef M
} }
void void
cogl_frustum (CoglFixed left, cogl_frustum (float left,
CoglFixed right, float right,
CoglFixed bottom, float bottom,
CoglFixed top, float top,
CoglFixed z_near, float z_near,
CoglFixed z_far) float z_far)
{ {
GLfloat c, d; GLfloat c, d;
@ -696,32 +675,32 @@ cogl_frustum (CoglFixed left,
GE( glMatrixMode (GL_PROJECTION) ); GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () ); GE( glLoadIdentity () );
GE( glFrustum (COGL_FIXED_TO_DOUBLE (left), GE( glFrustum ((GLdouble)(left),
COGL_FIXED_TO_DOUBLE (right), (GLdouble)(right),
COGL_FIXED_TO_DOUBLE (bottom), (GLdouble)(bottom),
COGL_FIXED_TO_DOUBLE (top), (GLdouble)(top),
COGL_FIXED_TO_DOUBLE (z_near), (GLdouble)(z_near),
COGL_FIXED_TO_DOUBLE (z_far)) ); (GLdouble)(z_far)) );
GE( glMatrixMode (GL_MODELVIEW) ); GE( glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */ /* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16); memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
c = -COGL_FIXED_TO_FLOAT (z_far + z_near) c = - (z_far + z_near)
/ COGL_FIXED_TO_FLOAT (z_far - z_near); / (z_far - z_near);
d = -COGL_FIXED_TO_FLOAT (2 * COGL_FIXED_MUL (z_far, z_near)) d = - (2 * (z_far * z_near))
/ COGL_FIXED_TO_FLOAT (z_far - z_near); / (z_far - z_near);
#define M(row,col) ctx->inverse_projection[col*4+row] #define M(row,col) ctx->inverse_projection[col*4+row]
M(0,0) = COGL_FIXED_TO_FLOAT (right - left) M(0,0) = (right - left)
/ COGL_FIXED_TO_FLOAT (2 * z_near); / (2 * z_near);
M(0,3) = COGL_FIXED_TO_FLOAT (right + left) M(0,3) = (right + left)
/ COGL_FIXED_TO_FLOAT (2 * z_near); / (2 * z_near);
M(1,1) = COGL_FIXED_TO_FLOAT (top - bottom) M(1,1) = (top - bottom)
/ COGL_FIXED_TO_FLOAT (2 * z_near); / (2 * z_near);
M(1,3) = COGL_FIXED_TO_FLOAT (top + bottom) M(1,3) = (top + bottom)
/ COGL_FIXED_TO_FLOAT (2 * z_near); / (2 * z_near);
M(2,3) = -1.0f; M(2,3) = -1.0f;
M(3,2) = 1.0f / d; M(3,2) = 1.0f / d;
M(3,3) = c / d; M(3,3) = c / d;
@ -738,45 +717,61 @@ cogl_viewport (guint width,
void void
cogl_setup_viewport (guint width, cogl_setup_viewport (guint width,
guint height, guint height,
CoglFixed fovy, float fovy,
CoglFixed aspect, float aspect,
CoglFixed z_near, float z_near,
CoglFixed z_far) float z_far)
{ {
GLfloat z_camera; GLfloat z_camera;
GLfloat projection_matrix[16];
GE( glViewport (0, 0, width, height) ); GE( glViewport (0, 0, width, height) );
cogl_perspective (fovy, aspect, z_near, z_far); 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 * 0.5 * tan (FOV)
* 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.
* *
* So for the default 60 deg angle we worked out that the value of 0.869 * However, it's better to compute the z_camera from our projection
* is giving correct stretch and no noticeable artifacts on text. Seems * matrix so that we get a 1:1 mapping at the screen distance. Consider
* good on all drivers too. * 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) GE( glLoadIdentity () );
{
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( glTranslatef (-0.5f, -0.5f, -z_camera) ); GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
GE( glScalef ( 1.0f / width, GE( glScalef ( 1.0f / width,
@ -1164,75 +1159,21 @@ cogl_features_available (CoglFeatureFlags features)
} }
void void
cogl_get_modelview_matrix (CoglFixed m[16]) cogl_get_modelview_matrix (float m[16])
{ {
GLdouble md[16]; glGetFloatv (GL_MODELVIEW_MATRIX, m);
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
} }
void void
cogl_get_projection_matrix (CoglFixed m[16]) cogl_get_projection_matrix (float m[16])
{ {
GLdouble md[16]; glGetFloatv (GL_PROJECTION_MATRIX, m);
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
} }
void void
cogl_get_viewport (CoglFixed v[4]) cogl_get_viewport (float v[4])
{ {
GLdouble vd[4]; glGetFloatv (GL_VIEWPORT, v);
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]);
} }
void void
@ -1263,9 +1204,9 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
void void
cogl_fog_set (const CoglColor *fog_color, cogl_fog_set (const CoglColor *fog_color,
CoglFixed density, float density,
CoglFixed start, float start,
CoglFixed stop) float stop)
{ {
GLfloat fogColor[4]; GLfloat fogColor[4];
@ -1281,8 +1222,8 @@ cogl_fog_set (const CoglColor *fog_color,
glFogi (GL_FOG_MODE, GL_LINEAR); glFogi (GL_FOG_MODE, GL_LINEAR);
glHint (GL_FOG_HINT, GL_NICEST); glHint (GL_FOG_HINT, GL_NICEST);
glFogf (GL_FOG_DENSITY, COGL_FIXED_TO_FLOAT (density)); glFogf (GL_FOG_DENSITY, (density));
glFogf (GL_FOG_START, COGL_FIXED_TO_FLOAT (start)); glFogf (GL_FOG_START, (start));
glFogf (GL_FOG_END, COGL_FIXED_TO_FLOAT (stop)); glFogf (GL_FOG_END, (stop));
} }

View File

@ -10,7 +10,7 @@ libclutterinclude_HEADERS = \
$(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-shader.h \
$(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \
$(top_builddir)/clutter/cogl/cogl-types.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-material.h \
$(top_builddir)/clutter/cogl/cogl-matrix.h $(top_builddir)/clutter/cogl/cogl-matrix.h

View File

@ -73,7 +73,7 @@ cogl_create_context ()
_context->shader_handles = NULL; _context->shader_handles = NULL;
_context->draw_buffer = COGL_WINDOW_BUFFER; _context->draw_buffer = COGL_WINDOW_BUFFER;
_context->mesh_handles = NULL; _context->vertex_buffer_handles = NULL;
_context->blend_src_factor = CGL_SRC_ALPHA; _context->blend_src_factor = CGL_SRC_ALPHA;
_context->blend_dst_factor = CGL_ONE_MINUS_SRC_ALPHA; _context->blend_dst_factor = CGL_ONE_MINUS_SRC_ALPHA;
@ -84,7 +84,7 @@ cogl_create_context ()
#endif #endif
/* Init OpenGL state */ /* 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( glColorMask (TRUE, TRUE, TRUE, FALSE) );
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ); GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
cogl_enable (0); cogl_enable (0);

View File

@ -53,15 +53,15 @@ typedef struct
gboolean enable_backface_culling; gboolean enable_backface_culling;
/* Primitives */ /* Primitives */
CoglFixedVec2 path_start; floatVec2 path_start;
CoglFixedVec2 path_pen; floatVec2 path_pen;
GArray *path_nodes; GArray *path_nodes;
guint last_path; guint last_path;
CoglFixedVec2 path_nodes_min; floatVec2 path_nodes_min;
CoglFixedVec2 path_nodes_max; floatVec2 path_nodes_max;
/* Cache of inverse projection matrix */ /* Cache of inverse projection matrix */
CoglFixed inverse_projection[16]; float inverse_projection[16];
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
@ -72,6 +72,7 @@ typedef struct
can be flushed */ can be flushed */
GLuint texture_current; GLuint texture_current;
GLenum texture_target; GLenum texture_target;
GLenum texture_format;
/* Materials */ /* Materials */
GArray *material_handles; GArray *material_handles;
@ -86,8 +87,8 @@ typedef struct
GArray *program_handles; GArray *program_handles;
GArray *shader_handles; GArray *shader_handles;
/* Mesh */ /* Vertex buffers */
GArray *mesh_handles; GArray *vertex_buffer_handles;
/* Clip stack */ /* Clip stack */
CoglClipStackState clip; CoglClipStackState clip;

View File

@ -227,12 +227,12 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
/* Setup new viewport and matrices */ /* Setup new viewport and matrices */
GE( glViewport (0, 0, fbo->width, fbo->height) ); GE( glViewport (0, 0, fbo->width, fbo->height) );
GE( cogl_wrap_glTranslatex (-COGL_FIXED_1, -COGL_FIXED_1, 0) ); GE( cogl_wrap_glTranslatef (-1.0, -1.0, 0) );
GE( cogl_wrap_glScalex (COGL_FIXED_DIV (COGL_FIXED_FROM_INT (2), GE( cogl_wrap_glScalef (((float)(2) /
COGL_FIXED_FROM_INT (fbo->width)), (float)(fbo->width)),
COGL_FIXED_DIV (COGL_FIXED_FROM_INT (2), ((float)(2) /
COGL_FIXED_FROM_INT (fbo->height)), (float)(fbo->height)),
COGL_FIXED_1) ); 1.0) );
/* Bind offscreen framebuffer object */ /* Bind offscreen framebuffer object */
GE( glBindFramebuffer (GL_FRAMEBUFFER, fbo->gl_handle) ); GE( glBindFramebuffer (GL_FRAMEBUFFER, fbo->gl_handle) );

View File

@ -105,7 +105,7 @@ cogl_gles2_wrapper_create_shader (GLenum type, const char *source)
void void
cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper) 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)); memset (wrapper, 0, sizeof (CoglGles2Wrapper));
@ -125,11 +125,11 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
/* Initialize the fogging options */ /* Initialize the fogging options */
cogl_wrap_glDisable (GL_FOG); cogl_wrap_glDisable (GL_FOG);
cogl_wrap_glFogx (GL_FOG_MODE, GL_LINEAR); cogl_wrap_glFogf (GL_FOG_MODE, GL_LINEAR);
cogl_wrap_glFogx (GL_FOG_DENSITY, COGL_FIXED_1); cogl_wrap_glFogf (GL_FOG_DENSITY, 1.0);
cogl_wrap_glFogx (GL_FOG_START, 0); cogl_wrap_glFogf (GL_FOG_START, 0);
cogl_wrap_glFogx (GL_FOG_END, 1); cogl_wrap_glFogf (GL_FOG_END, 1);
cogl_wrap_glFogxv (GL_FOG_COLOR, default_fog_color); cogl_wrap_glFogfv (GL_FOG_COLOR, default_fog_color);
/* Initialize alpha testing */ /* Initialize alpha testing */
cogl_wrap_glDisable (GL_ALPHA_TEST); 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 void
cogl_wrap_glPushMatrix () cogl_wrap_glPushMatrix ()
{ {
@ -810,58 +801,58 @@ cogl_wrap_glMultMatrix (const float *m)
} }
void void
cogl_wrap_glMultMatrixx (const GLfixed *m) cogl_wrap_glMultMatrixf (const GLfloat *m)
{ {
float new_matrix[16]; float new_matrix[16];
int i; int i;
for (i = 0; i < 16; 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); cogl_wrap_glMultMatrix (new_matrix);
} }
void void
cogl_wrap_glFrustumx (GLfixed left, GLfixed right, cogl_wrap_glFrustumf (GLfloat left, GLfloat right,
GLfixed bottom, GLfixed top, GLfloat bottom, GLfloat top,
GLfixed z_near, GLfixed z_far) GLfloat z_near, GLfloat z_far)
{ {
float matrix[16]; float matrix[16];
float two_near = COGL_FIXED_TO_FLOAT (2 * z_near); float two_near = (2 * z_near);
memset (matrix, 0, sizeof (matrix)); memset (matrix, 0, sizeof (matrix));
matrix[0] = two_near / COGL_FIXED_TO_FLOAT (right - left); matrix[0] = two_near / (right - left);
matrix[5] = two_near / COGL_FIXED_TO_FLOAT (top - bottom); matrix[5] = two_near / (top - bottom);
matrix[8] = COGL_FIXED_TO_FLOAT (right + left) matrix[8] = (right + left)
/ COGL_FIXED_TO_FLOAT (right - left); / (right - left);
matrix[9] = COGL_FIXED_TO_FLOAT (top + bottom) matrix[9] = (top + bottom)
/ COGL_FIXED_TO_FLOAT (top - bottom); / (top - bottom);
matrix[10] = -COGL_FIXED_TO_FLOAT (z_far + z_near) matrix[10] = - (z_far + z_near)
/ COGL_FIXED_TO_FLOAT (z_far - z_near); / (z_far - z_near);
matrix[11] = -1.0f; matrix[11] = -1.0f;
matrix[14] = -two_near * COGL_FIXED_TO_FLOAT (z_far) matrix[14] = -two_near * (z_far)
/ COGL_FIXED_TO_FLOAT (z_far - z_near); / (z_far - z_near);
cogl_wrap_glMultMatrix (matrix); cogl_wrap_glMultMatrix (matrix);
} }
void void
cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z) cogl_wrap_glScalef (GLfloat x, GLfloat y, GLfloat z)
{ {
float matrix[16]; float matrix[16];
memset (matrix, 0, sizeof (matrix)); memset (matrix, 0, sizeof (matrix));
matrix[0] = COGL_FIXED_TO_FLOAT (x); matrix[0] = (x);
matrix[5] = COGL_FIXED_TO_FLOAT (y); matrix[5] = (y);
matrix[10] = COGL_FIXED_TO_FLOAT (z); matrix[10] = (z);
matrix[15] = 1.0f; matrix[15] = 1.0f;
cogl_wrap_glMultMatrix (matrix); cogl_wrap_glMultMatrix (matrix);
} }
void void
cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z) cogl_wrap_glTranslatef (GLfloat x, GLfloat y, GLfloat z)
{ {
float matrix[16]; float matrix[16];
@ -869,22 +860,22 @@ cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z)
matrix[0] = 1.0f; matrix[0] = 1.0f;
matrix[5] = 1.0f; matrix[5] = 1.0f;
matrix[10] = 1.0f; matrix[10] = 1.0f;
matrix[12] = COGL_FIXED_TO_FLOAT (x); matrix[12] = (x);
matrix[13] = COGL_FIXED_TO_FLOAT (y); matrix[13] = (y);
matrix[14] = COGL_FIXED_TO_FLOAT (z); matrix[14] = (z);
matrix[15] = 1.0f; matrix[15] = 1.0f;
cogl_wrap_glMultMatrix (matrix); cogl_wrap_glMultMatrix (matrix);
} }
void 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 matrix[16];
float xf = COGL_FIXED_TO_FLOAT (x); float xf = (x);
float yf = COGL_FIXED_TO_FLOAT (y); float yf = (y);
float zf = COGL_FIXED_TO_FLOAT (z); float zf = (z);
float anglef = COGL_FIXED_TO_FLOAT (angle) * G_PI / 180.0f; float anglef = (angle) * G_PI / 180.0f;
float c = cosf (anglef); float c = cosf (anglef);
float s = sinf (anglef); float s = sinf (anglef);
@ -912,21 +903,21 @@ cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
} }
void void
cogl_wrap_glOrthox (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, cogl_wrap_glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
GLfixed near, GLfixed far) GLfloat near, GLfloat far)
{ {
float matrix[16]; float matrix[16];
float xrange = COGL_FIXED_TO_FLOAT (right - left); float xrange = (right - left);
float yrange = COGL_FIXED_TO_FLOAT (top - bottom); float yrange = (top - bottom);
float zrange = COGL_FIXED_TO_FLOAT (far - near); float zrange = (far - near);
memset (matrix, 0, sizeof (matrix)); memset (matrix, 0, sizeof (matrix));
matrix[0] = 2.0f / xrange; matrix[0] = 2.0f / xrange;
matrix[5] = 2.0f / yrange; matrix[5] = 2.0f / yrange;
matrix[10] = 2.0f / zrange; matrix[10] = 2.0f / zrange;
matrix[12] = COGL_FIXED_TO_FLOAT (right + left) / xrange; matrix[12] = (right + left) / xrange;
matrix[13] = COGL_FIXED_TO_FLOAT (top + bottom) / yrange; matrix[13] = (top + bottom) / yrange;
matrix[14] = COGL_FIXED_TO_FLOAT (far + near) / zrange; matrix[14] = (far + near) / zrange;
matrix[15] = 1.0f; matrix[15] = 1.0f;
cogl_wrap_glMultMatrix (matrix); cogl_wrap_glMultMatrix (matrix);
@ -1049,8 +1040,8 @@ cogl_gles2_do_set_uniform (GLint location, CoglBoxedValue *value)
} }
} }
void static void
cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) cogl_wrap_prepare_for_draw (void)
{ {
CoglGles2WrapperProgram *program; CoglGles2WrapperProgram *program;
@ -1247,9 +1238,25 @@ cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count)
w->dirty_vertex_attrib_enables = 0; 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); 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 void
cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
GLenum internal_format) GLenum internal_format)
@ -1268,7 +1275,7 @@ cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
} }
void 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 /* This function is only used to set the texture mode once to
GL_MODULATE. The shader is hard-coded to modulate the texture so GL_MODULATE. The shader is hard-coded to modulate the texture so
@ -1479,30 +1486,17 @@ cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref)
} }
void 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, glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB, r, g, b, a);
COGL_FIXED_TO_FLOAT (r),
COGL_FIXED_TO_FLOAT (g),
COGL_FIXED_TO_FLOAT (b),
COGL_FIXED_TO_FLOAT (a));
} }
void void
cogl_wrap_glClipPlanex (GLenum plane, GLfixed *equation) cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation)
{ {
/* FIXME */ /* 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 void
cogl_wrap_glGetIntegerv (GLenum pname, GLint *params) cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
{ {
@ -1525,37 +1519,30 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
} }
void void
cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params) cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params)
{ {
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
switch (pname) switch (pname)
{ {
case GL_MODELVIEW_MATRIX: case GL_MODELVIEW_MATRIX:
cogl_gles2_float_array_to_fixed (16, w->modelview_stack memcpy (params, w->modelview_stack + w->modelview_stack_pos * 16,
+ w->modelview_stack_pos * 16, sizeof (GLfloat) * 16);
params);
break; break;
case GL_PROJECTION_MATRIX: case GL_PROJECTION_MATRIX:
cogl_gles2_float_array_to_fixed (16, w->projection_stack memcpy (params, w->projection_stack + w->projection_stack_pos * 16,
+ w->projection_stack_pos * 16, sizeof (GLfloat) * 16);
params);
break; break;
case GL_VIEWPORT: case GL_VIEWPORT:
{ glGetFloatv (GL_VIEWPORT, params);
GLfloat v[4];
glGetFloatv (GL_VIEWPORT, v);
cogl_gles2_float_array_to_fixed (4, v, params);
}
break; break;
} }
} }
void void
cogl_wrap_glFogx (GLenum pname, GLfixed param) cogl_wrap_glFogf (GLenum pname, GLfloat param)
{ {
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
@ -1567,23 +1554,23 @@ cogl_wrap_glFogx (GLenum pname, GLfixed param)
case GL_FOG_DENSITY: case GL_FOG_DENSITY:
_COGL_GLES2_CHANGE_UNIFORM (w, FOG_DENSITY, fog_density, _COGL_GLES2_CHANGE_UNIFORM (w, FOG_DENSITY, fog_density,
COGL_FIXED_TO_FLOAT (param)); (param));
break; break;
case GL_FOG_START: case GL_FOG_START:
_COGL_GLES2_CHANGE_UNIFORM (w, FOG_START, fog_start, _COGL_GLES2_CHANGE_UNIFORM (w, FOG_START, fog_start,
COGL_FIXED_TO_FLOAT (param)); (param));
break; break;
case GL_FOG_END: case GL_FOG_END:
_COGL_GLES2_CHANGE_UNIFORM (w, FOG_END, fog_end, _COGL_GLES2_CHANGE_UNIFORM (w, FOG_END, fog_end,
COGL_FIXED_TO_FLOAT (param)); (param));
break; break;
} }
} }
void void
cogl_wrap_glFogxv (GLenum pname, const GLfixed *params) cogl_wrap_glFogfv (GLenum pname, const GLfloat *params)
{ {
int i; int i;
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
@ -1591,7 +1578,7 @@ cogl_wrap_glFogxv (GLenum pname, const GLfixed *params)
if (pname == GL_FOG_COLOR) if (pname == GL_FOG_COLOR)
{ {
for (i = 0; i < 4; i++) 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; w->dirty_uniforms |= COGL_GLES2_DIRTY_FOG_COLOR;
} }

View File

@ -264,22 +264,20 @@ struct _CoglGles2WrapperShader
void cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper); void cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper);
void cogl_gles2_wrapper_deinit (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_glPushMatrix ();
void cogl_wrap_glPopMatrix (); void cogl_wrap_glPopMatrix ();
void cogl_wrap_glMatrixMode (GLenum mode); void cogl_wrap_glMatrixMode (GLenum mode);
void cogl_wrap_glLoadIdentity (); void cogl_wrap_glLoadIdentity ();
void cogl_wrap_glMultMatrixx (const GLfixed *m); void cogl_wrap_glMultMatrixf (const GLfloat *m);
void cogl_wrap_glFrustumx (GLfixed left, GLfixed right, void cogl_wrap_glFrustumf (GLfloat left, GLfloat right,
GLfixed bottom, GLfixed top, GLfloat bottom, GLfloat top,
GLfixed z_near, GLfixed z_far); GLfloat z_near, GLfloat z_far);
void cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z); void cogl_wrap_glScalef (GLfloat x, GLfloat y, GLfloat z);
void cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z); void cogl_wrap_glTranslatef (GLfloat x, GLfloat y, GLfloat z);
void cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); void cogl_wrap_glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void cogl_wrap_glOrthox (GLfixed left, GLfixed right, void cogl_wrap_glOrthof (GLfloat left, GLfloat right,
GLfixed bottom, GLfixed top, GLfloat bottom, GLfloat top,
GLfixed near, GLfixed far); GLfloat near, GLfloat far);
void cogl_wrap_glEnable (GLenum cap); void cogl_wrap_glEnable (GLenum cap);
void cogl_wrap_glDisable (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, void cogl_wrap_glNormalPointer (GLenum type, GLsizei stride,
const GLvoid *pointer); 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_glClientActiveTexture (GLenum texture);
void cogl_wrap_glActiveTexture (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_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_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_glFogf (GLenum pname, GLfloat param);
void cogl_wrap_glFogxv (GLenum pname, const GLfixed *params); void cogl_wrap_glFogfv (GLenum pname, const GLfloat *params);
void cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count); 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_wrap_glTexParameteri (GLenum target, GLenum pname, GLfloat param);
void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture, 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 /* If we're not using GL ES 2 then just use the GL functions
directly */ directly */
#define cogl_wrap_glClearColorx glClearColorx
#define cogl_wrap_glDrawArrays glDrawArrays #define cogl_wrap_glDrawArrays glDrawArrays
#define cogl_wrap_glDrawElements glDrawElements
#define cogl_wrap_glPushMatrix glPushMatrix #define cogl_wrap_glPushMatrix glPushMatrix
#define cogl_wrap_glPopMatrix glPopMatrix #define cogl_wrap_glPopMatrix glPopMatrix
#define cogl_wrap_glMatrixMode glMatrixMode #define cogl_wrap_glMatrixMode glMatrixMode
#define cogl_wrap_glLoadIdentity glLoadIdentity #define cogl_wrap_glLoadIdentity glLoadIdentity
#define cogl_wrap_glMultMatrixx glMultMatrixx #define cogl_wrap_glMultMatrixf glMultMatrixf
#define cogl_wrap_glFrustumx glFrustumx #define cogl_wrap_glFrustumf glFrustumf
#define cogl_wrap_glScalex glScalex #define cogl_wrap_glScalef glScalef
#define cogl_wrap_glTranslatex glTranslatex #define cogl_wrap_glTranslatef glTranslatef
#define cogl_wrap_glRotatex glRotatex #define cogl_wrap_glRotatef glRotatef
#define cogl_wrap_glOrthox glOrthox #define cogl_wrap_glOrthof glOrthof
#define cogl_wrap_glEnable glEnable #define cogl_wrap_glEnable glEnable
#define cogl_wrap_glDisable glDisable #define cogl_wrap_glDisable glDisable
#define cogl_wrap_glTexCoordPointer glTexCoordPointer #define cogl_wrap_glTexCoordPointer glTexCoordPointer
#define cogl_wrap_glVertexPointer glVertexPointer #define cogl_wrap_glVertexPointer glVertexPointer
#define cogl_wrap_glColorPointer glColorPointer #define cogl_wrap_glColorPointer glColorPointer
#define cogl_wrap_glNormalPointer glNormalPointer #define cogl_wrap_glNormalPointer glNormalPointer
#define cogl_wrap_glTexEnvx glTexEnvx #define cogl_wrap_glTexEnvf glTexEnvf
#define cogl_wrap_glActiveTexture glActiveTexture #define cogl_wrap_glActiveTexture glActiveTexture
#define cogl_wrap_glEnableClientState glEnableClientState #define cogl_wrap_glEnableClientState glEnableClientState
#define cogl_wrap_glDisableClientState glDisableClientState #define cogl_wrap_glDisableClientState glDisableClientState
#define cogl_wrap_glAlphaFunc glAlphaFunc #define cogl_wrap_glAlphaFunc glAlphaFunc
#define cogl_wrap_glColor4x glColor4x #define cogl_wrap_glColor4f glColor4f
#define cogl_wrap_glClipPlanex glClipPlanex #define cogl_wrap_glClipPlanef glClipPlanef
#define cogl_wrap_glGetIntegerv glGetIntegerv #define cogl_wrap_glGetIntegerv glGetIntegerv
#define cogl_wrap_glGetFixedv glGetFixedv #define cogl_wrap_glGetFloatv glGetFloatv
#define cogl_wrap_glFogx glFogx #define cogl_wrap_glFogf glFogf
#define cogl_wrap_glFogxv glFogxv #define cogl_wrap_glFogfv glFogfv
#define cogl_wrap_glTexParameteri glTexParameteri #define cogl_wrap_glTexParameteri glTexParameteri
/* The extra third parameter of the bind texture wrapper isn't needed /* The extra third parameter of the bind texture wrapper isn't needed

View File

@ -34,63 +34,35 @@
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
#include <math.h>
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 #define _COGL_MAX_BEZ_RECURSE_DEPTH 16
void void
_cogl_rectangle (gint x, _cogl_rectangle (float x,
gint y, float y,
guint width, float width,
guint height) float height)
{ {
/* 32-bit integers are not supported as coord types GLfloat rect_verts[8] = {
in GLES . Fixed type has got 16 bits left of the (GLfloat) x, (GLfloat) y,
point which is equal to short anyway. */ (GLfloat) (x + width), (GLfloat) y,
(GLfloat) x, (GLfloat) (y + height),
GLshort rect_verts[8] = { (GLfloat) (x + width), (GLfloat) (y + height)
(GLshort) x, (GLshort) y,
(GLshort) (x + width), (GLshort) y,
(GLshort) x, (GLshort) (y + height),
(GLshort) (x + width), (GLshort) (y + height)
}; };
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_enable (COGL_ENABLE_VERTEX_ARRAY cogl_enable (COGL_ENABLE_VERTEX_ARRAY
| (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0)); | (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) ); 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 void
_cogl_path_add_node (gboolean new_sub_path, _cogl_path_add_node (gboolean new_sub_path,
CoglFixed x, float x,
CoglFixed y) float y)
{ {
CoglPathNode new_node; CoglPathNode new_node;
@ -147,19 +119,17 @@ _cogl_path_stroke_nodes ()
} }
static void static void
_cogl_path_get_bounds (CoglFixedVec2 nodes_min, _cogl_path_get_bounds (floatVec2 nodes_min,
CoglFixedVec2 nodes_max, floatVec2 nodes_max,
gint *bounds_x, float *bounds_x,
gint *bounds_y, float *bounds_y,
guint *bounds_w, float *bounds_w,
guint *bounds_h) float *bounds_h)
{ {
*bounds_x = COGL_FIXED_FLOOR (nodes_min.x); *bounds_x = nodes_min.x;
*bounds_y = COGL_FIXED_FLOOR (nodes_min.y); *bounds_y = nodes_min.y;
*bounds_w = COGL_FIXED_CEIL (nodes_max.x *bounds_w = nodes_max.x - *bounds_x;
- COGL_FIXED_FROM_INT (*bounds_x)); *bounds_h = nodes_max.y - *bounds_y;
*bounds_h = COGL_FIXED_CEIL (nodes_max.y
- COGL_FIXED_FROM_INT (*bounds_y));
} }
static gint compare_ints (gconstpointer a, static gint compare_ints (gconstpointer a,
@ -169,18 +139,18 @@ static gint compare_ints (gconstpointer a,
} }
void void
_cogl_add_path_to_stencil_buffer (CoglFixedVec2 nodes_min, _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
CoglFixedVec2 nodes_max, floatVec2 nodes_max,
guint path_size, guint path_size,
CoglPathNode *path, CoglPathNode *path,
gboolean merge) gboolean merge)
{ {
guint path_start = 0; guint path_start = 0;
guint sub_path_num = 0; guint sub_path_num = 0;
gint bounds_x; float bounds_x;
gint bounds_y; float bounds_y;
guint bounds_w; float bounds_w;
guint bounds_h; float bounds_h;
_cogl_path_get_bounds (nodes_min, nodes_max, _cogl_path_get_bounds (nodes_min, nodes_max,
&bounds_x, &bounds_y, &bounds_w, &bounds_h); &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_glMatrixMode (GL_PROJECTION) );
GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glPushMatrix () );
GE( cogl_wrap_glLoadIdentity () ); GE( cogl_wrap_glLoadIdentity () );
cogl_rectanglex (-COGL_FIXED_1, -COGL_FIXED_1, cogl_rectangle (-1.0, -1.0, 2, 2);
COGL_FIXED_FROM_INT (2), cogl_rectangle (-1.0, -1.0, 2, 2);
COGL_FIXED_FROM_INT (2));
cogl_rectanglex (-COGL_FIXED_1, -COGL_FIXED_1,
COGL_FIXED_FROM_INT (2),
COGL_FIXED_FROM_INT (2));
GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glPopMatrix () );
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glPopMatrix () );
@ -292,14 +258,14 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
for (i=0; i < bounds_h; i++) for (i=0; i < bounds_h; i++)
scanlines[i]=NULL; scanlines[i]=NULL;
first_x = prev_x = COGL_FIXED_TO_INT (path->x); first_x = prev_x = (path->x);
first_y = prev_y = COGL_FIXED_TO_INT (path->y); first_y = prev_y = (path->y);
/* create scanline intersection list */ /* create scanline intersection list */
for (i=1; i < path_size; i++) for (i=1; i < path_size; i++)
{ {
gint dest_x = COGL_FIXED_TO_INT (path[i].x); gint dest_x = (path[i].x);
gint dest_y = COGL_FIXED_TO_INT (path[i].y); gint dest_y = (path[i].y);
gint ydir; gint ydir;
gint dx; gint dx;
gint dy; gint dy;
@ -362,7 +328,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
{ {
gint spans = 0; gint spans = 0;
gint span_no; gint span_no;
GLfixed *coords; GLfloat *coords;
/* count number of spans */ /* count number of spans */
for (i=0; i < bounds_h; i++) for (i=0; i < bounds_h; i++)
@ -380,7 +346,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
iter = next->next; iter = next->next;
} }
} }
coords = g_malloc0 (spans * sizeof (GLfixed) * 3 * 2 * 2); coords = g_malloc0 (spans * sizeof (GLfloat) * 3 * 2 * 2);
span_no = 0; span_no = 0;
/* build list of triangles */ /* build list of triangles */
@ -390,15 +356,15 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
while (iter) while (iter)
{ {
GSList *next = iter->next; GSList *next = iter->next;
GLfixed x0, x1; GLfloat x0, x1;
GLfixed y0, y1; GLfloat y0, y1;
if (!next) if (!next)
break; break;
x0 = COGL_FIXED_FROM_INT (GPOINTER_TO_INT (iter->data)); x0 = (float)(GPOINTER_TO_INT (iter->data));
x1 = COGL_FIXED_FROM_INT (GPOINTER_TO_INT (next->data)); x1 = (float)(GPOINTER_TO_INT (next->data));
y0 = COGL_FIXED_FROM_INT (bounds_y + i); y0 = (float)(bounds_y + i);
y1 = COGL_FIXED_FROM_INT (bounds_y + i + 1) + 2048; y1 = (float)(bounds_y + i + 1) + 2048;
/* render scanlines 1.0625 high to avoid gaps when /* render scanlines 1.0625 high to avoid gaps when
transformed */ transformed */
@ -435,10 +401,10 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
void void
_cogl_path_fill_nodes () _cogl_path_fill_nodes ()
{ {
gint bounds_x; float bounds_x;
gint bounds_y; float bounds_y;
guint bounds_w; float bounds_w;
guint bounds_h; float bounds_h;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);

View File

@ -40,12 +40,14 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#if HAVE_COGL_GLES2 #if HAVE_COGL_GLES2
#define glVertexPointer cogl_wrap_glVertexPointer #define glVertexPointer cogl_wrap_glVertexPointer
#define glTexCoordPointer cogl_wrap_glTexCoordPointer #define glTexCoordPointer cogl_wrap_glTexCoordPointer
#define glColorPointer cogl_wrap_glColorPointer #define glColorPointer cogl_wrap_glColorPointer
#define glDrawArrays cogl_wrap_glDrawArrays #define glDrawArrays cogl_wrap_glDrawArrays
#define glDrawElements cogl_wrap_glDrawElements
#define glTexParameteri cogl_wrap_glTexParameteri #define glTexParameteri cogl_wrap_glTexParameteri
#define glClientActiveTexture cogl_wrap_glClientActiveTexture #define glClientActiveTexture cogl_wrap_glClientActiveTexture
#define glActiveTexture cogl_wrap_glActiveTexture #define glActiveTexture cogl_wrap_glActiveTexture
@ -71,15 +73,15 @@ struct _CoglSpanIter
gint index; gint index;
GArray *array; GArray *array;
CoglTexSliceSpan *span; CoglTexSliceSpan *span;
CoglFixed pos; float pos;
CoglFixed next_pos; float next_pos;
CoglFixed origin; float origin;
CoglFixed cover_start; float cover_start;
CoglFixed cover_end; float cover_end;
CoglFixed intersect_start; float intersect_start;
CoglFixed intersect_end; float intersect_end;
CoglFixed intersect_start_local; float intersect_start_local;
CoglFixed intersect_end_local; float intersect_end_local;
gboolean intersects; gboolean intersects;
}; };
@ -118,7 +120,7 @@ _cogl_span_iter_update (CoglSpanIter *iter)
/* Offset next position by span size */ /* Offset next position by span size */
iter->next_pos = iter->pos + 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 */ /* Check if span intersects the area to cover */
if (iter->next_pos <= iter->cover_start || if (iter->next_pos <= iter->cover_start ||
@ -147,9 +149,9 @@ _cogl_span_iter_update (CoglSpanIter *iter)
static void static void
_cogl_span_iter_begin (CoglSpanIter *iter, _cogl_span_iter_begin (CoglSpanIter *iter,
GArray *array, GArray *array,
CoglFixed origin, float origin,
CoglFixed cover_start, float cover_start,
CoglFixed cover_end) float cover_end)
{ {
/* Copy info */ /* Copy info */
iter->index = 0; iter->index = 0;
@ -400,10 +402,10 @@ _cogl_texture_draw_and_read (CoglTexture *tex,
GLint *viewport) GLint *viewport)
{ {
gint bpp; gint bpp;
CoglFixed rx1, ry1; float rx1, ry1;
CoglFixed rx2, ry2; float rx2, ry2;
CoglFixed tx1, ty1; float tx1, ty1;
CoglFixed tx2, ty2; float tx2, ty2;
int bw, bh; int bw, bh;
CoglBitmap rect_bmp; CoglBitmap rect_bmp;
CoglHandle handle; CoglHandle handle;
@ -424,9 +426,9 @@ _cogl_texture_draw_and_read (CoglTexture *tex,
/* Draw the texture image */ /* Draw the texture image */
cogl_texture_rectangle (handle, cogl_texture_rectangle (handle,
0, 0, 0, 0,
COGL_FIXED_FROM_INT (tex->bitmap.width), (float)(tex->bitmap.width),
COGL_FIXED_FROM_INT (tex->bitmap.height), (float)(tex->bitmap.height),
0, 0, COGL_FIXED_1, COGL_FIXED_1); 0, 0, 1.0, 1.0);
/* Read into target bitmap */ /* Read into target bitmap */
prep_for_gl_pixels_download (tex->bitmap.rowstride); prep_for_gl_pixels_download (tex->bitmap.rowstride);
@ -441,7 +443,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex,
ry1 = 0; ry2 = 0; ry1 = 0; ry2 = 0;
ty1 = 0; ty2 = 0; ty1 = 0; ty2 = 0;
#define CFIX COGL_FIXED_FROM_INT #define CFIX (float)
/* Walk Y axis until whole bitmap height consumed */ /* Walk Y axis until whole bitmap height consumed */
for (bh = tex->bitmap.height; bh > 0; bh -= viewport[3]) 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 */ /* Normalized texture Y coords */
ty1 = ty2; ty1 = ty2;
ty2 = COGL_FIXED_DIV (CFIX (ry2), CFIX (tex->bitmap.height)); ty2 = (CFIX (ry2) / CFIX (tex->bitmap.height));
rx1 = 0; rx2 = 0; rx1 = 0; rx2 = 0;
tx1 = 0; tx2 = 0; tx1 = 0; tx2 = 0;
@ -466,7 +468,7 @@ _cogl_texture_draw_and_read (CoglTexture *tex,
/* Normalized texture X coords */ /* Normalized texture X coords */
tx1 = tx2; 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 /* Clear buffer with transparent black, draw with white
for direct copy to framebuffer */ for direct copy to framebuffer */
@ -546,10 +548,10 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glPushMatrix () );
GE( cogl_wrap_glLoadIdentity () ); GE( cogl_wrap_glLoadIdentity () );
GE( cogl_wrap_glOrthox (0, COGL_FIXED_FROM_INT (viewport[2]), GE( cogl_wrap_glOrthof (0, (float)(viewport[2]),
0, COGL_FIXED_FROM_INT (viewport[3]), 0, (float)(viewport[3]),
COGL_FIXED_FROM_INT (0), (float)(0),
COGL_FIXED_FROM_INT (100)) ); (float)(100)) );
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glPushMatrix () );
@ -664,8 +666,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
/* Iterate vertical spans */ /* Iterate vertical spans */
for (source_y = src_y, for (source_y = src_y,
_cogl_span_iter_begin (&y_iter, tex->slice_y_spans, _cogl_span_iter_begin (&y_iter, tex->slice_y_spans,
0, COGL_FIXED_FROM_INT (dst_y), 0, (float)(dst_y),
COGL_FIXED_FROM_INT (dst_y + height)); (float)(dst_y + height));
!_cogl_span_iter_end (&y_iter); !_cogl_span_iter_end (&y_iter);
@ -685,8 +687,8 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
/* Iterate horizontal spans */ /* Iterate horizontal spans */
for (source_x = src_x, for (source_x = src_x,
_cogl_span_iter_begin (&x_iter, tex->slice_x_spans, _cogl_span_iter_begin (&x_iter, tex->slice_x_spans,
0, COGL_FIXED_FROM_INT (dst_x), 0, (float)(dst_x),
COGL_FIXED_FROM_INT (dst_x + width)); (float)(dst_x + width));
!_cogl_span_iter_end (&x_iter); !_cogl_span_iter_end (&x_iter);
@ -704,15 +706,15 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
x_iter.index); x_iter.index);
/* Pick intersection width and height */ /* 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); x_iter.intersect_start);
inter_h = COGL_FIXED_TO_INT (y_iter.intersect_end - inter_h = (y_iter.intersect_end -
y_iter.intersect_start); y_iter.intersect_start);
/* Localize intersection top-left corner to slice*/ /* 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); x_iter.pos);
local_y = COGL_FIXED_TO_INT (y_iter.intersect_start - local_y = (y_iter.intersect_start -
y_iter.pos); y_iter.pos);
/* Pick slice GL handle */ /* Pick slice GL handle */
@ -770,7 +772,7 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
guint wx, wy; guint wx, wy;
src = source_bmp->data src = source_bmp->data
+ (src_y + COGL_FIXED_TO_INT (y_iter.intersect_start) + (src_y + ((int)y_iter.intersect_start)
- dst_y) - dst_y)
* source_bmp->rowstride * source_bmp->rowstride
+ (src_x + x_span->start + x_span->size - x_span->waste + (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; guint copy_width;
src = source_bmp->data src = source_bmp->data
+ (src_x + COGL_FIXED_TO_INT (x_iter.intersect_start) + (src_x + ((int)x_iter.intersect_start)
- dst_x) - dst_x)
* bpp * bpp
+ (src_y + y_span->start + y_span->size - y_span->waste + (src_y + y_span->start + y_span->size - y_span->waste
@ -1314,11 +1316,11 @@ _cogl_texture_free (CoglTexture *tex)
} }
CoglHandle CoglHandle
cogl_texture_new_with_size (guint width, cogl_texture_new_with_size (guint width,
guint height, guint height,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat internal_format) CoglPixelFormat internal_format)
{ {
CoglTexture *tex; CoglTexture *tex;
gint bpp; gint bpp;
@ -1339,7 +1341,7 @@ cogl_texture_new_with_size (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex); COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = auto_mipmap; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0);
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1374,14 +1376,14 @@ cogl_texture_new_with_size (guint width,
} }
CoglHandle CoglHandle
cogl_texture_new_from_data (guint width, cogl_texture_new_from_data (guint width,
guint height, guint height,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat format, CoglPixelFormat format,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
guint rowstride, guint rowstride,
const guchar *data) const guchar *data)
{ {
CoglTexture *tex; CoglTexture *tex;
gint bpp; gint bpp;
@ -1403,7 +1405,7 @@ cogl_texture_new_from_data (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex); COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE; tex->is_foreign = FALSE;
tex->auto_mipmap = auto_mipmap; tex->auto_mipmap = ((flags & COGL_TEXTURE_AUTO_MIPMAP) != 0);
tex->bitmap.width = width; tex->bitmap.width = width;
tex->bitmap.height = height; tex->bitmap.height = height;
@ -1449,30 +1451,13 @@ cogl_texture_new_from_data (guint width,
} }
CoglHandle CoglHandle
cogl_texture_new_from_file (const gchar *filename, cogl_texture_new_from_bitmap (CoglBitmap *bmp,
gint max_waste, gint max_waste,
gboolean auto_mipmap, CoglTextureFlags flags,
CoglPixelFormat internal_format, CoglPixelFormat internal_format)
GError **error)
{ {
CoglBitmap bmp;
CoglTexture *tex; 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 */ /* Create new texture and fill with loaded data */
tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture)); tex = (CoglTexture*) g_malloc ( sizeof (CoglTexture));
@ -1480,10 +1465,11 @@ cogl_texture_new_from_file (const gchar *filename,
COGL_HANDLE_DEBUG_NEW (texture, tex); COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE; 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; tex->bitmap_owner = TRUE;
bmp->data = NULL;
tex->slice_x_spans = NULL; tex->slice_x_spans = NULL;
tex->slice_y_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); 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 CoglHandle
cogl_texture_new_from_foreign (GLuint gl_handle, cogl_texture_new_from_foreign (GLuint gl_handle,
GLenum gl_target, GLenum gl_target,
@ -2097,7 +2107,9 @@ _cogl_texture_flush_vertices (void)
GE( glTexCoordPointer (2, GL_FLOAT, GE( glTexCoordPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->t ) ); 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, GE( glDrawElements (GL_TRIANGLES,
needed_indices, needed_indices,
GL_UNSIGNED_SHORT, GL_UNSIGNED_SHORT,
@ -2140,24 +2152,24 @@ _cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1,
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2) float ty2)
{ {
CoglSpanIter iter_x , iter_y; CoglSpanIter iter_x , iter_y;
CoglFixed tw , th; float tw , th;
CoglFixed tqx , tqy; float tqx , tqy;
CoglFixed first_tx , first_ty; float first_tx , first_ty;
CoglFixed first_qx , first_qy; float first_qx , first_qy;
CoglFixed slice_tx1 , slice_ty1; float slice_tx1 , slice_ty1;
CoglFixed slice_tx2 , slice_ty2; float slice_tx2 , slice_ty2;
CoglFixed slice_qx1 , slice_qy1; float slice_qx1 , slice_qy1;
CoglFixed slice_qx2 , slice_qy2; float slice_qx2 , slice_qy2;
GLuint gl_handle; GLuint gl_handle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -2172,7 +2184,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
slices */ slices */
if (tx2 < tx1) if (tx2 < tx1)
{ {
CoglFixed temp = x1; float temp = x1;
x1 = x2; x1 = x2;
x2 = temp; x2 = temp;
temp = tx1; temp = tx1;
@ -2181,7 +2193,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
} }
if (ty2 < ty1) if (ty2 < ty1)
{ {
CoglFixed temp = y1; float temp = y1;
y1 = y2; y1 = y2;
y2 = temp; y2 = temp;
temp = ty1; temp = ty1;
@ -2190,27 +2202,27 @@ _cogl_texture_quad_sw (CoglTexture *tex,
} }
/* Scale ratio from texture to quad widths */ /* Scale ratio from texture to quad widths */
tw = COGL_FIXED_FROM_INT (tex->bitmap.width); tw = (float)(tex->bitmap.width);
th = COGL_FIXED_FROM_INT (tex->bitmap.height); th = (float)(tex->bitmap.height);
tqx = COGL_FIXED_DIV (x2 - x1, COGL_FIXED_MUL (tw, (tx2 - tx1))); tqx = (x2 - x1) / (tw * (tx2 - tx1));
tqy = COGL_FIXED_DIV (y2 - y1, COGL_FIXED_MUL (th, (ty2 - ty1))); tqy = (y2 - y1) / (th * (ty2 - ty1));
/* Integral texture coordinate for first tile */ /* Integral texture coordinate for first tile */
first_tx = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (tx1)); first_tx = (float)(floorf (tx1));
first_ty = COGL_FIXED_FROM_INT (COGL_FIXED_FLOOR (ty1)); first_ty = (float)(floorf (ty1));
/* Denormalize texture coordinates */ /* Denormalize texture coordinates */
first_tx = COGL_FIXED_MUL (first_tx, tw); first_tx = (first_tx * tw);
first_ty = COGL_FIXED_MUL (first_ty, th); first_ty = (first_ty * th);
tx1 = COGL_FIXED_MUL (tx1, tw); tx1 = (tx1 * tw);
ty1 = COGL_FIXED_MUL (ty1, th); ty1 = (ty1 * th);
tx2 = COGL_FIXED_MUL (tx2, tw); tx2 = (tx2 * tw);
ty2 = COGL_FIXED_MUL (ty2, th); ty2 = (ty2 * th);
/* Quad coordinate of the first tile */ /* Quad coordinate of the first tile */
first_qx = x1 - COGL_FIXED_MUL (tx1 - first_tx, tqx); first_qx = x1 - (tx1 - first_tx) * tqx;
first_qy = y1 - COGL_FIXED_MUL (ty1 - first_ty, tqy); first_qy = y1 - (ty1 - first_ty) * tqy;
/* Iterate until whole quad height covered */ /* Iterate until whole quad height covered */
@ -2223,11 +2235,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
if (!iter_y.intersects) continue; if (!iter_y.intersects) continue;
/* Span-quad intersection in quad coordinates */ /* Span-quad intersection in quad coordinates */
slice_qy1 = first_qy + slice_qy1 = first_qy + (iter_y.intersect_start - first_ty) * tqy;
COGL_FIXED_MUL (iter_y.intersect_start - first_ty, tqy);
slice_qy2 = first_qy + slice_qy2 = first_qy + (iter_y.intersect_end - first_ty) * tqy;
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_ty1 = iter_y.intersect_start - iter_y.pos; slice_ty1 = iter_y.intersect_start - iter_y.pos;
@ -2248,11 +2258,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
if (!iter_x.intersects) continue; if (!iter_x.intersects) continue;
/* Span-quad intersection in quad coordinates */ /* Span-quad intersection in quad coordinates */
slice_qx1 = first_qx + slice_qx1 = first_qx + (iter_x.intersect_start - first_tx) * tqx;
COGL_FIXED_MUL (iter_x.intersect_start - first_tx, tqx);
slice_qx2 = first_qx + slice_qx2 = first_qx + (iter_x.intersect_end - first_tx) * tqx;
COGL_FIXED_MUL (iter_x.intersect_end - first_tx, tqx);
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_tx1 = iter_x.intersect_start - iter_x.pos; slice_tx1 = iter_x.intersect_start - iter_x.pos;
@ -2265,14 +2273,14 @@ _cogl_texture_quad_sw (CoglTexture *tex,
#if COGL_DEBUG #if COGL_DEBUG
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); printf("qx1: %f\n", (slice_qx1));
printf("qy1: %f\n", COGL_FIXED_TO_FLOAT (slice_qy1)); printf("qy1: %f\n", (slice_qy1));
printf("qx2: %f\n", COGL_FIXED_TO_FLOAT (slice_qx2)); printf("qx2: %f\n", (slice_qx2));
printf("qy2: %f\n", COGL_FIXED_TO_FLOAT (slice_qy2)); printf("qy2: %f\n", (slice_qy2));
printf("tx1: %f\n", COGL_FIXED_TO_FLOAT (slice_tx1)); printf("tx1: %f\n", (slice_tx1));
printf("ty1: %f\n", COGL_FIXED_TO_FLOAT (slice_ty1)); printf("ty1: %f\n", (slice_ty1));
printf("tx2: %f\n", COGL_FIXED_TO_FLOAT (slice_tx2)); printf("tx2: %f\n", (slice_tx2));
printf("ty2: %f\n", COGL_FIXED_TO_FLOAT (slice_ty2)); printf("ty2: %f\n", (slice_ty2));
#endif #endif
/* Pick and bind opengl texture object */ /* Pick and bind opengl texture object */
@ -2287,29 +2295,30 @@ _cogl_texture_quad_sw (CoglTexture *tex,
_cogl_texture_flush_vertices (); _cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target; ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle; ctx->texture_current = gl_handle;
ctx->texture_format = tex->gl_intformat;
_cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1), _cogl_texture_add_quad_vertices ( (slice_qx1),
COGL_FIXED_TO_FLOAT (slice_qy1), (slice_qy1),
COGL_FIXED_TO_FLOAT (slice_qx2), (slice_qx2),
COGL_FIXED_TO_FLOAT (slice_qy2), (slice_qy2),
COGL_FIXED_TO_FLOAT (slice_tx1), (slice_tx1),
COGL_FIXED_TO_FLOAT (slice_ty1), (slice_ty1),
COGL_FIXED_TO_FLOAT (slice_tx2), (slice_tx2),
COGL_FIXED_TO_FLOAT (slice_ty2)); (slice_ty2));
} }
} }
} }
static void static void
_cogl_texture_quad_hw (CoglTexture *tex, _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2) float ty2)
{ {
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
@ -2331,6 +2340,7 @@ _cogl_texture_quad_hw (CoglTexture *tex,
_cogl_texture_flush_vertices (); _cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target; ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle; ctx->texture_current = gl_handle;
ctx->texture_format = tex->gl_intformat;
/* Don't include the waste in the texture coordinates */ /* Don't include the waste in the texture coordinates */
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); 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; ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
ty2 = ty2 * (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_texture_add_quad_vertices ( (x1),
COGL_FIXED_TO_FLOAT (y1), (y1),
COGL_FIXED_TO_FLOAT (x2), (x2),
COGL_FIXED_TO_FLOAT (y2), (y2),
COGL_FIXED_TO_FLOAT (tx1), (tx1),
COGL_FIXED_TO_FLOAT (ty1), (ty1),
COGL_FIXED_TO_FLOAT (tx2), (tx2),
COGL_FIXED_TO_FLOAT (ty2)); (ty2));
} }
void void
cogl_texture_multiple_rectangles (CoglHandle handle, cogl_texture_multiple_rectangles (CoglHandle handle,
const CoglFixed *verts, const float *verts,
guint n_rects) guint n_rects)
{ {
CoglTexture *tex; CoglTexture *tex;
@ -2401,10 +2411,10 @@ cogl_texture_multiple_rectangles (CoglHandle handle,
if (tex->slice_gl_handles->len == 1 if (tex->slice_gl_handles->len == 1
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D) && tex->gl_target == GL_TEXTURE_2D)
|| (verts[4] >= 0 && verts[4] <= COGL_FIXED_1 || (verts[4] >= 0 && verts[4] <= 1.0
&& verts[6] >= 0 && verts[6] <= COGL_FIXED_1 && verts[6] >= 0 && verts[6] <= 1.0
&& verts[5] >= 0 && verts[5] <= COGL_FIXED_1 && verts[5] >= 0 && verts[5] <= 1.0
&& verts[7] >= 0 && verts[7] <= COGL_FIXED_1))) && verts[7] >= 0 && verts[7] <= 1.0)))
_cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3], _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]); verts[4],verts[5], verts[6],verts[7]);
else else
@ -2420,16 +2430,16 @@ cogl_texture_multiple_rectangles (CoglHandle handle,
void void
cogl_texture_rectangle (CoglHandle handle, cogl_texture_rectangle (CoglHandle handle,
CoglFixed x1, float x1,
CoglFixed y1, float y1,
CoglFixed x2, float x2,
CoglFixed y2, float y2,
CoglFixed tx1, float tx1,
CoglFixed ty1, float ty1,
CoglFixed tx2, float tx2,
CoglFixed ty2) float ty2)
{ {
CoglFixed verts[8]; float verts[8];
verts[0] = x1; verts[0] = x1;
verts[1] = y1; verts[1] = y1;
@ -2531,7 +2541,7 @@ cogl_texture_polygon (CoglHandle handle,
OpenGL */ OpenGL */
for (i = 0; i < n_vertices; i++, p++) 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[0] = CFX_F(vertices[i].x);
p->v[1] = CFX_F(vertices[i].y); p->v[1] = CFX_F(vertices[i].y);

View File

@ -37,6 +37,7 @@
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-gles2-wrapper.h" #include "cogl-gles2-wrapper.h"
#include <math.h>
/* GL error to string conversion */ /* GL error to string conversion */
#if COGL_DEBUG #if COGL_DEBUG
@ -92,10 +93,10 @@ cogl_paint_init (const CoglColor *color)
fprintf(stderr, "\n ============== Paint Start ================ \n"); fprintf(stderr, "\n ============== Paint Start ================ \n");
#endif #endif
cogl_wrap_glClearColorx (cogl_color_get_red (color), glClearColor (cogl_color_get_red (color),
cogl_color_get_green (color), cogl_color_get_green (color),
cogl_color_get_blue (color), cogl_color_get_blue (color),
0); 0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
cogl_wrap_glDisable (GL_LIGHTING); cogl_wrap_glDisable (GL_LIGHTING);
@ -116,41 +117,21 @@ cogl_pop_matrix (void)
} }
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 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 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), GE( cogl_wrap_glRotatef (angle, x, y, z) );
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)) );
} }
static inline gboolean static inline gboolean
@ -315,7 +296,7 @@ cogl_set_source_color (const CoglColor *color)
#else #else
/* conversion can cause issues with picking on some gles implementations */ /* 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_green (color),
cogl_color_get_blue (color), cogl_color_get_blue (color),
cogl_color_get_alpha (color)) ); cogl_color_get_alpha (color)) );
@ -326,22 +307,22 @@ cogl_set_source_color (const CoglColor *color)
} }
static void static void
apply_matrix (const CoglFixed *matrix, CoglFixed *vertex) apply_matrix (const float *matrix, float *vertex)
{ {
int x, y; int x, y;
CoglFixed vertex_out[4] = { 0 }; float vertex_out[4] = { 0 };
for (y = 0; y < 4; y++) for (y = 0; y < 4; y++)
for (x = 0; x < 4; x++) 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)); memcpy (vertex, vertex_out, sizeof (vertex_out));
} }
static void static void
project_vertex (CoglFixed *modelview, project_vertex (float *modelview,
CoglFixed *project, float *project,
CoglFixed *vertex) float *vertex)
{ {
int i; int i;
@ -351,62 +332,61 @@ project_vertex (CoglFixed *modelview,
apply_matrix (project, vertex); apply_matrix (project, vertex);
/* Convert from homogenized coordinates */ /* Convert from homogenized coordinates */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
vertex[i] = cogl_fixed_div (vertex[i], vertex[3]); vertex[i] = (vertex[i] / vertex[3]);
} }
static void static void
set_clip_plane (GLint plane_num, set_clip_plane (GLint plane_num,
const CoglFixed *vertex_a, const float *vertex_a,
const CoglFixed *vertex_b) const float *vertex_b)
{ {
GLfixed plane[4]; GLfloat plane[4];
GLfixed angle; GLfloat angle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Calculate the angle between the axes and the line crossing the /* Calculate the angle between the axes and the line crossing the
two points */ two points */
angle = cogl_fixed_mul (cogl_fixed_atan2 (vertex_b[1] - vertex_a[1], angle = atan2f (vertex_b[1] - vertex_a[1],
vertex_b[0] - vertex_a[0]), vertex_b[0] - vertex_a[0]) * (180.0/G_PI);
COGL_RADIANS_TO_DEGREES);
GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glPushMatrix () );
/* Load the identity matrix and multiply by the reverse of the /* Load the identity matrix and multiply by the reverse of the
projection matrix so we can specify the plane in screen projection matrix so we can specify the plane in screen
coordinates */ coordinates */
GE( cogl_wrap_glLoadIdentity () ); GE( cogl_wrap_glLoadIdentity () );
GE( cogl_wrap_glMultMatrixx ((GLfixed *) ctx->inverse_projection) ); GE( cogl_wrap_glMultMatrixf ((GLfloat *) ctx->inverse_projection) );
/* Rotate about point a */ /* 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 /* Rotate the plane by the calculated angle so that it will connect
the two points */ the two points */
GE( cogl_wrap_glRotatex (angle, 0.0f, 0.0f, 1.0f) ); GE( cogl_wrap_glRotatef (angle, 0.0f, 0.0f, 1.0f) );
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]) );
plane[0] = 0; plane[0] = 0;
plane[1] = -COGL_FIXED_1; plane[1] = -1.0;
plane[2] = 0; plane[2] = 0;
plane[3] = vertex_a[1]; plane[3] = vertex_a[1];
GE( cogl_wrap_glClipPlanex (plane_num, plane) ); GE( cogl_wrap_glClipPlanef (plane_num, plane) );
GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glPopMatrix () );
} }
void void
_cogl_set_clip_planes (CoglFixed x_offset, _cogl_set_clip_planes (float x_offset,
CoglFixed y_offset, float y_offset,
CoglFixed width, float width,
CoglFixed height) float height)
{ {
GLfixed modelview[16], projection[16]; GLfloat modelview[16], projection[16];
CoglFixed vertex_tl[4] = { x_offset, y_offset, 0, COGL_FIXED_1 }; float vertex_tl[4] = { x_offset, y_offset, 0, 1.0 };
CoglFixed vertex_tr[4] = { x_offset + width, y_offset, 0, COGL_FIXED_1 }; float vertex_tr[4] = { x_offset + width, y_offset, 0, 1.0 };
CoglFixed vertex_bl[4] = { x_offset, y_offset + height, 0, COGL_FIXED_1 }; float vertex_bl[4] = { x_offset, y_offset + height, 0, 1.0 };
CoglFixed vertex_br[4] = { x_offset + width, y_offset + height, float vertex_br[4] = { x_offset + width, y_offset + height,
0, COGL_FIXED_1 }; 0, 1.0 };
GE( cogl_wrap_glGetFixedv (GL_MODELVIEW_MATRIX, modelview) ); GE( cogl_wrap_glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
GE( cogl_wrap_glGetFixedv (GL_PROJECTION_MATRIX, projection) ); GE( cogl_wrap_glGetFloatv (GL_PROJECTION_MATRIX, projection) );
project_vertex (modelview, projection, vertex_tl); project_vertex (modelview, projection, vertex_tl);
project_vertex (modelview, projection, vertex_tr); 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) if ((vertex_tl[0] < vertex_tr[0] ? 1 : 0)
!= (vertex_bl[1] < vertex_tl[1] ? 1 : 0)) != (vertex_bl[1] < vertex_tl[1] ? 1 : 0))
{ {
CoglFixed temp[4]; float temp[4];
memcpy (temp, vertex_tl, sizeof (temp)); memcpy (temp, vertex_tl, sizeof (temp));
memcpy (vertex_tl, vertex_tr, sizeof (temp)); memcpy (vertex_tl, vertex_tr, sizeof (temp));
memcpy (vertex_tr, temp, sizeof (temp)); memcpy (vertex_tr, temp, sizeof (temp));
@ -437,10 +417,10 @@ _cogl_set_clip_planes (CoglFixed x_offset,
} }
void void
_cogl_add_stencil_clip (CoglFixed x_offset, _cogl_add_stencil_clip (float x_offset,
CoglFixed y_offset, float y_offset,
CoglFixed width, float width,
CoglFixed height, float height,
gboolean first) gboolean first)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -457,7 +437,7 @@ _cogl_add_stencil_clip (CoglFixed x_offset,
GE( glStencilFunc (GL_NEVER, 0x1, 0x1) ); GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) ); 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 else
{ {
@ -465,7 +445,7 @@ _cogl_add_stencil_clip (CoglFixed x_offset,
rectangle */ rectangle */
GE( glStencilFunc (GL_NEVER, 0x1, 0x3) ); GE( glStencilFunc (GL_NEVER, 0x1, 0x3) );
GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); 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 /* Subtract one from all pixels in the stencil buffer so that
only pixels where both the original stencil buffer and the 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_glMatrixMode (GL_PROJECTION) );
GE( cogl_wrap_glPushMatrix () ); GE( cogl_wrap_glPushMatrix () );
GE( cogl_wrap_glLoadIdentity () ); GE( cogl_wrap_glLoadIdentity () );
cogl_rectanglex (-COGL_FIXED_1, -COGL_FIXED_1, cogl_rectangle (-1.0, -1.0, 2, 2);
COGL_FIXED_FROM_INT (2),
COGL_FIXED_FROM_INT (2));
GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glPopMatrix () );
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
GE( cogl_wrap_glPopMatrix () ); GE( cogl_wrap_glPopMatrix () );
@ -490,10 +468,10 @@ _cogl_add_stencil_clip (CoglFixed x_offset,
} }
void void
_cogl_set_matrix (const CoglFixed *matrix) _cogl_set_matrix (const float *matrix)
{ {
GE( cogl_wrap_glLoadIdentity () ); GE( cogl_wrap_glLoadIdentity () );
GE( cogl_wrap_glMultMatrixx (matrix) ); GE( cogl_wrap_glMultMatrixf (matrix) );
} }
void void
@ -522,25 +500,25 @@ _cogl_disable_clip_planes (void)
void void
cogl_alpha_func (COGLenum func, 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 * Fixed point implementation of the perspective function
*/ */
void void
cogl_perspective (CoglFixed fovy, cogl_perspective (float fovy,
CoglFixed aspect, float aspect,
CoglFixed zNear, float zNear,
CoglFixed zFar) float zFar)
{ {
CoglFixed xmax, ymax; float xmax, ymax;
CoglFixed x, y, c, d; float x, y, c, d;
CoglFixed fovy_rad_half = cogl_fixed_mul (fovy, COGL_FIXED_PI) / 360; float fovy_rad_half = (fovy * G_PI) / 360;
GLfixed m[16]; GLfloat m[16];
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _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 * 2) When working with small numbers, we can are loosing significant
* precision * precision
*/ */
ymax = cogl_fixed_mul (zNear, ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
cogl_fixed_div (cogl_fixed_sin (fovy_rad_half), xmax = (ymax * aspect);
cogl_fixed_cos (fovy_rad_half)));
xmax = cogl_fixed_mul (ymax, aspect);
x = cogl_fixed_div (zNear, xmax); x = (zNear / xmax);
y = cogl_fixed_div (zNear, ymax); y = (zNear / ymax);
c = cogl_fixed_div (-(zFar + zNear), ( zFar - zNear)); c = (-(zFar + zNear) / ( zFar - zNear));
d = cogl_fixed_div (-(cogl_fixed_mul (2 * zFar, zNear)), (zFar - zNear)); d = (-(2 * zFar) * zNear) / (zFar - zNear);
#define M(row,col) m[col*4+row] #define M(row,col) m[col*4+row]
M(0,0) = x; M(0,0) = x;
M(1,1) = y; M(1,1) = y;
M(2,2) = c; M(2,2) = c;
M(2,3) = d; 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) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */ /* 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 #define m ctx->inverse_projection
M(0, 0) = cogl_fixed_div (COGL_FIXED_1, x); M(0, 0) = (1.0 / x);
M(1, 1) = cogl_fixed_div (COGL_FIXED_1, y); M(1, 1) = (1.0 / y);
M(2, 3) = -COGL_FIXED_1; M(2, 3) = -1.0;
M(3, 2) = cogl_fixed_div (COGL_FIXED_1, d); M(3, 2) = (1.0 / d);
M(3, 3) = cogl_fixed_div (c, d); M(3, 3) = (c / d);
#undef m #undef m
#undef M #undef M
} }
void void
cogl_frustum (CoglFixed left, cogl_frustum (float left,
CoglFixed right, float right,
CoglFixed bottom, float bottom,
CoglFixed top, float top,
CoglFixed z_near, float z_near,
CoglFixed z_far) float z_far)
{ {
CoglFixed c, d; float c, d;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) ); GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
GE( cogl_wrap_glLoadIdentity () ); GE( cogl_wrap_glLoadIdentity () );
GE( cogl_wrap_glFrustumx (left, right, GE( cogl_wrap_glFrustumf (left, right,
bottom, top, bottom, top,
z_near, z_far) ); z_near, z_far) );
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) ); GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */ /* 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); c = -(z_far + z_near / z_far - z_near);
d = -cogl_fixed_div (2 * cogl_fixed_mul (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] #define M(row,col) ctx->inverse_projection[col*4+row]
M(0,0) = cogl_fixed_div (right - left, 2 * z_near); M(0,0) = (right - left / 2 * z_near);
M(0,3) = cogl_fixed_div (right + left, 2 * z_near); M(0,3) = (right + left / 2 * z_near);
M(1,1) = cogl_fixed_div (top - bottom, 2 * z_near); M(1,1) = (top - bottom / 2 * z_near);
M(1,3) = cogl_fixed_div (top + bottom, 2 * z_near); M(1,3) = (top + bottom / 2 * z_near);
M(2,3) = -COGL_FIXED_1; M(2,3) = -1.0;
M(3,2) = cogl_fixed_div (COGL_FIXED_1, d); M(3,2) = (1.0 / d);
M(3,3) = cogl_fixed_div (c, d); M(3,3) = (c / d);
#undef M #undef M
} }
@ -639,51 +615,44 @@ cogl_viewport (guint width,
} }
void void
cogl_setup_viewport (guint w, cogl_setup_viewport (guint w,
guint h, guint h,
CoglFixed fovy, float fovy,
CoglFixed aspect, float aspect,
CoglFixed z_near, float z_near,
CoglFixed z_far) float z_far)
{ {
gint width = (gint) w; gint width = (gint) w;
gint height = (gint) h; gint height = (gint) h;
CoglFixed z_camera; float z_camera;
float projection_matrix[16];
GE( glViewport (0, 0, width, height) ); GE( glViewport (0, 0, width, height) );
/* For Ortho projection. /* 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); 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 * 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) cogl_get_projection_matrix (projection_matrix);
{ z_camera = 0.5 * projection_matrix[0];
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;
}
GE( cogl_wrap_glTranslatex (-1 << 15, -1 << 15, -z_camera) ); GE( cogl_wrap_glLoadIdentity () );
GE( cogl_wrap_glScalex ( COGL_FIXED_1 / width, GE( cogl_wrap_glTranslatef (-0.5f, -0.5f, -z_camera) );
-COGL_FIXED_1 / height,
COGL_FIXED_1 / width) );
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 static void
@ -735,19 +704,19 @@ cogl_features_available (CoglFeatureFlags features)
} }
void 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 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 void
cogl_get_viewport (CoglFixed v[4]) cogl_get_viewport (float v[4])
{ {
GLint viewport[4]; GLint viewport[4];
int i; int i;
@ -755,7 +724,7 @@ cogl_get_viewport (CoglFixed v[4])
cogl_wrap_glGetIntegerv (GL_VIEWPORT, viewport); cogl_wrap_glGetIntegerv (GL_VIEWPORT, viewport);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
v[i] = COGL_FIXED_FROM_INT (viewport[i]); v[i] = (float)(viewport[i]);
} }
void void
@ -773,11 +742,11 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
void void
cogl_fog_set (const CoglColor *fog_color, cogl_fog_set (const CoglColor *fog_color,
CoglFixed density, float density,
CoglFixed z_near, float z_near,
CoglFixed z_far) float z_far)
{ {
GLfixed fogColor[4]; GLfloat fogColor[4];
fogColor[0] = cogl_color_get_red (fog_color); fogColor[0] = cogl_color_get_red (fog_color);
fogColor[1] = cogl_color_get_green (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_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); glHint (GL_FOG_HINT, GL_NICEST);
cogl_wrap_glFogx (GL_FOG_DENSITY, (GLfixed) density); cogl_wrap_glFogf (GL_FOG_DENSITY, (GLfloat) density);
cogl_wrap_glFogx (GL_FOG_START, (GLfixed) z_near); cogl_wrap_glFogf (GL_FOG_START, (GLfloat) z_near);
cogl_wrap_glFogx (GL_FOG_END, (GLfixed) z_far); cogl_wrap_glFogf (GL_FOG_END, (GLfloat) z_far);
} }

View File

@ -199,6 +199,12 @@ clutter_stage_egl_realize (ClutterActor *actor)
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return; 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 else
{ {

View File

@ -320,7 +320,7 @@ create_cogl_texture (ClutterTexture *texture,
CoglHandle handle; CoglHandle handle;
gboolean using_rectangle; gboolean using_rectangle;
GLint gl_format; GLint gl_format;
CoglPixelFormat cogl_format; CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_RGBA_8888;
guint depth; guint depth;
g_object_get (G_OBJECT (texture_glx), "pixmap-depth", &depth, NULL); g_object_get (G_OBJECT (texture_glx), "pixmap-depth", &depth, NULL);

View File

@ -272,6 +272,7 @@ cogl_pango_glyph_cache_set (CoglPangoGlyphCache *cache,
texture = texture->next); texture = texture->next);
if (texture == NULL) if (texture == NULL)
{ {
CoglTextureFlags flags = COGL_TEXTURE_NONE;
guchar *clear_data; guchar *clear_data;
/* Allocate a new texture that is the nearest power of two /* 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 = g_slice_new (CoglPangoGlyphCacheTexture);
texture->texture_size = MIN_TEXTURE_SIZE; texture->texture_size = MIN_TEXTURE_SIZE;
while (texture->texture_size < band_height while (texture->texture_size < band_height ||
|| texture->texture_size < width) texture->texture_size < width)
texture->texture_size *= 2; {
texture->texture_size *= 2;
}
/* Allocate an empty buffer to clear the texture */ /* Allocate an empty buffer to clear the texture */
clear_data = g_malloc0 (texture->texture_size clear_data =
* texture->texture_size); g_malloc0 (texture->texture_size * texture->texture_size);
texture->texture = cogl_texture_new_from_data if (cache->use_mipmapping)
(texture->texture_size, texture->texture_size, flags |= COGL_TEXTURE_AUTO_MIPMAP;
32, cache->use_mipmapping,
COGL_PIXEL_FORMAT_A_8, COGL_PIXEL_FORMAT_A_8, texture->texture =
texture->texture_size, clear_data); 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); g_free (clear_data);
@ -342,13 +351,13 @@ cogl_pango_glyph_cache_set (CoglPangoGlyphCache *cache,
value = g_slice_new (CoglPangoGlyphCacheValue); value = g_slice_new (CoglPangoGlyphCacheValue);
value->texture = cogl_texture_ref (band->texture); 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; / band->texture_size;
value->tx2 = COGL_FIXED_FROM_INT (band->space_remaining + width) value->tx2 = (float)(band->space_remaining + width)
/ band->texture_size; / band->texture_size;
value->ty1 = COGL_FIXED_FROM_INT (band->top) value->ty1 = (float)(band->top)
/ band->texture_size; / band->texture_size;
value->ty2 = COGL_FIXED_FROM_INT (band->top + height) value->ty2 = (float)(band->top + height)
/ band->texture_size; / band->texture_size;
value->draw_x = draw_x; value->draw_x = draw_x;
value->draw_y = draw_y; value->draw_y = draw_y;

View File

@ -37,10 +37,10 @@ struct _CoglPangoGlyphCacheValue
{ {
CoglHandle texture; CoglHandle texture;
CoglFixed tx1; float tx1;
CoglFixed ty1; float ty1;
CoglFixed tx2; float tx2;
CoglFixed ty2; float ty2;
int draw_x; int draw_x;
int draw_y; int draw_y;

View File

@ -67,7 +67,7 @@ cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv)
{ {
if (priv->glyph_rectangles->len > 0) 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, cogl_texture_multiple_rectangles (priv->glyph_texture, rectangles,
priv->glyph_rectangles->len / 8); priv->glyph_rectangles->len / 8);
g_array_set_size (priv->glyph_rectangles, 0); g_array_set_size (priv->glyph_rectangles, 0);
@ -77,11 +77,11 @@ cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv)
static void static void
cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv,
CoglPangoGlyphCacheValue *cache_value, CoglPangoGlyphCacheValue *cache_value,
CoglFixed x1, float x1,
CoglFixed y1) float y1)
{ {
CoglFixed x2, y2; float x2, y2;
CoglFixed *p; float *p;
if (priv->glyph_rectangles->len > 0 if (priv->glyph_rectangles->len > 0
&& priv->glyph_texture != cache_value->texture) && 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); y2 = y1 + CLUTTER_INT_TO_FIXED (cache_value->draw_height);
g_array_set_size (priv->glyph_rectangles, priv->glyph_rectangles->len + 8); 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); priv->glyph_rectangles->len - 8);
*(p++) = x1; *(p++) = y1; *(p++) = x1; *(p++) = y1;
@ -102,8 +102,6 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv,
*(p++) = cache_value->tx2; *(p++) = cache_value->ty2; *(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_finalize (GObject *object);
static void cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, static void cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
PangoFont *font, PangoFont *font,
@ -133,7 +131,7 @@ cogl_pango_renderer_init (CoglPangoRenderer *priv)
priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE); priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE);
priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE); priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE);
priv->use_mipmapping = FALSE; 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 static void
@ -413,10 +411,10 @@ static void
cogl_pango_renderer_draw_box (int x, int y, cogl_pango_renderer_draw_box (int x, int y,
int width, int height) int width, int height)
{ {
cogl_path_rectangle (COGL_FIXED_FROM_INT (x), cogl_path_rectangle ((float)(x),
COGL_FIXED_FROM_INT (y - height), (float)(y - height),
COGL_FIXED_FROM_INT (width), (float)(width),
COGL_FIXED_FROM_INT (height)); (float)(height));
cogl_path_stroke (); cogl_path_stroke ();
} }
@ -424,23 +422,23 @@ static void
cogl_pango_renderer_get_device_units (PangoRenderer *renderer, cogl_pango_renderer_get_device_units (PangoRenderer *renderer,
int xin, int xin,
int yin, int yin,
CoglFixed *xout, float *xout,
CoglFixed *yout) float *yout)
{ {
const PangoMatrix *matrix; const PangoMatrix *matrix;
if ((matrix = pango_renderer_get_matrix (renderer))) if ((matrix = pango_renderer_get_matrix (renderer)))
{ {
/* Convert user-space coords to device coords */ /* 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); / 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); / PANGO_SCALE + matrix->y0);
} }
else else
{ {
*xout = COGL_PANGO_UNIT_TO_FIXED (xin); *xout = PANGO_PIXELS (xin);
*yout = COGL_PANGO_UNIT_TO_FIXED (yin); *yout = PANGO_PIXELS (yin);
} }
} }
@ -452,7 +450,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
int width, int width,
int height) int height)
{ {
CoglFixed x1, x2, y1, y2; float x1, x2, y1, y2;
cogl_pango_renderer_set_color_for_part (renderer, part); cogl_pango_renderer_set_color_for_part (renderer, part);
@ -463,7 +461,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
x + width, y + height, x + width, y + height,
&x2, &y2); &x2, &y2);
cogl_rectanglex (x1, y1, x2 - x1, y2 - y1); cogl_rectangle (x1, y1, x2 - x1, y2 - y1);
} }
static void static void
@ -476,15 +474,15 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
double x12, double x12,
double x22) double x22)
{ {
CoglFixed points[8]; float points[8];
points[0] = COGL_FIXED_FROM_FLOAT (x11); points[0] = (x11);
points[1] = COGL_FIXED_FROM_FLOAT (y1); points[1] = (y1);
points[2] = COGL_FIXED_FROM_FLOAT (x12); points[2] = (x12);
points[3] = COGL_FIXED_FROM_FLOAT (y2); points[3] = (y2);
points[4] = COGL_FIXED_FROM_FLOAT (x22); points[4] = (x22);
points[5] = points[3]; points[5] = points[3];
points[6] = COGL_FIXED_FROM_FLOAT (x21); points[6] = (x21);
points[7] = points[1]; points[7] = points[1];
cogl_pango_renderer_set_color_for_part (renderer, part); 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++) for (i = 0; i < glyphs->num_glyphs; i++)
{ {
PangoGlyphInfo *gi = glyphs->glyphs + i; PangoGlyphInfo *gi = glyphs->glyphs + i;
CoglFixed x, y; float x, y;
cogl_pango_renderer_get_device_units (renderer, cogl_pango_renderer_get_device_units (renderer,
xi + gi->geometry.x_offset, xi + gi->geometry.x_offset,
@ -526,15 +524,15 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
if (font == NULL || if (font == NULL ||
(metrics = pango_font_get_metrics (font, NULL)) == NULL) (metrics = pango_font_get_metrics (font, NULL)) == NULL)
{ {
cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), cogl_pango_renderer_draw_box ( (x),
COGL_FIXED_TO_INT (y), (y),
PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT); PANGO_UNKNOWN_GLYPH_HEIGHT);
} }
else else
{ {
cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), cogl_pango_renderer_draw_box ( (x),
COGL_FIXED_TO_INT (y), (y),
metrics->approximate_char_width metrics->approximate_char_width
/ PANGO_SCALE, / PANGO_SCALE,
metrics->ascent / 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_glyphs_end (priv);
cogl_pango_renderer_draw_box (COGL_FIXED_TO_INT (x), cogl_pango_renderer_draw_box ( (x),
COGL_FIXED_TO_INT (y), (y),
PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT); PANGO_UNKNOWN_GLYPH_HEIGHT);
} }
else else
{ {
CoglFixed width, height; float width, height;
x += COGL_FIXED_FROM_INT (cache_value->draw_x); x += (float)(cache_value->draw_x);
y += COGL_FIXED_FROM_INT (cache_value->draw_y); y += (float)(cache_value->draw_y);
width = x + COGL_FIXED_FROM_INT (cache_value->draw_width); width = x + (float)(cache_value->draw_width);
height = y + COGL_FIXED_FROM_INT (cache_value->draw_height); height = y + (float)(cache_value->draw_height);
cogl_pango_renderer_draw_glyph (priv, cache_value, x, y); cogl_pango_renderer_draw_glyph (priv, cache_value, x, y);
} }

View File

@ -427,12 +427,6 @@ event_translate (ClutterBackend *backend,
case ConfigureNotify: case ConfigureNotify:
if (!stage_x11->is_foreign_xwin) 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)", CLUTTER_NOTE (BACKEND, "%s: ConfigureNotify[%x] (%d, %d)",
G_STRLOC, G_STRLOC,
(unsigned int) stage_x11->xwin, (unsigned int) stage_x11->xwin,
@ -443,8 +437,6 @@ event_translate (ClutterBackend *backend,
xevent->xconfigure.width, xevent->xconfigure.width,
xevent->xconfigure.height); xevent->xconfigure.height);
stage_x11->handling_configure = FALSE;
/* the resize process is complete, so we can ask the stage /* the resize process is complete, so we can ask the stage
* to set up the GL viewport with the new size * to set up the GL viewport with the new size
*/ */

View File

@ -270,21 +270,8 @@ clutter_stage_x11_allocate (ClutterActor *self,
stage_x11->xwin_width = new_width; stage_x11->xwin_width = new_width;
stage_x11->xwin_height = new_height; 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 && if (stage_x11->xwin != None &&
!stage_x11->is_foreign_xwin && !stage_x11->is_foreign_xwin)
!stage_x11->handling_configure)
{ {
CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)", CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)",
G_STRLOC, G_STRLOC,
@ -577,7 +564,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
stage->is_foreign_xwin = FALSE; stage->is_foreign_xwin = FALSE;
stage->fullscreen_on_map = FALSE; stage->fullscreen_on_map = FALSE;
stage->handling_configure = FALSE;
stage->is_cursor_visible = TRUE; stage->is_cursor_visible = TRUE;
stage->title = NULL; stage->title = NULL;

View File

@ -47,7 +47,6 @@ struct _ClutterStageX11
guint is_foreign_xwin : 1; guint is_foreign_xwin : 1;
guint fullscreen_on_map : 1; guint fullscreen_on_map : 1;
guint handling_configure : 1;
guint is_cursor_visible : 1; guint is_cursor_visible : 1;
Display *xdpy; Display *xdpy;

View File

@ -440,7 +440,7 @@ clutter_x11_texture_pixmap_set_property (GObject *object,
{ {
case PROP_PIXMAP: case PROP_PIXMAP:
clutter_x11_texture_pixmap_set_pixmap (texture, clutter_x11_texture_pixmap_set_pixmap (texture,
g_value_get_uint (value)); g_value_get_ulong (value));
break; break;
case PROP_AUTO: case PROP_AUTO:
clutter_x11_texture_pixmap_set_automatic (texture, clutter_x11_texture_pixmap_set_automatic (texture,
@ -481,7 +481,7 @@ clutter_x11_texture_pixmap_get_property (GObject *object,
switch (prop_id) switch (prop_id)
{ {
case PROP_PIXMAP: case PROP_PIXMAP:
g_value_set_uint (value, priv->pixmap); g_value_set_ulong (value, priv->pixmap);
break; break;
case PROP_PIXMAP_WIDTH: case PROP_PIXMAP_WIDTH:
g_value_set_uint (value, priv->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; klass->update_area = clutter_x11_texture_pixmap_update_area_real;
pspec = g_param_spec_uint ("pixmap", pspec = g_param_spec_ulong ("pixmap",
"Pixmap", "Pixmap",
"The X11 Pixmap to be bound", "The X11 Pixmap to be bound",
0, G_MAXINT, 0, G_MAXULONG,
None, None,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_PIXMAP, pspec); 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); g_object_class_install_property (object_class, PROP_AUTO, pspec);
pspec = g_param_spec_uint ("window", pspec = g_param_spec_ulong ("window",
"Window", "Window",
"The X11 Window to be bound", "The X11 Window to be bound",
0, G_MAXINT, 0, G_MAXULONG,
None, None,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_WINDOW, pspec); g_object_class_install_property (object_class, PROP_WINDOW, pspec);

View File

@ -1 +1 @@
SUBDIRS = clutter cogl SUBDIRS = cogl clutter

View File

@ -105,6 +105,7 @@
<xi:include href="xml/clutter-interval.xml"/> <xi:include href="xml/clutter-interval.xml"/>
<xi:include href="xml/clutter-animation.xml"/> <xi:include href="xml/clutter-animation.xml"/>
<xi:include href="xml/clutter-animatable.xml"/>
</chapter> </chapter>
</part> </part>

View File

@ -2,17 +2,17 @@
<FILE>clutter-media</FILE> <FILE>clutter-media</FILE>
<TITLE>ClutterMedia</TITLE> <TITLE>ClutterMedia</TITLE>
ClutterMedia ClutterMedia
ClutterMediaInterface ClutterMediaIface
clutter_media_set_uri clutter_media_set_uri
clutter_media_get_uri clutter_media_get_uri
clutter_media_set_playing clutter_media_set_playing
clutter_media_get_playing clutter_media_get_playing
clutter_media_set_position clutter_media_set_progress
clutter_media_get_position clutter_media_get_progress
clutter_media_set_volume clutter_media_set_audio_volume
clutter_media_get_volume clutter_media_get_audio_volume
clutter_media_get_can_seek clutter_media_get_can_seek
clutter_media_get_buffer_percent clutter_media_get_buffer_fill
clutter_media_get_duration clutter_media_get_duration
clutter_media_set_filename clutter_media_set_filename
<SUBSECTION Standard> <SUBSECTION Standard>
@ -29,26 +29,24 @@ clutter_media_get_type
<TITLE>Unit conversion</TITLE> <TITLE>Unit conversion</TITLE>
ClutterUnit ClutterUnit
CLUTTER_UNITS_FORMAT 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_FROM_FLOAT
CLUTTER_UNITS_TO_FLOAT CLUTTER_UNITS_TO_FLOAT
CLUTTER_UNITS_FROM_INT CLUTTER_UNITS_FROM_INT
CLUTTER_UNITS_TO_INT CLUTTER_UNITS_TO_INT
<SUBSECTION>
CLUTTER_UNITS_FROM_DEVICE
CLUTTER_UNITS_TO_DEVICE
CLUTTER_UNITS_FROM_FIXED
CLUTTER_UNITS_TO_FIXED
CLUTTER_UNITS_FROM_PANGO_UNIT CLUTTER_UNITS_FROM_PANGO_UNIT
CLUTTER_UNITS_TO_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_MM
CLUTTER_UNITS_FROM_MMX
CLUTTER_UNITS_FROM_POINTS CLUTTER_UNITS_FROM_POINTS
CLUTTER_UNITS_FROM_POINTSX CLUTTER_UNITS_FROM_EM
clutter_units_mm
clutter_units_pt
clutter_units_em
<SUBSECTION> <SUBSECTION>
CLUTTER_MAXUNIT CLUTTER_MAXUNIT
@ -102,7 +100,7 @@ ClutterAlpha
ClutterAlphaClass ClutterAlphaClass
clutter_alpha_new clutter_alpha_new
clutter_alpha_new_full clutter_alpha_new_full
clutter_alpha_new_for_mode clutter_alpha_new_with_func
clutter_alpha_get_alpha clutter_alpha_get_alpha
CLUTTER_ALPHA_MAX_ALPHA CLUTTER_ALPHA_MAX_ALPHA
ClutterAlphaFunc ClutterAlphaFunc
@ -113,6 +111,10 @@ clutter_alpha_get_timeline
clutter_alpha_set_mode clutter_alpha_set_mode
clutter_alpha_get_mode clutter_alpha_get_mode
<SUBSECTION>
clutter_alpha_register_closure
clutter_alpha_register_func
<SUBSECTION> <SUBSECTION>
clutter_ramp_inc_func clutter_ramp_inc_func
clutter_ramp_dec_func clutter_ramp_dec_func
@ -169,6 +171,35 @@ ClutterCloneTexturePrivate
clutter_clone_texture_get_type clutter_clone_texture_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>clutter-cairo-texture</FILE>
<TITLE>ClutterCairoTexture</TITLE>
ClutterCairoTexture
ClutterCairoTextureClass
clutter_cairo_texture_new
clutter_cairo_texture_set_surface_size
clutter_cairo_texture_get_surface_size
<SUBSECTION>
clutter_cairo_texture_create
clutter_cairo_texture_create_region
<SUBSECTION>
clutter_cairo_set_source_color
<SUBSECTION Standard>
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
<SUBSECTION Private>
ClutterCairoTexturePrivate
clutter_cairo_texture_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>clutter-group</FILE> <FILE>clutter-group</FILE>
<TITLE>ClutterGroup</TITLE> <TITLE>ClutterGroup</TITLE>
@ -518,6 +549,7 @@ clutter_stage_show_cursor
clutter_stage_hide_cursor clutter_stage_hide_cursor
clutter_stage_get_actor_at_pos clutter_stage_get_actor_at_pos
clutter_stage_ensure_current clutter_stage_ensure_current
clutter_stage_ensure_viewport
clutter_stage_queue_redraw clutter_stage_queue_redraw
clutter_stage_event clutter_stage_event
clutter_stage_set_key_focus clutter_stage_set_key_focus
@ -889,7 +921,6 @@ clutter_feature_get_all
<FILE>clutter-fixed</FILE> <FILE>clutter-fixed</FILE>
<TITLE>Fixed Point Support</TITLE> <TITLE>Fixed Point Support</TITLE>
ClutterFixed ClutterFixed
CFX_Q
CFX_ONE CFX_ONE
CFX_HALF CFX_HALF
CFX_MAX CFX_MAX
@ -923,23 +954,13 @@ CLUTTER_ANGLE_TO_DEG
CLUTTER_ANGLE_TO_DEGX CLUTTER_ANGLE_TO_DEGX
CLUTTER_ANGLE_MAX_DEG CLUTTER_ANGLE_MAX_DEG
CFX_RADIANS_TO_DEGREES CFX_RADIANS_TO_DEGREES
clutter_cosi
clutter_cosx clutter_cosx
clutter_sini
clutter_sinx clutter_sinx
CLUTTER_SQRTI_ARG_10_PERCENT clutter_tanx
CLUTTER_SQRTI_ARG_5_PERCENT clutter_atanx
CLUTTER_SQRTI_ARG_MAX clutter_atan2x
clutter_sqrti
clutter_sqrtx
clutter_log2x
clutter_pow2x
clutter_powx
clutter_qmulx clutter_qmulx
clutter_qdivx clutter_qdivx
clutter_tani
clutter_atani
clutter_atan2i
<SUBSECTION> <SUBSECTION>
CLUTTER_MAXFIXED CLUTTER_MAXFIXED
@ -1187,39 +1208,6 @@ CLUTTER_COGL
CLUTTER_NO_FPU CLUTTER_NO_FPU
</SECTION> </SECTION>
<SECTION>
<FILE>clutter-effect</FILE>
<TITLE>Clutter Effects</TITLE>
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
<SUBSECTION>
ClutterEffectCompleteFunc
clutter_effect_fade
clutter_effect_move
clutter_effect_path
clutter_effect_scale
clutter_effect_depth
clutter_effect_rotate
<SUBSECTION Standard>
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
<SUBSECTION Private>
ClutterEffectTemplatePrivate
clutter_effect_template_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>clutter-behaviour-depth</FILE> <FILE>clutter-behaviour-depth</FILE>
<TITLE>ClutterBehaviourDepth</TITLE> <TITLE>ClutterBehaviourDepth</TITLE>
@ -1507,8 +1495,8 @@ ClutterAnimation
ClutterAnimationClass ClutterAnimationClass
ClutterAnimationMode ClutterAnimationMode
clutter_animation_new clutter_animation_new
clutter_animation_set_actor clutter_animation_set_object
clutter_animation_get_actor clutter_animation_get_object
clutter_animation_set_mode clutter_animation_set_mode
clutter_animation_get_mode clutter_animation_get_mode
clutter_animation_set_duration clutter_animation_set_duration
@ -1567,6 +1555,10 @@ clutter_interval_get_interval
clutter_interval_compute_value clutter_interval_compute_value
clutter_interval_validate clutter_interval_validate
<SUBSECTION>
ClutterProgressFunc
clutter_interval_register_progress_func
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_TYPE_INTERVAL CLUTTER_TYPE_INTERVAL
CLUTTER_INTERVAL CLUTTER_INTERVAL
@ -1688,6 +1680,23 @@ ClutterTextPrivate
clutter_text_get_type clutter_text_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>clutter-animatable</FILE>
<TITLE>ClutterAnimatable</TITLE>
ClutterAnimatable
ClutterAnimatableIface
clutter_animatable_animate_property
<SUBSECTION Standard>
CLUTTER_TYPE_ANIMATABLE
CLUTTER_ANIMATABLE
CLUTTER_IS_ANIMATABLE
CLUTTER_ANIMATABLE_GET_IFACE
<SUBSECTION Private>
clutter_animatable_get_type
</SECTION>
<SECTION> <SECTION>
<TITLE>Key Bindings</TITLE> <TITLE>Key Bindings</TITLE>
<FILE>clutter-binding-pool</FILE> <FILE>clutter-binding-pool</FILE>
@ -1711,4 +1720,12 @@ clutter_binding_pool_unblock_action
<SUBSECTION> <SUBSECTION>
clutter_binding_pool_activate clutter_binding_pool_activate
<SUBSECTION Standard>
CLUTTER_BINDING_POOL
CLUTTER_IS_BINDING_POOL
CLUTTER_TYPE_BINDING_POOL
<SUBSECTION Private>
clutter_binding_pool_get_type
</SECTION> </SECTION>

View File

@ -28,3 +28,4 @@ clutter_shader_get_type
clutter_child_meta_get_type clutter_child_meta_get_type
clutter_cairo_texture_get_type clutter_cairo_texture_get_type
clutter_text_get_type clutter_text_get_type
clutter_animatable_get_type

View File

@ -62,7 +62,7 @@
<xi:include href="xml/cogl-offscreen.xml"/> <xi:include href="xml/cogl-offscreen.xml"/>
<xi:include href="xml/cogl-fixed.xml"/> <xi:include href="xml/cogl-fixed.xml"/>
<xi:include href="xml/cogl-color.xml"/> <xi:include href="xml/cogl-color.xml"/>
<xi:include href="xml/cogl-mesh.xml"/> <xi:include href="xml/cogl-vertex-buffer.xml"/>
</chapter> </chapter>

View File

@ -23,11 +23,10 @@ cogl_get_viewport
cogl_push_matrix cogl_push_matrix
cogl_pop_matrix cogl_pop_matrix
cogl_scale cogl_scale
cogl_translatex
cogl_translate cogl_translate
cogl_rotatex
cogl_rotate cogl_rotate
<SUBSECTION> <SUBSECTION>
CoglClipStackState
cogl_clip_set cogl_clip_set
cogl_clip_set_from_path cogl_clip_set_from_path
cogl_clip_set_from_path_preserve cogl_clip_set_from_path_preserve
@ -89,22 +88,28 @@ cogl_path_stroke
cogl_path_stroke_preserve cogl_path_stroke_preserve
cogl_set_source_color cogl_set_source_color
cogl_set_source_color4ub cogl_set_source_color4ub
cogl_set_source_color4x cogl_set_source_color4f
cogl_color
<SUBSECTION> <SUBSECTION>
cogl_rectangle cogl_rectangle
cogl_rectanglex
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>cogl-texture</FILE> <FILE>cogl-texture</FILE>
<TITLE>Textures</TITLE> <TITLE>Textures</TITLE>
CoglTextureVertex CoglTextureVertex
CoglTextureFlags
cogl_texture_new_with_size cogl_texture_new_with_size
cogl_texture_new_from_file cogl_texture_new_from_file
cogl_texture_new_from_data cogl_texture_new_from_data
cogl_texture_new_from_foreign cogl_texture_new_from_foreign
cogl_texture_new_from_bitmap
cogl_is_texture cogl_is_texture
cogl_texture_ref
cogl_texture_unref
<SUBSECTION>
cogl_texture_get_width cogl_texture_get_width
cogl_texture_get_height cogl_texture_get_height
cogl_texture_get_format cogl_texture_get_format
@ -117,11 +122,18 @@ cogl_texture_get_gl_texture
cogl_texture_get_data cogl_texture_get_data
cogl_texture_set_filters cogl_texture_set_filters
cogl_texture_set_region cogl_texture_set_region
cogl_texture_ref
cogl_texture_unref <SUBSECTION>
cogl_texture_rectangle cogl_texture_rectangle
cogl_texture_multiple_rectangles cogl_texture_multiple_rectangles
cogl_texture_polygon cogl_texture_polygon
<SUBSECTION>
CoglBitmap
cogl_bitmap_new_from_file
cogl_bitmap_free
cogl_bitmap_get_size_from_file
</SECTION> </SECTION>
<SECTION> <SECTION>
@ -145,6 +157,7 @@ cogl_program_link
cogl_program_use cogl_program_use
cogl_program_get_uniform_location cogl_program_get_uniform_location
cogl_program_uniform_1f cogl_program_uniform_1f
cogl_program_uniform_1i
cogl_program_uniform_float cogl_program_uniform_float
cogl_program_uniform_int cogl_program_uniform_int
cogl_program_uniform_matrix cogl_program_uniform_matrix
@ -228,6 +241,7 @@ cogl_fixed_pow
cogl_fixed_pow2 cogl_fixed_pow2
cogl_fixed_sin cogl_fixed_sin
cogl_fixed_sqrt cogl_fixed_sqrt
cogl_fixed_tan
<SUBSECTION> <SUBSECTION>
CoglAngle CoglAngle
@ -257,7 +271,7 @@ cogl_color_copy
cogl_color_free cogl_color_free
cogl_color_set_from_4ub cogl_color_set_from_4ub
cogl_color_set_from_4d cogl_color_set_from_4d
cogl_color_set_from_4x cogl_color_set_from_4f
<SUBSECTION> <SUBSECTION>
cogl_color_get_red cogl_color_get_red
@ -279,19 +293,21 @@ cogl_color_get_alpha_float
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>cogl-mesh</FILE> <FILE>cogl-vertex-buffer</FILE>
<TITLE>Mesh API</TITLE> <TITLE>Vertex Buffers</TITLE>
cogl_mesh_new CoglVertexBufferAttribFlags
cogl_mesh_ref COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK
cogl_mesh_unref COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK
CoglMeshAttributeFlags cogl_vertex_buffer_new
cogl_mesh_add_attribute cogl_vertex_buffer_ref
cogl_mesh_delete_attribute cogl_vertex_buffer_unref
cogl_mesh_enable_attribute cogl_vertex_buffer_add
cogl_mesh_disable_attribute cogl_vertex_buffer_delete
cogl_mesh_draw_arrays cogl_vertex_buffer_enable
cogl_mesh_draw_range_elements cogl_vertex_buffer_disable
cogl_mesh_submit cogl_vertex_buffer_submit
cogl_vertex_buffer_draw
cogl_vertex_buffer_draw_range_elements
</SECTION> </SECTION>
<SECTION> <SECTION>

View File

@ -12,9 +12,9 @@ test_conformance_SOURCES = \
test-timeline-rewind.c \ test-timeline-rewind.c \
test-timeline-smoothness.c \ test-timeline-smoothness.c \
test-timeline.c \ test-timeline.c \
test-mesh-contiguous.c \ test-vertex-buffer-contiguous.c \
test-mesh-interleved.c \ test-vertex-buffer-interleved.c \
test-mesh-mutability.c \ test-vertex-buffer-mutability.c \
test-path.c \ test-path.c \
test-pick.c \ test-pick.c \
test-clutter-rectangle.c \ test-clutter-rectangle.c \

View File

@ -114,33 +114,33 @@ on_paint (ClutterActor *actor, TestState *state)
the first */ the first */
for (i = 0; i < 2; i++) 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]; CoglTextureVertex verts[4];
memset (verts, 0, sizeof (verts)); memset (verts, 0, sizeof (verts));
/* Set the color to white so that all the textures will be drawn /* Set the color to white so that all the textures will be drawn
at their own color */ at their own color */
cogl_set_source_color4x (COGL_FIXED_1, COGL_FIXED_1, cogl_set_source_color4f (1.0, 1.0,
COGL_FIXED_1, COGL_FIXED_1); 1.0, 1.0);
x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a front-facing texture */ /* Draw a front-facing texture */
cogl_texture_rectangle (state->texture, cogl_texture_rectangle (state->texture,
x1, y1, x2, y2, x1, y1, x2, y2,
0, 0, COGL_FIXED_1, COGL_FIXED_1); 0, 0, 1.0, 1.0);
x1 = x2; x1 = x2;
x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a back-facing texture */ /* Draw a back-facing texture */
cogl_texture_rectangle (state->texture, cogl_texture_rectangle (state->texture,
x2, y1, x1, y2, x2, y1, x1, y2,
0, 0, COGL_FIXED_1, COGL_FIXED_1); 0, 0, 1.0, 1.0);
x1 = x2; x1 = x2;
x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a front-facing texture polygon */ /* Draw a front-facing texture polygon */
verts[0].x = x1; verts[0].y = y2; 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[2].x = x2; verts[2].y = y1;
verts[3].x = x1; verts[3].y = y1; verts[3].x = x1; verts[3].y = y1;
verts[0].tx = 0; verts[0].ty = 0; verts[0].tx = 0; verts[0].ty = 0;
verts[1].tx = COGL_FIXED_1; verts[1].ty = 0; verts[1].tx = 1.0; verts[1].ty = 0;
verts[2].tx = COGL_FIXED_1; verts[2].ty = COGL_FIXED_1; verts[2].tx = 1.0; verts[2].ty = 1.0;
verts[3].tx = 0; verts[3].ty = COGL_FIXED_1; verts[3].tx = 0; verts[3].ty = 1.0;
cogl_texture_polygon (state->texture, 4, cogl_texture_polygon (state->texture, 4,
verts, FALSE); verts, FALSE);
x1 = x2; x1 = x2;
x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a back-facing texture polygon */ /* Draw a back-facing texture polygon */
verts[0].x = x1; verts[0].y = y1; 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[2].x = x2; verts[2].y = y2;
verts[3].x = x1; verts[3].y = y2; verts[3].x = x1; verts[3].y = y2;
verts[0].tx = 0; verts[0].ty = 0; verts[0].tx = 0; verts[0].ty = 0;
verts[1].tx = COGL_FIXED_1; verts[1].ty = 0; verts[1].tx = 1.0; verts[1].ty = 0;
verts[2].tx = COGL_FIXED_1; verts[2].ty = COGL_FIXED_1; verts[2].tx = 1.0; verts[2].ty = 1.0;
verts[3].tx = 0; verts[3].ty = COGL_FIXED_1; verts[3].tx = 0; verts[3].ty = 1.0;
cogl_texture_polygon (state->texture, 4, cogl_texture_polygon (state->texture, 4,
verts, FALSE); verts, FALSE);
x1 = x2; x1 = x2;
x2 = x1 + COGL_FIXED_FROM_INT (TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a regular rectangle (this should always show) */ /* Draw a regular rectangle (this should always show) */
cogl_set_source_color4x (COGL_FIXED_1, 0, 0, COGL_FIXED_1); cogl_set_source_color4f (1.0, 0, 0, 1.0);
cogl_rectangle (COGL_FIXED_TO_INT (x1), COGL_FIXED_TO_INT (y1), cogl_rectangle ( (x1), (y1),
COGL_FIXED_TO_INT (x2 - x1), COGL_FIXED_TO_INT (y2 - y1)); (x2 - x1), (y2 - y1));
/* The second time round draw beneath the first with backface /* The second time round draw beneath the first with backface
culling disabled */ culling disabled */
@ -225,7 +225,7 @@ make_texture (void)
tex = cogl_texture_new_from_data (TEXTURE_SIZE, tex = cogl_texture_new_from_data (TEXTURE_SIZE,
TEXTURE_SIZE, TEXTURE_SIZE,
8, 8,
FALSE, COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_RGBA_8888,
COGL_PIXEL_FORMAT_ANY, COGL_PIXEL_FORMAT_ANY,
TEXTURE_SIZE * 4, TEXTURE_SIZE * 4,

View File

@ -46,17 +46,17 @@ main (int argc, char **argv)
#endif #endif
g_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.openedhand.com/show_bug.cgi?id=%s"); 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) g_assert (clutter_init (shared_state->argc_addr, shared_state->argv_addr)
== CLUTTER_INIT_SUCCESS); == CLUTTER_INIT_SUCCESS);
/* Initialise the state you need to share with everything. /* Initialise the state you need to share with everything.
*/ */
shared_state->argc_addr = &argc; shared_state->argc_addr = &argc;
shared_state->argv_addr = &argv; shared_state->argv_addr = &argv;
TEST_CONFORM_SIMPLE ("/timeline", test_timeline); TEST_CONFORM_SIMPLE ("/timeline", test_timeline);
if (g_test_slow ()) 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_rewind);
TEST_CONFORM_SIMPLE ("/timeline", test_timeline_smoothness); TEST_CONFORM_SIMPLE ("/timeline", test_timeline_smoothness);
} }
TEST_CONFORM_SIMPLE ("/picking", test_pick); TEST_CONFORM_SIMPLE ("/picking", test_pick);
/* ClutterText */ /* ClutterText */
@ -88,15 +88,15 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_color); TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_color);
TEST_CONFORM_SIMPLE ("/fixed", test_fixed_constants); TEST_CONFORM_SIMPLE ("/fixed", test_fixed_constants);
TEST_CONFORM_SIMPLE ("/invariants", test_initial_state); TEST_CONFORM_SIMPLE ("/invariants", test_initial_state);
TEST_CONFORM_SIMPLE ("/invariants", test_realized); TEST_CONFORM_SIMPLE ("/invariants", test_realized);
TEST_CONFORM_SIMPLE ("/invariants", test_mapped); TEST_CONFORM_SIMPLE ("/invariants", test_mapped);
TEST_CONFORM_SIMPLE ("/invariants", test_show_on_set_parent); TEST_CONFORM_SIMPLE ("/invariants", test_show_on_set_parent);
TEST_CONFORM_SIMPLE ("/mesh", test_mesh_contiguous); TEST_CONFORM_SIMPLE ("/vertex-buffer", test_vertex_buffer_contiguous);
TEST_CONFORM_SIMPLE ("/mesh", test_mesh_interleved); TEST_CONFORM_SIMPLE ("/vertex-buffer", test_vertex_buffer_interleved);
TEST_CONFORM_SIMPLE ("/mesh", test_mesh_mutability); TEST_CONFORM_SIMPLE ("/vertex-buffer", test_vertex_buffer_mutability);
TEST_CONFORM_SIMPLE ("/opacity", test_label_opacity); TEST_CONFORM_SIMPLE ("/opacity", test_label_opacity);
TEST_CONFORM_SIMPLE ("/opacity", test_rectangle_opacity); TEST_CONFORM_SIMPLE ("/opacity", test_rectangle_opacity);

View File

@ -4,9 +4,9 @@
#include "test-conform-common.h" #include "test-conform-common.h"
/* This test verifies that the simplest usage of the mesh API, where we add /* This test verifies that the simplest usage of the vertex buffer API,
* contiguous (x,y) GLfloat vertices, and RGBA GLubyte color attributes to a * where we add contiguous (x,y) GLfloat vertices, and RGBA GLubyte color
* mesh object, submit, and draw. * attributes to a buffer, submit, and draw.
* *
* It also tries to verify that the enable/disable attribute APIs are working * It also tries to verify that the enable/disable attribute APIs are working
* too. * too.
@ -17,7 +17,7 @@
typedef struct _TestState typedef struct _TestState
{ {
CoglHandle mesh; CoglHandle buffer;
ClutterGeometry stage_geom; ClutterGeometry stage_geom;
guint frame; guint frame;
} TestState; } TestState;
@ -44,7 +44,7 @@ validate_result (TestState *state)
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); 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); g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
/* Should see a red pixel */ /* Should see a red pixel */
glReadPixels (110, y_off, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); glReadPixels (110, y_off, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
if (g_test_verbose ()) if (g_test_verbose ())
@ -56,11 +56,11 @@ validate_result (TestState *state)
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("pixel 2 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); 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); g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
#undef RED #undef RED
#undef GREEN #undef GREEN
#undef BLUE #undef BLUE
/* Comment this out if you want visual feedback of what this test /* Comment this out if you want visual feedback of what this test
* paints. * paints.
*/ */
@ -71,35 +71,35 @@ static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor, TestState *state)
{ {
/* Draw a faded blue triangle */ /* 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_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_mesh_draw_arrays (state->mesh, cogl_vertex_buffer_draw (state->buffer,
GL_TRIANGLE_STRIP, /* mode */ GL_TRIANGLE_STRIP, /* mode */
0, /* first */ 0, /* first */
3); /* count */ 3); /* count */
/* Draw a red triangle */ /* Draw a red triangle */
/* Here we are testing that the disable attribute works; if it doesn't /* Here we are testing that the disable attribute works; if it doesn't
* the triangle will remain faded blue */ * the triangle will remain faded blue */
cogl_translate (100, 0, 0); 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_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_mesh_draw_arrays (state->mesh, cogl_vertex_buffer_draw (state->buffer,
GL_TRIANGLE_STRIP, /* mode */ GL_TRIANGLE_STRIP, /* mode */
0, /* first */ 0, /* first */
3); /* count */ 3); /* count */
/* Draw a faded blue triangle */ /* Draw a faded blue triangle */
/* Here we are testing that the re-enable works; if it doesn't /* Here we are testing that the re-enable works; if it doesn't
* the triangle will remain red */ * the triangle will remain red */
cogl_translate (100, 0, 0); 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_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_mesh_draw_arrays (state->mesh, cogl_vertex_buffer_draw (state->buffer,
GL_TRIANGLE_STRIP, /* mode */ GL_TRIANGLE_STRIP, /* mode */
0, /* first */ 0, /* first */
3); /* count */ 3); /* count */
/* XXX: Experiments have shown that for some buggy drivers, when using /* 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 * glReadPixels there is some kind of race, so we delay our test for a
* few frames and a few seconds: * few frames and a few seconds:
@ -108,7 +108,7 @@ on_paint (ClutterActor *actor, TestState *state)
validate_result (state); validate_result (state);
else else
g_usleep (G_USEC_PER_SEC); g_usleep (G_USEC_PER_SEC);
state->frame++; state->frame++;
} }
@ -121,8 +121,8 @@ queue_redraw (gpointer stage)
} }
void void
test_mesh_contiguous (TestConformSimpleFixture *fixture, test_vertex_buffer_contiguous (TestConformSimpleFixture *fixture,
gconstpointer data) gconstpointer data)
{ {
TestState state; TestState state;
ClutterActor *stage; ClutterActor *stage;
@ -149,7 +149,7 @@ test_mesh_contiguous (TestConformSimpleFixture *fixture,
idle_source = g_idle_add (queue_redraw, stage); idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
{ {
GLfloat triangle_verts[3][2] = 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 */
{0x00, 0x00, 0xff, 0x00} /* transparent blue */ {0x00, 0x00, 0xff, 0x00} /* transparent blue */
}; };
state.mesh = cogl_mesh_new (3 /* n vertices */); state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
cogl_mesh_add_attribute (state.mesh, cogl_vertex_buffer_add (state.buffer,
"gl_Vertex", "gl_Vertex",
2, /* n components */ 2, /* n components */
GL_FLOAT, GL_FLOAT,
FALSE, /* normalized */ FALSE, /* normalized */
0, /* stride */ 0, /* stride */
triangle_verts); triangle_verts);
cogl_mesh_add_attribute (state.mesh, cogl_vertex_buffer_add (state.buffer,
"gl_Color::blue", "gl_Color::blue",
4, /* n components */ 4, /* n components */
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
FALSE, /* normalized */ FALSE, /* normalized */
0, /* stride */ 0, /* stride */
triangle_colors); triangle_colors);
cogl_mesh_submit (state.mesh); cogl_vertex_buffer_submit (state.buffer);
} }
clutter_actor_show_all (stage); clutter_actor_show_all (stage);
clutter_main (); clutter_main ();
cogl_mesh_unref (state.mesh); cogl_vertex_buffer_unref (state.buffer);
g_source_remove (idle_source); g_source_remove (idle_source);

View File

@ -4,9 +4,9 @@
#include "test-conform-common.h" #include "test-conform-common.h"
/* This test verifies that interleved attributes work with the mesh API. /* This test verifies that interleved attributes work with the vertex buffer
* We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color * API. We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color
* attributes to a mesh object, submit and draw. * attributes to a buffer, submit and draw.
* *
* If you want visual feedback of what this test paints for debugging purposes, * If you want visual feedback of what this test paints for debugging purposes,
* then remove the call to clutter_main_quit() in validate_result. * then remove the call to clutter_main_quit() in validate_result.
@ -14,7 +14,7 @@
typedef struct _TestState typedef struct _TestState
{ {
CoglHandle mesh; CoglHandle buffer;
ClutterGeometry stage_geom; ClutterGeometry stage_geom;
guint frame; guint frame;
} TestState; } TestState;
@ -51,11 +51,11 @@ validate_result (TestState *state)
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); 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); g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
#undef RED #undef RED
#undef GREEN #undef GREEN
#undef BLUE #undef BLUE
/* Comment this out if you want visual feedback of what this test /* Comment this out if you want visual feedback of what this test
* paints. * paints.
*/ */
@ -66,10 +66,10 @@ static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor, TestState *state)
{ {
/* Draw a faded blue triangle */ /* Draw a faded blue triangle */
cogl_mesh_draw_arrays (state->mesh, cogl_vertex_buffer_draw (state->buffer,
GL_TRIANGLE_STRIP, /* mode */ GL_TRIANGLE_STRIP, /* mode */
0, /* first */ 0, /* first */
3); /* count */ 3); /* count */
/* XXX: Experiments have shown that for some buggy drivers, when using /* 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 * 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); validate_result (state);
else else
g_usleep (G_USEC_PER_SEC); g_usleep (G_USEC_PER_SEC);
state->frame++; state->frame++;
} }
@ -92,8 +92,8 @@ queue_redraw (gpointer stage)
} }
void void
test_mesh_interleved (TestConformSimpleFixture *fixture, test_vertex_buffer_interleved (TestConformSimpleFixture *fixture,
gconstpointer data) gconstpointer data)
{ {
TestState state; TestState state;
ClutterActor *stage; ClutterActor *stage;
@ -120,7 +120,7 @@ test_mesh_interleved (TestConformSimpleFixture *fixture,
idle_source = g_idle_add (queue_redraw, stage); idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
{ {
InterlevedVertex verts[3] = InterlevedVertex verts[3] =
{ {
@ -141,29 +141,29 @@ test_mesh_interleved (TestConformSimpleFixture *fixture,
*/ */
g_assert (sizeof (InterlevedVertex) == 12); g_assert (sizeof (InterlevedVertex) == 12);
state.mesh = cogl_mesh_new (3 /* n vertices */); state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
cogl_mesh_add_attribute (state.mesh, cogl_vertex_buffer_add (state.buffer,
"gl_Vertex", "gl_Vertex",
2, /* n components */ 2, /* n components */
GL_FLOAT, GL_FLOAT,
FALSE, /* normalized */ FALSE, /* normalized */
12, /* stride */ 12, /* stride */
&verts[0].x); &verts[0].x);
cogl_mesh_add_attribute (state.mesh, cogl_vertex_buffer_add (state.buffer,
"gl_Color", "gl_Color",
4, /* n components */ 4, /* n components */
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
FALSE, /* normalized */ FALSE, /* normalized */
12, /* stride */ 12, /* stride */
&verts[0].r); &verts[0].r);
cogl_mesh_submit (state.mesh); cogl_vertex_buffer_submit (state.buffer);
} }
clutter_actor_show_all (stage); clutter_actor_show_all (stage);
clutter_main (); clutter_main ();
cogl_mesh_unref (state.mesh); cogl_vertex_buffer_unref (state.buffer);
g_source_remove (idle_source); g_source_remove (idle_source);

View File

@ -4,7 +4,7 @@
#include "test-conform-common.h" #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. * vertex positions, and deleting and re-adding different color attributes.
* *
* If you want visual feedback of what this test paints for debugging purposes, * If you want visual feedback of what this test paints for debugging purposes,
@ -13,7 +13,7 @@
typedef struct _TestState typedef struct _TestState
{ {
CoglHandle mesh; CoglHandle buffer;
ClutterGeometry stage_geom; ClutterGeometry stage_geom;
guint frame; guint frame;
} TestState; } TestState;
@ -47,7 +47,7 @@ validate_result (TestState *state)
#undef RED #undef RED
#undef GREEN #undef GREEN
#undef BLUE #undef BLUE
/* Comment this out if you want visual feedback of what this test /* Comment this out if you want visual feedback of what this test
* paints. * paints.
*/ */
@ -76,41 +76,41 @@ on_paint (ClutterActor *actor, TestState *state)
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_mesh_add_attribute (state->mesh, cogl_vertex_buffer_add (state->buffer,
"gl_Vertex", "gl_Vertex",
2, /* n components */ 2, /* n components */
GL_FLOAT, GL_FLOAT,
FALSE, /* normalized */ FALSE, /* normalized */
0, /* stride */ 0, /* stride */
triangle_verts); triangle_verts);
cogl_mesh_delete_attribute (state->mesh, "gl_Color"); cogl_vertex_buffer_delete (state->buffer, "gl_Color");
cogl_mesh_submit (state->mesh); cogl_vertex_buffer_submit (state->buffer);
cogl_mesh_draw_arrays (state->mesh, cogl_vertex_buffer_draw (state->buffer,
GL_TRIANGLE_STRIP, /* mode */ GL_TRIANGLE_STRIP, /* mode */
0, /* first */ 0, /* first */
3); /* count */ 3); /* count */
/* /*
* Draw a faded green triangle * Draw a faded green triangle
*/ */
cogl_mesh_add_attribute (state->mesh, cogl_vertex_buffer_add (state->buffer,
"gl_Color", "gl_Color",
4, /* n components */ 4, /* n components */
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
FALSE, /* normalized */ FALSE, /* normalized */
0, /* stride */ 0, /* stride */
triangle_colors); triangle_colors);
cogl_mesh_submit (state->mesh); cogl_vertex_buffer_submit (state->buffer);
cogl_translate (100, 0, 0); cogl_translate (100, 0, 0);
cogl_mesh_draw_arrays (state->mesh, cogl_vertex_buffer_draw (state->buffer,
GL_TRIANGLE_STRIP, /* mode */ GL_TRIANGLE_STRIP, /* mode */
0, /* first */ 0, /* first */
3); /* count */ 3); /* count */
/* XXX: Experiments have shown that for some buggy drivers, when using /* 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 * glReadPixels there is some kind of race, so we delay our test for a
* few frames and a few seconds: * few frames and a few seconds:
@ -119,7 +119,7 @@ on_paint (ClutterActor *actor, TestState *state)
validate_result (state); validate_result (state);
else else
g_usleep (G_USEC_PER_SEC); g_usleep (G_USEC_PER_SEC);
state->frame++; state->frame++;
} }
@ -132,8 +132,8 @@ queue_redraw (gpointer stage)
} }
void void
test_mesh_mutability (TestConformSimpleFixture *fixture, test_vertex_buffer_mutability (TestConformSimpleFixture *fixture,
gconstpointer data) gconstpointer data)
{ {
TestState state; TestState state;
ClutterActor *stage; ClutterActor *stage;
@ -160,7 +160,7 @@ test_mesh_mutability (TestConformSimpleFixture *fixture,
idle_source = g_idle_add (queue_redraw, stage); idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
{ {
GLfloat triangle_verts[3][2] = 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 */
{0x00, 0x00, 0xff, 0x00} /* transparent blue */ {0x00, 0x00, 0xff, 0x00} /* transparent blue */
}; };
state.mesh = cogl_mesh_new (3 /* n vertices */); state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
cogl_mesh_add_attribute (state.mesh, cogl_vertex_buffer_add (state.buffer,
"gl_Vertex", "gl_Vertex",
2, /* n components */ 2, /* n components */
GL_FLOAT, GL_FLOAT,
FALSE, /* normalized */ FALSE, /* normalized */
0, /* stride */ 0, /* stride */
triangle_verts); triangle_verts);
cogl_mesh_add_attribute (state.mesh, cogl_vertex_buffer_add (state.buffer,
"gl_Color", "gl_Color",
4, /* n components */ 4, /* n components */
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
FALSE, /* normalized */ FALSE, /* normalized */
0, /* stride */ 0, /* stride */
triangle_colors); triangle_colors);
cogl_mesh_submit (state.mesh); cogl_vertex_buffer_submit (state.buffer);
} }
clutter_actor_show_all (stage); clutter_actor_show_all (stage);
clutter_main (); clutter_main ();
cogl_mesh_unref (state.mesh); cogl_vertex_buffer_unref (state.buffer);
g_source_remove (idle_source); g_source_remove (idle_source);

View File

@ -15,7 +15,6 @@ UNIT_TESTS = \
test-script.c \ test-script.c \
test-model.c \ test-model.c \
test-grab.c \ test-grab.c \
test-effects.c \
test-fullscreen.c \ test-fullscreen.c \
test-shader.c \ test-shader.c \
test-unproject.c \ test-unproject.c \
@ -40,7 +39,8 @@ UNIT_TESTS = \
test-easing.c \ test-easing.c \
test-binding-pool.c \ test-binding-pool.c \
test-text.c \ test-text.c \
test-text-field.c test-text-field.c \
test-clutter-cairo-flowers.c
if X11_TESTS if X11_TESTS
UNIT_TESTS += test-pixmap.c UNIT_TESTS += test-pixmap.c

View File

@ -168,7 +168,8 @@ test_actors_main (int argc, char *argv[])
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh); g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh);
/* Set up some behaviours to handle scaling */ /* 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, scaler_1 = clutter_behaviour_scale_new (alpha,
0.5, 0.5, 0.5, 0.5,

View File

@ -23,13 +23,12 @@ on_button_press (ClutterActor *actor,
ClutterAnimation *animation; ClutterAnimation *animation;
gint old_x, old_y, new_x, new_y; gint old_x, old_y, new_x, new_y;
guint old_width, old_height, new_width, new_height; guint old_width, old_height, new_width, new_height;
guint8 old_op, new_op;
gdouble new_angle; gdouble new_angle;
ClutterVertex vertex = { 0, }; ClutterVertex vertex = { 0, };
ClutterColor new_color = { 0, };
clutter_actor_get_position (actor, &old_x, &old_y); clutter_actor_get_position (actor, &old_x, &old_y);
clutter_actor_get_size (actor, &old_width, &old_height); 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 /* determine the final state of the animation depending on
* the state of the actor * the state of the actor
@ -40,8 +39,12 @@ on_button_press (ClutterActor *actor,
new_y = old_y - 100; new_y = old_y - 100;
new_width = old_width + 200; new_width = old_width + 200;
new_height = old_height + 200; new_height = old_height + 200;
new_op = 255;
new_angle = 360.0; new_angle = 360.0;
new_color.red = 0xdd;
new_color.green = 0x44;
new_color.blue = 0xdd;
new_color.alpha = 0xff;
} }
else else
{ {
@ -49,8 +52,12 @@ on_button_press (ClutterActor *actor,
new_y = old_y + 100; new_y = old_y + 100;
new_width = old_width - 200; new_width = old_width - 200;
new_height = old_height - 200; new_height = old_height - 200;
new_op = 128;
new_angle = 0.0; 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); vertex.x = CLUTTER_UNITS_FROM_FLOAT ((float) new_width / 2);
@ -62,7 +69,7 @@ on_button_press (ClutterActor *actor,
"y", new_y, "y", new_y,
"width", new_width, "width", new_width,
"height", new_height, "height", new_height,
"opacity", new_op, "color", &new_color,
"rotation-angle-z", new_angle, "rotation-angle-z", new_angle,
"fixed::rotation-center-z", &vertex, "fixed::rotation-center-z", &vertex,
"fixed::reactive", FALSE, "fixed::reactive", FALSE,

View File

@ -171,8 +171,7 @@ test_behave_main (int argc, char *argv[])
NULL); NULL);
/* Set an alpha func to power behaviour - ramp is constant rise */ /* Set an alpha func to power behaviour - ramp is constant rise */
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR); alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
/* Create a behaviour for that alpha */ /* Create a behaviour for that alpha */
o_behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff); o_behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff);

View File

@ -302,8 +302,10 @@ test_clip_main (int argc, char **argv)
stub_actor = clutter_rectangle_new (); stub_actor = clutter_rectangle_new ();
clutter_container_add (CLUTTER_CONTAINER (data.stage), stub_actor, NULL); clutter_container_add (CLUTTER_CONTAINER (data.stage), stub_actor, NULL);
data.hand = cogl_texture_new_from_file ("redhand.png", 64, FALSE, data.hand = cogl_texture_new_from_file ("redhand.png", 64,
COGL_PIXEL_FORMAT_ANY, NULL); COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_ANY,
NULL);
label = clutter_text_new_with_text ("Sans 12px", instructions); label = clutter_text_new_with_text ("Sans 12px", instructions);
clutter_text_set_line_wrap (CLUTTER_TEXT (label), TRUE); clutter_text_set_line_wrap (CLUTTER_TEXT (label), TRUE);

Some files were not shown because too many files have changed in this diff Show More