#include "clutter-scriptable.h"
#include "clutter-debug.h"
#include "clutter-fixed.h"
+#include "clutter-enum-types.h"
#include "cogl/cogl.h"
gint height;
guint sync_actor_size : 1;
gint max_tile_waste;
- guint filter_quality;
+ ClutterTextureQuality filter_quality;
guint repeat_x : 1;
guint repeat_y : 1;
CoglHandle texture;
return g_quark_from_static_string ("clutter-texture-error-quark");
}
+static COGLenum
+clutter_texture_quality_to_cogl_min_filter (ClutterTextureQuality buf_filter)
+{
+ switch (buf_filter)
+ {
+ case CLUTTER_TEXTURE_QUALITY_LOW:
+ return CGL_NEAREST;
+ case CLUTTER_TEXTURE_QUALITY_MEDIUM:
+ return CGL_LINEAR;
+ case CLUTTER_TEXTURE_QUALITY_HIGH:
+ return CGL_LINEAR_MIPMAP_LINEAR;
+ }
+ return 0;
+}
+
+static COGLenum
+clutter_texture_quality_to_cogl_mag_filter (ClutterTextureQuality buf_filter)
+{
+ switch (buf_filter)
+ {
+ case CLUTTER_TEXTURE_QUALITY_LOW:
+ return CGL_NEAREST;
+ case CLUTTER_TEXTURE_QUALITY_MEDIUM:
+ case CLUTTER_TEXTURE_QUALITY_HIGH:
+ return CGL_LINEAR;
+ }
+ return 0;
+}
+
+static ClutterTextureQuality
+cogl_filters_to_clutter_texture_quality (COGLenum min,
+ COGLenum mag)
+{
+ switch (min)
+ {
+ case CGL_NEAREST:
+ g_assert (mag == min); /* just for sanity */
+ return CLUTTER_TEXTURE_QUALITY_LOW;
+ case CGL_LINEAR:
+ g_assert (mag == min); /* just for sanity */
+ return CLUTTER_TEXTURE_QUALITY_MEDIUM;
+ case CGL_LINEAR_MIPMAP_LINEAR:
+ g_assert (mag == CGL_LINEAR); /* just for sanity */
+ return CLUTTER_TEXTURE_QUALITY_HIGH;
+ }
+ return 0;
+}
+
static void
texture_free_gl_resources (ClutterTexture *texture)
{
(priv->width,
priv->height,
priv->no_slice ? -1 : priv->max_tile_waste,
- FALSE,
+ priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH,
COGL_PIXEL_FORMAT_RGBA_8888);
cogl_texture_set_filters (priv->texture,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST);
+ clutter_texture_quality_to_cogl_min_filter (priv->filter_quality),
+ clutter_texture_quality_to_cogl_mag_filter (priv->filter_quality));
priv->fbo_handle = cogl_offscreen_new_to_texture (priv->texture);
break;
case PROP_FILTER_QUALITY:
clutter_texture_set_filter_quality (texture,
- g_value_get_int (value));
+ g_value_get_enum (value));
break;
case PROP_COGL_TEXTURE:
clutter_texture_set_cogl_texture
g_value_set_boolean (value, priv->repeat_y);
break;
case PROP_FILTER_QUALITY:
- g_value_set_int (value, clutter_texture_get_filter_quality (texture));
+ g_value_set_enum (value, clutter_texture_get_filter_quality (texture));
break;
case PROP_COGL_TEXTURE:
g_value_set_boxed (value, clutter_texture_get_cogl_texture (texture));
*/
g_object_class_install_property
(gobject_class, PROP_FILTER_QUALITY,
- g_param_spec_int ("filter-quality",
- "Quality of filter used when scaling a texture",
- "Values 0 and 1 current only supported, with 0 "
- "being lower quality but fast, 1 being better "
- "quality but slower. ( Currently just maps to "
- "GL_NEAREST / GL_LINEAR )",
- 0,
- G_MAXINT,
- 1,
- CLUTTER_PARAM_READWRITE));
+ g_param_spec_enum ("filter-quality",
+ "Filter Quality",
+ "Rendering quality used when drawing the texture.",
+ CLUTTER_TYPE_TEXTURE_QUALITY,
+ CLUTTER_TEXTURE_QUALITY_MEDIUM,
+ G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_MAX_TILE_WASTE,
self->priv = priv = CLUTTER_TEXTURE_GET_PRIVATE (self);
priv->max_tile_waste = 64;
- priv->filter_quality = 1;
+ priv->filter_quality = CLUTTER_TEXTURE_QUALITY_MEDIUM;
priv->repeat_x = FALSE;
priv->repeat_y = FALSE;
priv->sync_actor_size = TRUE;
priv = texture->priv;
if ((new_texture = cogl_texture_new_from_data
- (width, height,
- priv->no_slice ? -1 : priv->max_tile_waste,
- FALSE,
- source_format,
- COGL_PIXEL_FORMAT_ANY,
- rowstride,
- data)) == COGL_INVALID_HANDLE)
+ (width, height,
+ priv->no_slice ? -1 : priv->max_tile_waste,
+ priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH,
+ source_format,
+ COGL_PIXEL_FORMAT_ANY,
+ rowstride,
+ data)) == COGL_INVALID_HANDLE)
{
g_set_error (error, CLUTTER_TEXTURE_ERROR,
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
}
cogl_texture_set_filters (new_texture,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST);
+ clutter_texture_quality_to_cogl_min_filter (priv->filter_quality),
+ clutter_texture_quality_to_cogl_mag_filter (priv->filter_quality));
clutter_texture_set_cogl_texture (texture, new_texture);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if ((new_texture = cogl_texture_new_from_file
- (filename,
- priv->no_slice ? -1 : priv->max_tile_waste,
- FALSE,
- COGL_PIXEL_FORMAT_ANY,
- error))
+ (filename,
+ priv->no_slice ? -1 : priv->max_tile_waste,
+ priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH,
+ COGL_PIXEL_FORMAT_ANY,
+ error))
== COGL_INVALID_HANDLE)
{
/* If COGL didn't give an error then make one up */
}
cogl_texture_set_filters (new_texture,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST);
+ clutter_texture_quality_to_cogl_min_filter (priv->filter_quality),
+ clutter_texture_quality_to_cogl_mag_filter (priv->filter_quality));
clutter_texture_set_cogl_texture (texture, new_texture);
* Since: 0.8
*/
void
-clutter_texture_set_filter_quality (ClutterTexture *texture,
- guint filter_quality)
+clutter_texture_set_filter_quality (ClutterTexture *texture,
+ ClutterTextureQuality filter_quality)
{
ClutterTexturePrivate *priv;
+ ClutterTextureQuality old_quality;
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
priv = texture->priv;
- if (filter_quality != clutter_texture_get_filter_quality (texture))
+ old_quality = clutter_texture_get_filter_quality (texture);
+ if (filter_quality != old_quality)
{
priv->filter_quality = filter_quality;
if (priv->texture != COGL_INVALID_HANDLE)
cogl_texture_set_filters (priv->texture,
- filter_quality ? CGL_LINEAR : CGL_NEAREST,
- filter_quality ? CGL_LINEAR : CGL_NEAREST);
+ clutter_texture_quality_to_cogl_min_filter (priv->filter_quality),
+ clutter_texture_quality_to_cogl_mag_filter (priv->filter_quality));
+
+
+ if ((old_quality == CLUTTER_TEXTURE_QUALITY_HIGH ||
+ filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) &&
+ CLUTTER_ACTOR_IS_REALIZED (texture))
+ {
+ clutter_texture_unrealize (CLUTTER_ACTOR (texture));
+ clutter_texture_realize (CLUTTER_ACTOR (texture));
+ }
+
if (CLUTTER_ACTOR_IS_VISIBLE (texture))
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
*
* Since: 0.8
*/
-guint
+ClutterTextureQuality
clutter_texture_get_filter_quality (ClutterTexture *texture)
{
ClutterTexturePrivate *priv;
else
/* If we have a valid texture handle then use the filter quality
from that instead */
- return cogl_texture_get_min_filter (texture->priv->texture)
- == CGL_LINEAR ? 1 : 0;
+
+ return cogl_filters_to_clutter_texture_quality (
+ cogl_texture_get_min_filter (texture->priv->texture),
+ cogl_texture_get_mag_filter (texture->priv->texture));
}
/**
priv->texture = cogl_texture_new_with_size (priv->width,
priv->height,
-1,
- FALSE,
+ priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH,
COGL_PIXEL_FORMAT_RGBA_8888);
- cogl_texture_set_filters (priv->texture,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST,
- priv->filter_quality
- ? CGL_LINEAR : CGL_NEAREST);
+ cogl_texture_set_filters (priv->texture,
+ clutter_texture_quality_to_cogl_min_filter (priv->filter_quality),
+ clutter_texture_quality_to_cogl_mag_filter (priv->filter_quality));
priv->fbo_handle = cogl_offscreen_new_to_texture (priv->texture);
--- /dev/null
+#include <stdlib.h>
+#include <clutter/clutter.h>
+
+/* each time the timeline animating the label completes, swap the direction */
+static void
+timeline_completed (ClutterTimeline *timeline,
+ gpointer user_data)
+{
+ clutter_timeline_set_direction (timeline,
+ !clutter_timeline_get_direction (timeline));
+ clutter_timeline_start (timeline);
+}
+
+static gboolean
+change_filter (gpointer actor)
+{
+ ClutterTextureQuality old_quality;
+
+ old_quality = clutter_texture_get_filter_quality (actor);
+ switch (old_quality)
+ {
+ case CLUTTER_TEXTURE_QUALITY_LOW:
+ clutter_texture_set_filter_quality (actor,
+ CLUTTER_TEXTURE_QUALITY_MEDIUM);
+ g_print ("Setting texture rendering quality to medium\n");
+ break;
+ case CLUTTER_TEXTURE_QUALITY_MEDIUM:
+ clutter_texture_set_filter_quality (actor,
+ CLUTTER_TEXTURE_QUALITY_HIGH);
+ g_print ("Setting texture rendering quality to high\n");
+ break;
+ case CLUTTER_TEXTURE_QUALITY_HIGH:
+ clutter_texture_set_filter_quality (actor,
+ CLUTTER_TEXTURE_QUALITY_LOW);
+ g_print ("Setting texture rendering quality to low\n");
+ break;
+ }
+ return TRUE;
+}
+
+gint
+main (int argc, char *argv[])
+{
+ ClutterTimeline *timeline;
+ ClutterBehaviour *depth_behavior;
+ ClutterActor *stage;
+ ClutterActor *image;
+ ClutterColor stage_color = { 0x12, 0x34, 0x56, 0xff };
+ GError *error;
+
+ clutter_init (&argc, &argv);
+
+ stage = clutter_stage_get_default ();
+ clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
+ clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE);
+ clutter_stage_set_fog (CLUTTER_STAGE (stage), 1.0, 10, -50);
+
+ g_signal_connect (stage,
+ "button-press-event", G_CALLBACK (clutter_main_quit),
+ NULL);
+
+ error = NULL;
+ image = clutter_texture_new_from_file (argv[1]?argv[1]:"redhand.png", &error);
+ if (error)
+ g_error ("Unable to load image.", error->message);
+
+ if (!argv[1])
+ g_print ("Hint: the redhand.png isn't a good test image for this, this test can take any clutter loadable image as an argument\n");
+
+ /* center the image */
+ clutter_actor_set_position (image,
+ (clutter_actor_get_width (stage) - clutter_actor_get_width (image))/2,
+ (clutter_actor_get_height (stage) - clutter_actor_get_height (image))/2);
+ clutter_container_add (CLUTTER_CONTAINER (stage), image, NULL);
+
+ timeline = clutter_timeline_new (60*5, 60);
+ g_signal_connect (timeline,
+ "completed", G_CALLBACK (timeline_completed),
+ NULL);
+
+ depth_behavior = clutter_behaviour_depth_new (
+ clutter_alpha_new_full (timeline, CLUTTER_ALPHA_RAMP_INC, NULL, NULL),
+ -2500, 400);
+
+ clutter_behaviour_apply (depth_behavior, image);
+
+ clutter_actor_show (stage);
+ clutter_timeline_start (timeline);
+
+ g_timeout_add (10000, change_filter, image);
+
+ clutter_main ();
+
+ g_object_unref (depth_behavior);
+ g_object_unref (timeline);
+
+ return EXIT_SUCCESS;
+}