+2007-05-25 Matthew Allum <mallum@openedhand.com>
+
+ * Makefile.am:
+ Install a default flavour .pc file.
+
+ * clutter/clutter-actor.c:
+ Translate units correctly for translate()
+
+ * clutter/clutter-feature.h:
+ Add new texture features.
+
+ * clutter/clutter-fixed.h:
+ Add clutter angle conversion defines.
+
+ * clutter/clutter-group.c:
+ Use cogl not GL. Dont recurse on show all.
+
+ * clutter/clutter-private.h:
+ Remove sync_viewport.
+
+ * clutter/clutter-rectangle.c:
+ Fix cogl typo.
+
+ * clutter/clutter-stage.c:
+ * clutter/clutter-stage.h:
+ Add perspective settings. Remove viewport_sync.
+ Add audience stubs. Fix up actor_at_pos a little (still broken)
+
+ * clutter/clutter-texture.h:
+ * clutter/clutter-texture.c:
+ Redo pixel uploading. Add initial (disabled) YUV support.
+
+ * clutter/clutter-timeline.c:
+ Fire 'completed' signal when looping.
+
+ * clutter/cogl/gl/cogl.c:
+ Move some backend checks here.
+
+ * clutter/glx/clutter-backend-glx.c:
+ Actually check target display has GLX ext.
+
+ * clutter/glx/clutter-stage-glx.c:
+ Handle offscreen failing more gracefully.
+
+ * examples/Makefile.am:
+ Use AM_LDFLAGS.
+
+ * clutter/clutter-main.c:
+ * clutter/clutter-feature.c:
+ * clutter/clutter-backend.c:
+ * clutter/clutter-alpha.c:
+ Fix a compile warnings.
+
+ * tests/Makefile.am:
+ * tests/test-offscreen.c:
+ * tests/test-scale.c:
+ More tests.
+
2007-05-23 Tomas Frydrych <tf@openedhand.com>
* clutter/clutter-actor.c:
pkgconfig_DATA = $(pcfiles)
pkgconfigdir = $(libdir)/pkgconfig
+DEFAULT_FLAVOUR=@CLUTTER_FLAVOUR@
+install-data-hook:
+ (cd $(DESTDIR)$(pkgconfigdir) && \
+ test -f clutter-$(DEFAULT_FLAVOUR)-@CLUTTER_MAJORMINOR@.pc && \
+ rm -f clutter-@CLUTTER_MAJORMINOR@.pc && cp -f clutter-$(DEFAULT_FLAVOUR)-@CLUTTER_MAJORMINOR@.pc clutter-@CLUTTER_MAJORMINOR@.pc)
+
+uninstall-local:
+ rm -f $(DESTDIR)$(pkgconfigdir)/clutter-@CLUTTER_MAJORMINOR@.pc
+
+
EXTRA_DIST = clutter.pc.in
CLEANFILES = $(pcfiles)
#include "clutter-units.h"
#include "cogl.h"
-#include <GL/gl.h>
-
G_DEFINE_ABSTRACT_TYPE (ClutterActor,
clutter_actor,
G_TYPE_INITIALLY_UNOWNED);
cogl_push_matrix();
-#define NEG(x) (1 + ~(x))
-
-#if CLUTTER_COGL_GL
+#if HAVE_COGL_GL
glLoadName (clutter_actor_get_id (self));
#endif
if (clutter_actor_get_parent (self) != NULL)
{
- cogl_translate (CLUTTER_FIXED_TO_FLOAT (priv->coords.x1),
- CLUTTER_FIXED_TO_FLOAT (priv->coords.y1),
+ cogl_translate (CLUTTER_UNITS_TO_INT (priv->coords.x1),
+ CLUTTER_UNITS_TO_INT (priv->coords.y1),
0);
}
cogl_scale (priv->scale_x, priv->scale_y);
}
-#if CLUTTER_COGL_GL
+#if HAVE_COGL_GL
if (priv->has_clip)
{
ClutterGeometry *clip = &(priv->clip);
clutter_smoothstep_func (ClutterAlpha *alpha,
gpointer *data)
{
- ClutterSmoothstep * smoothstep = data;
- ClutterTimeline * timeline;
+ ClutterSmoothstep *smoothstep = (ClutterSmoothstep*)data;
+ ClutterTimeline *timeline;
gint frame;
gint n_frames;
gint32 r;
{
ClutterBackendClass *klass;
- g_return_if_fail (CLUTTER_IS_BACKEND (backend));
+ g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), 0);
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->get_features)
} ClutterFeatures;
static ClutterFeatures* __features = NULL;
-G_LOCK_DEFINE_STATIC (__features);
void
_clutter_feature_init (void)
{
CLUTTER_FEATURE_TEXTURE_RECTANGLE = (1 << 1),
CLUTTER_FEATURE_SYNC_TO_VBLANK = (1 << 2),
- CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 3)
+ CLUTTER_FEATURE_TEXTURE_YUV = (1 << 3),
+ CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 4)
} ClutterFeatureFlags;
gboolean clutter_feature_available (ClutterFeatureFlags feature);
#define CLUTTER_FIXED_MUL(x,y) ((x) >> 8) * ((y) >> 8)
#define CLUTTER_FIXED_DIV(x,y) ((((x) << 8)/(y)) << 8)
+#define CLUTTER_DEGF_TO_CLUTTER_ANGLE(x) CLUTTER_FLOAT_TO_INT ((x / 360.0) * 1024)
+
+#define CLUTTER_ANGLE_TO_DEGF(x) (((float)x * 360.0)/ 1024.0)
+
/* some handy short aliases to avoid exessively long lines */
#define CFX_INT CLUTTER_FIXED_INT
#include "clutter-marshal.h"
#include "clutter-enum-types.h"
-#include <GL/gl.h>
-
enum
{
ADD,
CLUTTER_NOTE (PAINT, "ClutterGroup paint enter");
- glPushMatrix();
+ cogl_push_matrix();
for (child_item = self->priv->children;
child_item != NULL;
clutter_actor_paint (child);
}
- glPopMatrix();
+ cogl_pop_matrix();
CLUTTER_NOTE (PAINT, "ClutterGroup paint leave");
}
clutter_group_real_show_all (ClutterActor *actor)
{
clutter_group_foreach (CLUTTER_GROUP (actor),
- CLUTTER_CALLBACK (clutter_actor_show_all),
+ CLUTTER_CALLBACK (clutter_actor_show),
NULL);
clutter_actor_show (actor);
}
{
clutter_actor_hide (actor);
clutter_group_foreach (CLUTTER_GROUP (actor),
- CLUTTER_CALLBACK (clutter_actor_hide_all),
+ CLUTTER_CALLBACK (clutter_actor_hide),
NULL);
}
if (!initialised)
{
+ GType foo; /* Quiet gcc */
+
initialised = TRUE;
/* initialise GLib type system */
g_type_init ();
- (void) clutter_actor_get_type ();
+ foo = clutter_actor_get_type ();
}
}
void _clutter_feature_init (void);
-/* FIXME: move elsewhere via ClutterAudience */
-void _clutter_stage_sync_viewport (ClutterStage *stage);
-
/* Does this need to be private ? */
void clutter_do_event (ClutterEvent *event);
cogl_rectangle (0, 0, geom.width, geom.height);
}
- cogl_push_matrix();
+ cogl_pop_matrix();
}
static void
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
-#define FIXED_PERSPECTIVE
-#undef USING_GLES
-
G_DEFINE_ABSTRACT_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
#define CLUTTER_STAGE_GET_PRIVATE(obj) \
struct _ClutterStagePrivate
{
- ClutterColor color;
+ ClutterColor color;
+ ClutterPerspective perspective;
+ ClutterAudience audience;
guint is_fullscreen : 1;
guint is_offscreen : 1;
PROP_COLOR,
PROP_FULLSCREEN,
PROP_OFFSCREEN,
- PROP_CURSOR_VISIBLE
+ PROP_CURSOR_VISIBLE,
+ PROP_PERSPECTIVE,
+ PROP_AUDIENCE
};
enum
/* chain up */
CLUTTER_NOTE (PAINT, "Chaining up to parent class paint");
- if (CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint)
- CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (actor);
+ CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (actor);
}
static void
const GValue *value,
GParamSpec *pspec)
{
- ClutterStage *stage;
+ ClutterStage *stage;
ClutterStagePrivate *priv;
- ClutterActor *actor;
+ ClutterActor *actor;
stage = CLUTTER_STAGE (object);
actor = CLUTTER_ACTOR (stage);
clutter_stage_set_color (stage, g_value_get_boxed (value));
break;
case PROP_OFFSCREEN:
+ if (priv->is_offscreen == g_value_get_boolean (value))
+ return;
+
if (CLUTTER_ACTOR_IS_REALIZED (actor))
{
clutter_actor_unrealize (actor);
priv->is_offscreen = g_value_get_boolean (value);
clutter_actor_realize (actor);
+
+ if (!CLUTTER_ACTOR_IS_REALIZED (actor))
+ priv->is_offscreen = ~g_value_get_boolean (value);
}
else
priv->is_offscreen = g_value_get_boolean (value);
else
clutter_stage_hide_cursor (stage);
break;
+ case PROP_PERSPECTIVE:
+ clutter_stage_set_perspectivex (stage, g_value_get_boxed (value));
+ break;
+ case PROP_AUDIENCE:
+ clutter_stage_set_audience (stage, g_value_get_boxed (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
ClutterStage *stage;
ClutterStagePrivate *priv;
ClutterColor color;
+ ClutterAudience audience;
+ ClutterPerspective perspective;
stage = CLUTTER_STAGE(object);
priv = stage->priv;
case PROP_CURSOR_VISIBLE:
g_value_set_boolean (value, priv->is_cursor_visible);
break;
+ case PROP_PERSPECTIVE:
+ clutter_stage_get_perspectivex (stage, &perspective);
+ g_value_set_boxed (value, &perspective);
+ break;
+ case PROP_AUDIENCE:
+ clutter_stage_get_audience (stage, &audience);
+ g_value_set_boxed (value, &audience);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
/**
+ * clutter_stage_set_perspectivex
+ * @stage: A #ClutterStage
+ * @perspective: A #ClutterPerspective
+ *
+ * Set the stage perspective.
+ **/
+void
+clutter_stage_set_perspectivex (ClutterStage *stage,
+ ClutterPerspective *perspective)
+{
+ ClutterStagePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_STAGE (stage));
+
+ priv = stage->priv;
+ priv->perspective.fovy = perspective->fovy;
+ priv->perspective.aspect = perspective->aspect;
+ priv->perspective.z_near = perspective->z_near;
+ priv->perspective.z_far = perspective->z_far;
+
+ CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
+}
+
+/**
+ * clutter_stage_get_perspectivex
+ * @stage: A #ClutterStage
+ * @perspective: return location for a #ClutterPerspective
+ *
+ * Retrieves the stage perspective.
+ */
+void
+clutter_stage_get_perspectivex (ClutterStage *stage,
+ ClutterPerspective *perspective)
+{
+ ClutterStagePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_STAGE (stage));
+
+ priv = stage->priv;
+ perspective->fovy = priv->perspective.fovy;
+ perspective->aspect = priv->perspective.aspect;
+ perspective->z_near = priv->perspective.z_near;
+ perspective->z_far = priv->perspective.z_far;
+}
+
+/**
+ * clutter_stage_set_perspective
+ * @stage: A #ClutterStage
+ * FIXME
+ *
+ * Set the stage perspective.
+ **/
+void
+clutter_stage_set_perspective (ClutterStage *stage,
+ gfloat fovy,
+ gfloat aspect,
+ gfloat z_near,
+ gfloat z_far)
+{
+ ClutterStagePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_STAGE (stage));
+
+ priv = stage->priv;
+ priv->perspective.fovy = CLUTTER_DEGF_TO_CLUTTER_ANGLE(fovy);
+ priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED(aspect);
+ priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED(z_near);
+ priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED(z_far);
+
+ CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
+}
+
+/**
+ * clutter_stage_get_perspective
+ * @stage: A #ClutterStage
+ * @perspective: return location for a #ClutterPerspective
+ *
+ * Retrieves the stage perspective.
+ */
+void
+clutter_stage_get_perspective (ClutterStage *stage,
+ gfloat *fovy,
+ gfloat *aspect,
+ gfloat *z_near,
+ gfloat *z_far)
+{
+ ClutterStagePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_STAGE (stage));
+
+ priv = stage->priv;
+ *fovy = CLUTTER_ANGLE_TO_DEGF(priv->perspective.fovy);
+ *aspect = CLUTTER_FIXED_TO_FLOAT(priv->perspective.aspect);
+ *z_near = CLUTTER_FIXED_TO_FLOAT(priv->perspective.z_near);
+ *z_far = CLUTTER_FIXED_TO_FLOAT(priv->perspective.z_far);
+}
+
+
+void
+clutter_stage_set_audience (ClutterStage *stage,
+ ClutterAudience *audience)
+{
+
+}
+
+void
+clutter_stage_get_audience (ClutterStage *stage,
+ ClutterAudience *audience)
+{
+
+}
+
+/**
* clutter_stage_fullscreen:
* @stage: a #ClutterStage
*
return NULL;
}
-void
-_clutter_stage_sync_viewport (ClutterStage *stage)
-{
- /* FIXME:
- * Something needs to be done with this func, apps may need to
- * overide it and its need better integration into the backend.
- */
- ClutterActor *actor;
- gint width, height;
-
- g_return_if_fail (CLUTTER_IS_STAGE (stage));
-
- actor = CLUTTER_ACTOR (stage);
-
- width = clutter_actor_get_width (actor);
- height = clutter_actor_get_height (actor);
-
- cogl_setup_viewport (width,
- height,
- 171, /* 60 degrees */
- CFX_ONE,
- CLUTTER_FLOAT_TO_FIXED (0.1),
- CLUTTER_FLOAT_TO_FIXED (100.0));
-}
-
/**
* clutter_stage_get_actor_at_pos:
* @stage:
GLuint buff[64] = { 0 };
GLint hits;
GLint view[4];
+ ClutterMainContext *ctx;
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
+ ctx = clutter_context_get_default ();
+
glSelectBuffer (sizeof (buff), buff);
glGetIntegerv (GL_VIEWPORT, view);
glRenderMode (GL_SELECT);
if (hits != 0)
{
-#if 0
- gint i
+#if 1
+ gint i;
for (i = 0; i < hits; i++)
- g_print ("Hit at %i\n", buff[i * 4 + 3]);
+ g_print ("Hit at %i\n", buff[(hits-1) * 4 + 3]);
#endif
found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage),
buff[(hits-1) * 4 + 3]);
}
- _clutter_stage_sync_viewport (stage);
+ CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
return found;
#else
*
* Return value: an allocated copy of @perspective.
*
- * Since: 0.2
+ * Since: 0.4
*/
ClutterPerspective *
clutter_perspective_copy (const ClutterPerspective *perspective)
(GBoxedFreeFunc) clutter_perspective_free);
return our_type;
}
+
+/*** Audience boxed type ******/
+
+/**
+ * clutter_audience_copy:
+ * @audience: a #ClutterAudience
+ *
+ * Makes a copy of the audience structure. The result must be
+ * freed using clutter_audience_free().
+ *
+ * Return value: an allocated copy of @audience.
+ *
+ * Since: 0.4
+ */
+ClutterAudience *
+clutter_audience_copy (const ClutterAudience *audience)
+{
+ ClutterAudience *result;
+
+ g_return_val_if_fail (audience != NULL, NULL);
+
+ result = g_slice_new (ClutterAudience);
+ *result = *audience;
+
+ return result;
+}
+
+/**
+ * clutter_audience_free:
+ * @audience: a #ClutterAudience
+ *
+ * Frees a audience structure created with clutter_audience_copy().
+ *
+ * Since: 0.4
+ */
+void
+clutter_audience_free (ClutterAudience *audience)
+{
+ g_return_if_fail (audience != NULL);
+
+ g_slice_free (ClutterAudience, audience);
+}
+
+GType
+clutter_audience_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (!our_type)
+ our_type = g_boxed_type_register_static
+ ("ClutterAudience",
+ (GBoxedCopyFunc) clutter_audience_copy,
+ (GBoxedFreeFunc) clutter_audience_free);
+ return our_type;
+}
{
ClutterFixed fovy;
ClutterFixed aspect;
- ClutterFixed zNear;
- ClutterFixed zFar;
+ ClutterFixed z_near;
+ ClutterFixed z_far;
+};
+
+#define CLUTTER_TYPE_AUDIENCE (clutter_audience_get_type ())
+
+typedef struct _ClutterAudience ClutterAudience;
+
+struct _ClutterAudience
+{
};
GType clutter_perspective_get_type (void) G_GNUC_CONST;
ClutterPerspective *clutter_perspective_copy (const ClutterPerspective *perspective);
void clutter_perspective_free (ClutterPerspective *perspective);
-
+GType clutter_audience_get_type (void) G_GNUC_CONST;
+ClutterAudience *clutter_audience_copy (const ClutterAudience *audience);
+void clutter_audience_free (ClutterAudience *audience);
GType clutter_stage_get_type (void) G_GNUC_CONST;
const ClutterColor *color);
void clutter_stage_get_color (ClutterStage *stage,
ClutterColor *color);
+void clutter_stage_set_perspectivex (ClutterStage *stage,
+ ClutterPerspective *perspective);
+void clutter_stage_get_perspectivex (ClutterStage *stage,
+ ClutterPerspective *perspective);
+void clutter_stage_set_perspective (ClutterStage *stage,
+ gfloat fovy,
+ gfloat aspect,
+ gfloat z_near,
+ gfloat z_far);
+void clutter_stage_get_perspective (ClutterStage *stage,
+ gfloat *fovy,
+ gfloat *aspect,
+ gfloat *z_near,
+ gfloat *z_far);
+void clutter_stage_set_audience (ClutterStage *stage,
+ ClutterAudience *audience);
+void clutter_stage_get_audience (ClutterStage *stage,
+ ClutterAudience *audience);
void clutter_stage_fullscreen (ClutterStage *stage);
void clutter_stage_unfullscreen (ClutterStage *stage);
void clutter_stage_show_cursor (ClutterStage *stage);
* #ClutterTexture is a base class for displaying and manipulating pixel
* buffer type data.
*
- * The #clutter_texture_set_from_data and #clutter_texture_set_pixbuf are
+ * The #clutter_texture_set_from_rgb_data and #clutter_texture_set_pixbuf are
* used to copy image data into texture memory and subsequently realize the
- * the texture. Unrealizing/hiding frees image data from texture memory moving
- * to main system memory. Re-realizing then performs the opposite operation.
- * This process allows basic management of commonly limited available texture
+ * the texture.
+ *
+ * If texture reads are supported by underlying GL implementaion
+ * Unrealizing/hiding frees image data from texture memory moving to main
+ * system memory. Re-realizing then performs the opposite operation.
+ * This process allows basic management of commonly limited available texture
* memory.
*/
/* Move any local image data we have from unrealization
* back into video memory.
*/
- clutter_texture_set_pixbuf (texture, priv->local_pixbuf);
+ clutter_texture_set_pixbuf (texture, priv->local_pixbuf, NULL);
g_object_unref (priv->local_pixbuf);
priv->local_pixbuf = NULL;
}
{
case PROP_PIXBUF:
clutter_texture_set_pixbuf (texture,
- (GdkPixbuf*)g_value_get_pointer(value));
+ (GdkPixbuf*)g_value_get_pointer(value),
+ NULL);
break;
case PROP_USE_TILES:
priv->is_tiled = g_value_get_boolean (value);
case PROP_MAX_TILE_WASTE:
priv->max_tile_waste = g_value_get_int (value);
break;
- case PROP_PIXEL_TYPE:
- priv->pixel_type = g_value_get_int (value);
- break;
- case PROP_PIXEL_FORMAT:
- priv->pixel_format = g_value_get_int (value);
- break;
case PROP_SYNC_SIZE:
priv->sync_actor_size = g_value_get_boolean (value);
break;
0,
G_MAXINT,
PIXEL_TYPE,
- G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
+ G_PARAM_READABLE));
g_object_class_install_property
(gobject_class, PROP_PIXEL_FORMAT,
0,
G_MAXINT,
CGL_RGBA,
- G_PARAM_CONSTRUCT_ONLY | CLUTTER_PARAM_READWRITE));
+ G_PARAM_READABLE));
/**
* ClutterTexture::size-change:
GdkPixbuf*
clutter_texture_get_pixbuf (ClutterTexture* texture)
{
-#if CLUTTER_COGL_GL
+#if HAVE_COGL_GL
ClutterTexturePrivate *priv;
GdkPixbuf *pixbuf = NULL;
guchar *pixels = NULL;
}
/**
- * clutter_texture_set_from_data:
+ * clutter_texture_set_from_rgb_data:
* @texture: A #ClutterTexture
* @data: Image data in RGB type colorspace.
* @has_alpha: Set to TRUE if image data has a alpha channel.
* @height: Height in pixels of image data
* @rowstride: Distance in bytes between row starts.
* @bpp: bytes per pixel ( Currently only 4 supported )
+ * @flags: #ClutterTextureFlags
+ * @error: FIXME.
*
* Sets #ClutterTexture image data.
*
- * Since 0.2. This function is likely to change in future versions.
+ * Return value: TRUE on success, FALSE on failure.
+ *
+ * Since 0.4. This function is likely to change in future versions.
**/
-void
-clutter_texture_set_from_data (ClutterTexture *texture,
- const guchar *data,
- gboolean has_alpha,
- gint width,
- gint height,
- gint rowstride,
- gint bpp)
+gboolean
+clutter_texture_set_from_rgb_data (ClutterTexture *texture,
+ const guchar *data,
+ gboolean has_alpha,
+ gint width,
+ gint height,
+ gint rowstride,
+ gint bpp,
+ ClutterTextureFlags flags,
+ GError *error)
{
ClutterTexturePrivate *priv;
gboolean texture_dirty = TRUE;
+ COGLenum prev_format;
priv = texture->priv;
- g_return_if_fail (data != NULL);
- g_return_if_fail (bpp == 4);
-
- /* FIXME: check other image props */
+ g_return_val_if_fail (data != NULL, FALSE);
+ /* Needed for GL_RGBA (internal format) and gdk pixbuf usage */
+ g_return_val_if_fail (bpp == 4, FALSE);
+
texture_dirty = (width != priv->width || height != priv->height);
- priv->width = width;
- priv->height = height;
-
+ prev_format = priv->pixel_format;
+
if (has_alpha)
priv->pixel_format = CGL_RGBA;
else
priv->pixel_format = CGL_RGB;
+ if (flags & CLUTTER_TEXTURE_RGB_FLAG_BGR)
+ {
+ if (has_alpha)
+ priv->pixel_format = CGL_BGRA;
+ else
+ priv->pixel_format = CGL_BGR;
+ }
+
+ if (prev_format != priv->pixel_format || priv->pixel_type != PIXEL_TYPE)
+ texture_dirty = TRUE;
+
+ priv->pixel_type = PIXEL_TYPE;
+ priv->width = width;
+ priv->height = height;
+
if (texture_dirty)
{
texture_free_gl_resources (texture);
priv->width,
priv->height);
- texture_upload_data (texture, data, has_alpha,
- width, height, rowstride, bpp);
+ /* Set Error from this */
+ texture_upload_data (texture,
+ data,
+ has_alpha,
+ width,
+ height,
+ rowstride,
+ bpp);
CLUTTER_ACTOR_SET_FLAGS (CLUTTER_ACTOR (texture), CLUTTER_ACTOR_REALIZED);
if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR(texture)))
clutter_actor_queue_redraw (CLUTTER_ACTOR(texture));
+ return TRUE;
+}
+
+/**
+ * clutter_texture_set_from_yuv_data:
+ * @texture: A #ClutterTexture
+ * @data: Image data in RGB type colorspace.
+ * @width: Width in pixels of image data.
+ * @height: Height in pixels of image data
+ * @flags: #ClutterTextureFlags
+ * @error: FIXME.
+ *
+ * Sets a #ClutterTexture from YUV image data.
+ *
+ * Return value: TRUE on success, FALSE on failure.
+ *
+ * Since 0.4. This function is likely to change in future versions.
+ **/
+gboolean
+clutter_texture_set_from_yuv_data (ClutterTexture *texture,
+ const guchar *data,
+ gint width,
+ gint height,
+ ClutterTextureFlags flags,
+ GError *error)
+{
+#if 0
+ gboolean texture_dirty = TRUE;
+ COGLenum prev_format;
+
+ if (!clutter_feature_available(CLUTTER_FEATURE_TEXTURE_YUV))
+ return FALSE;
+
+ priv = texture->priv;
+
+ /* FIXME: check other image props */
+ texture_dirty = (width != priv->width || height != priv->height);
+
+ priv->width = width;
+ priv->height = height;
+
+ /* #ifdef GL_YCBCR_MESA */
+ priv->pixel_format = CGL_YCBCR_MESA;
+
+ if (!priv->tiles)
+ {
+ priv->tiles = g_new (guint, 1);
+ glGenTextures (1, priv->tiles);
+ }
+
+ cogl_texture_bind (priv->target_type, priv->tiles[0]);
+
+ cogl_texture_set_filters (priv->target_type,
+ priv->filter_quality ? CGL_LINEAR : CGL_NEAREST,
+ priv->filter_quality ? CGL_LINEAR : CGL_NEAREST);
+
+ if (texture_dirty)
+ {
+ if (cogl_texture_can_size(priv->pixel_format,
+ priv->pixel_type,
+ clutter_util_next_p2(priv->width),
+ clutter_util_next_p2(priv->height)))
+ {
+ glTexImage2D (CGL_TEXTURE_2D,
+ 0,
+ GL_YCBCR_MESA,
+ clutter_util_next_p2(priv->width),
+ clutter_util_next_p2(priv->height),
+ 0,
+ GL_YCBCR_MESA,
+ GL_UNSIGNED_SHORT_8_8_REV_MESA,
+ NULL);
+ }
+ else
+ /* No tiled support for YUV textures as yet */
+ return FALSE; /* Set Error */
+ }
+
+ if (flags & CLUTTER_TEXTURE_YUV_FLAG_YUV2)
+ {
+ glTexSubImage2D (GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ priv->width,
+ priv->height
+ CGL_YCBCR_MESA,
+ CGL_UNSIGNED_SHORT_8_8_REV_MESA,
+ data);
+ }
+ else
+ {
+ glTexSubImage2D (GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ priv->width,
+ priv->height
+ CGL_YCBCR_MESA,
+ CGL_UNSIGNED_SHORT_8_8_MESA,
+ data);
+ }
+#endif
+ return FALSE;
}
/**
* Sets a #ClutterTexture image data from a #GdkPixbuf
*
**/
-void
+gboolean
clutter_texture_set_pixbuf (ClutterTexture *texture,
- GdkPixbuf *pixbuf)
+ GdkPixbuf *pixbuf,
+ GError *error)
{
ClutterTexturePrivate *priv;
priv = texture->priv;
- g_return_if_fail (pixbuf != NULL);
-
- clutter_texture_set_from_data (texture,
- gdk_pixbuf_get_pixels (pixbuf),
- gdk_pixbuf_get_has_alpha (pixbuf),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- gdk_pixbuf_get_rowstride (pixbuf),
- 4);
+ g_return_val_if_fail (pixbuf != NULL, FALSE);
+
+ return clutter_texture_set_from_rgb_data (texture,
+ gdk_pixbuf_get_pixels (pixbuf),
+ gdk_pixbuf_get_has_alpha (pixbuf),
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf),
+ gdk_pixbuf_get_rowstride (pixbuf),
+ 4,
+ 0,
+ error);
}
/**
G_BEGIN_DECLS
-#if 0
-
-/* New API Ideas */
-
-#define CLUTTER_TEXTURE_RGB_FLAG_BRGA (1<<1)
-#define CLUTTER_TEXTURE_RGB_FLAG_PREMULT (1<<2)
-
-gboolean
-clutter_texture_set_from_rgb_data (ClutterTexture *texture,
- const guchar *data,
- gboolean has_alpha,
- gint width,
- gint height,
- gint rowstride,
- gint bpp,
- gint flags,
- GError *error);
-
-gboolean
-clutter_texture_set_from_yuv_data (ClutterTexture *texture,
- const guchar *data,
- gint width,
- gint height,
- gint flags,
- GError *error);
-
-Notes
-=====
-
- - drop format and type props - would be set in GL texture automagically
- via about calls.
-
-#endif
-
#define CLUTTER_TYPE_TEXTURE (clutter_texture_get_type ())
#define CLUTTER_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXTURE, ClutterTexture))
#define CLUTTER_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_TEXTURE, ClutterTextureClass))
void (*_clutter_texture6) (void);
};
+typedef enum ClutterTextureFlags
+{
+ CLUTTER_TEXTURE_RGB_FLAG_BGR = (1<<1),
+ CLUTTER_TEXTURE_RGB_FLAG_PREMULT = (1<<2),
+ CLUTTER_TEXTURE_YUV_FLAG_YUV2 = (1<<3)
+ /* FIXME: add compressed types ? */
+} ClutterTextureFlags;
+
GType clutter_texture_get_type (void) G_GNUC_CONST;
ClutterActor *clutter_texture_new (void);
ClutterActor *clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf);
-void clutter_texture_set_from_data (ClutterTexture *texture,
- const guchar *data,
- gboolean has_alpha,
- gint width,
- gint height,
- gint rowstride,
- gint bpp);
-void clutter_texture_set_pixbuf (ClutterTexture *texture,
- GdkPixbuf *pixbuf);
+gboolean clutter_texture_set_from_rgb_data (ClutterTexture *texture,
+ const guchar *data,
+ gboolean has_alpha,
+ gint width,
+ gint height,
+ gint rowstride,
+ gint bpp,
+ ClutterTextureFlags flags,
+ GError *error);
+gboolean clutter_texture_set_from_yuv_data (ClutterTexture *texture,
+ const guchar *data,
+ gint width,
+ gint height,
+ ClutterTextureFlags flags,
+ GError *error);
+gboolean clutter_texture_set_pixbuf (ClutterTexture *texture,
+ GdkPixbuf *pixbuf,
+ GError *error);
GdkPixbuf * clutter_texture_get_pixbuf (ClutterTexture *texture);
void clutter_texture_get_base_size (ClutterTexture *texture,
gint *width,
}
if (priv->loop)
- clutter_timeline_rewind (timeline);
+ {
+ clutter_timeline_rewind (timeline);
+ g_signal_emit (timeline, timeline_signals[COMPLETED], 0);
+ }
else
{
clutter_timeline_stop (timeline);
#include <GL/gl.h>
#include <string.h>
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define PIXEL_TYPE GL_UNSIGNED_BYTE
-#else
-#define PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
-#endif
-
static gulong __enable_flags = 0;
#if COGL_DEBUG
return FALSE;
}
+#if 0
static gboolean
is_gl_version_at_least_12 (void)
{
return
(g_ascii_strtod ((const gchar*) glGetString (GL_VERSION), NULL) >= 1.2);
-#if 0
+
/* At least GL 1.2 is needed for CLAMP_TO_EDGE */
/* FIXME: move to cogl... */
if (!is_gl_version_at_least_12 ())
"Clutter needs at least version 1.2 of OpenGL");
return FALSE;
}
-#endif
}
+#endif
CoglFuncPtr
cogl_get_proc_address (const gchar* name)
{
/* FIXME */
+ return NULL;
}
gboolean
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
-
if (check_gl_extension ("GL_ARB_texture_rectangle", gl_extensions) ||
check_gl_extension ("GL_EXT_texture_rectangle", gl_extensions))
{
flags |= CLUTTER_FEATURE_TEXTURE_RECTANGLE;
}
+
+#ifdef GL_YCBCR_MESA
+ if (check_gl_extension ("GL_MESA_ycbcr_texture", gl_extensions))
+ {
+ flags |= CLUTTER_FEATURE_TEXTURE_YUV;
+ }
+#endif
+
+#if 0
+ CLUTTER_NOTE (GL,
+ "\n"
+ "===========================================\n"
+ "GL_VENDOR: %s\n"
+ "GL_RENDERER: %s\n"
+ "GL_VERSION: %s\n"
+ "GL_EXTENSIONS: %s\n"
+ "===========================================\n",
+ glGetString (GL_VENDOR),
+ glGetString (GL_RENDERER),
+ glGetString (GL_VERSION),
+ glGetString (GL_EXTENSIONS),
+ : "no");
+#endif
return flags;
}
if (clutter_display_name)
{
- CLUTTER_NOTE (MISC, "XOpenDisplay on `%s'", clutter_display_name);
+ CLUTTER_NOTE (BACKEND, "XOpenDisplay on `%s'", clutter_display_name);
backend_glx->xdpy = XOpenDisplay (clutter_display_name);
}
else
if (backend_glx->xdpy)
{
- CLUTTER_NOTE (MISC, "Getting the X screen");
+ int glx_major, glx_minor;
+
+ CLUTTER_NOTE (BACKEND, "Getting the X screen");
if (clutter_screen == 0)
backend_glx->xscreen = DefaultScreenOfDisplay (backend_glx->xdpy);
backend_glx->display_name = g_strdup (clutter_display_name);
+ CLUTTER_NOTE (BACKEND, "Checking GLX info");
+
+ if (!glXQueryVersion (backend_glx->xdpy, &glx_major, &glx_minor)
+ || !(glx_major > 1 || glx_minor > 1))
+ {
+ g_set_error (error, CLUTTER_INIT_ERROR,
+ CLUTTER_INIT_ERROR_BACKEND,
+ "XServer appears to lack required GLX support");
+ return 1;
+ }
+
+#if 0
+ /* Prefer current GLX specs over current violations */
+ if (!(glx_major > 1 || glx_minor > 2))
+ {
+
+ const char* exts = glXQueryExtensionsString (display, screen);
+ if (!exts || !strstr (exts, "GLX_SGIX_fbconfig"))
+ have_fbconfig = 0;
+ }
+#endif
+
}
g_free (clutter_display_name);
else
{
int gl_attributes[] = {
- GLX_RGBA,
+ GLX_DEPTH_SIZE, 0,
+ GLX_ALPHA_SIZE, 0,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
+ GLX_USE_GL,
+ GLX_RGBA,
0
};
if (!stage_glx->xvisinfo)
{
g_critical ("Unable to find suitable GL visual.");
-
- CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
-
- return;
+ goto fail;
}
if (stage_glx->gl_context)
stage_glx->xwin_root,
stage_glx->xwin_width,
stage_glx->xwin_height,
- stage_glx->xvisinfo->depth);
+ DefaultDepth (stage_glx->xdpy,
+ stage_glx->xscreen));
stage_glx->glxpixmap = glXCreateGLXPixmap (stage_glx->xdpy,
stage_glx->xvisinfo,
stage_glx->xvisinfo,
0,
False);
-
+
+ clutter_glx_trap_x_errors ();
+
glXMakeCurrent (stage_glx->xdpy,
stage_glx->glxpixmap,
stage_glx->gl_context);
+ if (clutter_glx_untrap_x_errors ())
+ {
+ g_critical ("Unable to set up offscreen context.");
+ goto fail;
+ }
+
#if 0
/* Debug code for monitoring a off screen pixmap via window */
{
XMapWindow(clutter_glx_display(), foo_win);
}
#endif
+
}
- CLUTTER_NOTE (GL,
- "\n"
- "===========================================\n"
- "GL_VENDOR: %s\n"
- "GL_RENDERER: %s\n"
- "GL_VERSION: %s\n"
- "GL_EXTENSIONS: %s\n"
- "Direct Rendering: %s\n"
- "===========================================\n",
- glGetString (GL_VENDOR),
- glGetString (GL_RENDERER),
- glGetString (GL_VERSION),
- glGetString (GL_EXTENSIONS),
- glXIsDirect (stage_glx->xdpy, stage_glx->gl_context) ? "yes"
- : "no");
-
- _clutter_stage_sync_viewport (CLUTTER_STAGE (stage_glx));
+ CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
+
+ return;
+
+ fail:
+
+ /* For one reason or another we cant realize the stage.. */
+ CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
+ return;
}
static void
/* Reset view matrices if needed. */
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_SYNC_MATRICES)
{
- /*
- cogl_set_view_matrix (view_width,
- view_height,
- perspective)
-
- */
+ cogl_setup_viewport (clutter_actor_get_width (self),
+ clutter_actor_get_height (self),
+ 171, /* 60 degrees */
+ CFX_ONE,
+ CLUTTER_FLOAT_TO_FIXED (0.1),
+ CLUTTER_FLOAT_TO_FIXED (100.0));
}
/* Setup the initial paint */
clutter_actor_realize (self);
}
- _clutter_stage_sync_viewport (CLUTTER_STAGE (stage_glx));
+ CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
}
if (stage_glx->xwin != None) /* Do we want to bother ? */
XDeleteProperty (stage_glx->xdpy, stage_glx->xwin, atom_WM_STATE);
}
- _clutter_stage_sync_viewport (stage);
+ CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
}
static void
XDefineCursor (stage_glx->xdpy, stage_glx->xwin, curs);
#endif /* HAVE_XFIXES */
}
-
- _clutter_stage_sync_viewport (stage);
}
static void
stage->xvisinfo = None;
stage->is_foreign_xwin = FALSE;
+
+ CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
}
/**
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
AM_CFLAGS = $(CLUTTER_CFLAGS)
-LDFLAGS = $(CLUTTER_LIBS)
+AM_LDFLAGS = $(CLUTTER_LIBS)
slider_SOURCES = slider.c
-noinst_PROGRAMS = test-textures test-events
+noinst_PROGRAMS = test-textures test-events test-offscreen test-scale
INCLUDES = -I$(top_srcdir)/
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
AM_CFLAGS = $(CLUTTER_CFLAGS)
-LDFLAGS = $(CLUTTER_LIBS)
+AM_LDFLAGS = $(CLUTTER_LIBS)
-test_textures_SOURCES = test-textures.c
-
-test_events_SOURCES = test-events.c
+test_textures_SOURCES = test-textures.c
+test_events_SOURCES = test-events.c
+test_offscreen_SOURCES = test-offscreen.c
+test_scale_SOURCES = test-scale.c
--- /dev/null
+#include <clutter/clutter.h>
+
+/* Very simple test just to see what happens setting up offscreen rendering */
+
+int
+main (int argc, char *argv[])
+{
+ ClutterActor *stage;
+ gboolean offscreen;
+
+ clutter_init (&argc, &argv);
+
+ stage = clutter_stage_get_default ();
+
+ /* Attempt to set up rendering offscreen */
+ g_object_set (stage, "offscreen", TRUE, NULL);
+
+ /* See if it worked */
+ g_object_get (stage, "offscreen", &offscreen, NULL);
+
+ if (offscreen == FALSE)
+ printf ("FAIL: Unable to setup offscreen rendering\n.");
+ else
+ printf ("SUCCESS: Able to setup offscreen rendering\n.");
+
+ clutter_actor_show_all (CLUTTER_ACTOR (stage));
+
+ clutter_main();
+
+ return 0;
+}
--- /dev/null
+#include <clutter/clutter.h>
+
+ClutterGravity gravitys[] = {
+ CLUTTER_GRAVITY_NORTH_EAST,
+ CLUTTER_GRAVITY_NORTH,
+ CLUTTER_GRAVITY_NORTH_WEST,
+ CLUTTER_GRAVITY_WEST,
+ CLUTTER_GRAVITY_SOUTH_WEST,
+ CLUTTER_GRAVITY_SOUTH,
+ CLUTTER_GRAVITY_SOUTH_EAST,
+ CLUTTER_GRAVITY_EAST,
+ CLUTTER_GRAVITY_CENTER,
+ CLUTTER_GRAVITY_NONE
+};
+
+gint gindex = 0;
+
+void
+on_timeline_completed (ClutterTimeline *cluttertimeline,
+ gpointer data)
+{
+ ClutterBehaviourScale *behave = CLUTTER_BEHAVIOUR_SCALE(data);
+
+ if (++gindex > G_N_ELEMENTS(gravitys))
+ gindex = 0;
+
+ g_object_set (behave, "scale-gravity", gravitys[gindex], NULL);
+}
+
+int
+main (int argc, char *argv[])
+{
+ ClutterActor *stage, *rect;
+ ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
+ ClutterColor rect_color = { 0xff, 0xff, 0xff, 0x99 };
+ ClutterTimeline *timeline;
+ ClutterAlpha *alpha;
+ ClutterBehaviour *behave;
+
+ clutter_init (&argc, &argv);
+
+ stage = clutter_stage_get_default ();
+
+ clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
+ clutter_actor_set_size (stage, 300, 300);
+
+ rect = clutter_rectangle_new_with_color(&rect_color);
+ clutter_actor_set_size (rect, 100, 100);
+ clutter_actor_set_position (rect, 100, 100);
+
+ clutter_group_add (CLUTTER_GROUP(stage), rect);
+
+ rect_color.alpha = 0xff;
+ rect = clutter_rectangle_new_with_color(&rect_color);
+ clutter_actor_set_size (rect, 100, 100);
+ clutter_actor_set_position (rect, 100, 100);
+
+ clutter_group_add (CLUTTER_GROUP(stage), rect);
+
+ timeline = clutter_timeline_new (20, 30);
+ alpha = clutter_alpha_new_full (timeline,
+ CLUTTER_ALPHA_RAMP,
+ NULL, NULL);
+
+ behave = clutter_behaviour_scale_new (alpha,
+ 0.0,
+ 1.0,
+ gravitys[gindex]);
+
+ clutter_behaviour_apply (behave, rect);
+
+ clutter_timeline_set_loop (timeline, TRUE);
+ g_signal_connect (timeline, "completed",
+ G_CALLBACK(on_timeline_completed), behave);
+ clutter_timeline_start (timeline);
+
+ clutter_actor_show_all (stage);
+
+ clutter_main();
+}