Made it possible to do picking when the colors stored in the
framebuffer are only approximately the correct value. * clutter/clutter-actor.c: (init_bits): initialize constants about how many bits are available/will be used for r,g,b components. (_clutter_pix_to_id): now own function, compute an id from a pixel into its own function (used from _clutter_do_pick). (_clutter_id_to_col): now own function, computes the color to use for a given id. (clutter_actor_paint): use clutter_id_to_col. * clutter/clutter-main.c: (_clutter_do_pick): use _clutter_pix_to_id (clutter_main): re-enable invocation of fruity app shell.
This commit is contained in:
parent
04f3e42253
commit
a1b240d31b
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
||||
2008-05-13 Øyvind Kolås <pippin@o-hand.com>
|
||||
|
||||
Made it possible to do picking when the colors stored in the
|
||||
framebuffer are only approximately the correct value.
|
||||
|
||||
* clutter/clutter-actor.c:
|
||||
(init_bits): initialize constants about how many bits are
|
||||
available/will be used for r,g,b components.
|
||||
(_clutter_pix_to_id): now own function, compute an id from a
|
||||
pixel into its own function (used from _clutter_do_pick).
|
||||
(_clutter_id_to_col): now own function, computes the color to use for
|
||||
a given id.
|
||||
(clutter_actor_paint): use clutter_id_to_col.
|
||||
* clutter/clutter-main.c:
|
||||
(_clutter_do_pick): use _clutter_pix_to_id
|
||||
(clutter_main): re-enable invocation of fruity app shell.
|
||||
|
||||
2008-05-13 Emmanuele Bassi <ebassi@openedhand.com>
|
||||
|
||||
* clutter/fruity/clutter-stage-fruity.c:
|
||||
|
@ -1211,6 +1211,91 @@ _clutter_actor_apply_modelview_transform_recursive (ClutterActor *self,
|
||||
_clutter_actor_apply_modelview_transform (self);
|
||||
}
|
||||
|
||||
static gint r_available, g_available, b_available;
|
||||
static gint r_used, g_used, b_used;
|
||||
|
||||
static inline void init_bits (void)
|
||||
{
|
||||
static gboolean done = FALSE;
|
||||
if (G_LIKELY (done))
|
||||
return;
|
||||
done = TRUE;
|
||||
cogl_get_bitmasks (&r_available, &g_available, &b_available, NULL);
|
||||
|
||||
r_used = r_available;
|
||||
g_used = g_available;
|
||||
b_used = b_available;
|
||||
|
||||
#ifndef HAVE_CLUTTER_FRUITY
|
||||
/* We always do fuzzy picking for the fruity backend */
|
||||
if (g_getenv ("CLUTTER_FUZZY_PICK")!=NULL)
|
||||
#endif
|
||||
{
|
||||
r_used--;
|
||||
g_used--;
|
||||
b_used--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
_clutter_id_to_col (guint id,
|
||||
ClutterColor *col)
|
||||
{
|
||||
gint red, green, blue;
|
||||
|
||||
init_bits ();
|
||||
|
||||
/* compute the numbers we'll store in the components */
|
||||
red = (id >> (g_used+b_used)) & (0xff >> (8-r_used));
|
||||
green = (id >> b_used) & (0xff >> (8-g_used));
|
||||
blue = (id) & (0xff >> (8-b_used));
|
||||
|
||||
/* shift left bits a bit and add one, this circumvents
|
||||
* at least some potential rounding errors in GL/GLES
|
||||
* driver / hw implementation.
|
||||
*/
|
||||
if (r_used != r_available)
|
||||
red = red * 2 + 1;
|
||||
if (g_used != g_available)
|
||||
green = green * 2 + 1;
|
||||
if (b_used != b_available)
|
||||
blue = blue * 2 + 1;
|
||||
|
||||
/* shift up to be full 8bit values */
|
||||
red = red << (8-r_available);
|
||||
green = green << (8-g_available);
|
||||
blue = blue << (8-b_available);
|
||||
|
||||
col->red = red;
|
||||
col->green = green;
|
||||
col->blue = blue;
|
||||
col->alpha = 0xff;
|
||||
}
|
||||
|
||||
guint _clutter_pix_to_id (guchar pixel[4])
|
||||
{
|
||||
gint red, green, blue;
|
||||
guint id;
|
||||
|
||||
/* reduce the pixel components to the number of bits actually used of the
|
||||
* 8bits.
|
||||
*/
|
||||
red = pixel[0] >> (8 - r_available);
|
||||
green = pixel[1] >> (8 - g_available);
|
||||
blue = pixel[2] >> (8 - b_available);
|
||||
|
||||
/* divide by two */
|
||||
red = red >> (r_available-r_used);
|
||||
green = green >> (g_available-g_used);
|
||||
blue = blue >> (b_available-b_used);
|
||||
|
||||
/* combine the correct per component values into the final id */
|
||||
id = blue + (green << b_used) + (red << (b_used + g_used));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_paint:
|
||||
* @self: A #ClutterActor
|
||||
@ -1256,19 +1341,9 @@ clutter_actor_paint (ClutterActor *self)
|
||||
|
||||
if (G_UNLIKELY(context->pick_mode != CLUTTER_PICK_NONE))
|
||||
{
|
||||
gint r, g, b;
|
||||
ClutterColor col;
|
||||
guint32 id;
|
||||
|
||||
id = clutter_actor_get_gid (self);
|
||||
|
||||
cogl_get_bitmasks (&r, &g, &b, NULL);
|
||||
|
||||
/* Encode the actor id into a color, taking into account bpp */
|
||||
col.red = ((id >> (g+b)) & (0xff>>(8-r)))<<(8-r);
|
||||
col.green = ((id >> b) & (0xff>>(8-g))) << (8-g);
|
||||
col.blue = (id & (0xff>>(8-b)))<<(8-b);
|
||||
col.alpha = 0xff;
|
||||
_clutter_id_to_col (clutter_actor_get_gid (self), &col);
|
||||
|
||||
/* Actor will then paint silhouette of itself in supplied
|
||||
* color. See clutter_stage_get_actor_at_pos() for where
|
||||
|
@ -226,6 +226,8 @@ clutter_get_motion_events_enabled (void)
|
||||
return context->motion_events_per_actor;
|
||||
}
|
||||
|
||||
guint _clutter_pix_to_id (guchar pixel[4]);
|
||||
|
||||
ClutterActor *
|
||||
_clutter_do_pick (ClutterStage *stage,
|
||||
gint x,
|
||||
@ -237,8 +239,7 @@ _clutter_do_pick (ClutterStage *stage,
|
||||
GLint viewport[4];
|
||||
ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
|
||||
guint32 id;
|
||||
gint r,g,b;
|
||||
|
||||
|
||||
context = clutter_context_get_default ();
|
||||
|
||||
_clutter_backend_ensure_context (context->backend, stage);
|
||||
@ -273,10 +274,7 @@ _clutter_do_pick (ClutterStage *stage,
|
||||
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
|
||||
return CLUTTER_ACTOR (stage);
|
||||
|
||||
cogl_get_bitmasks (&r, &g, &b, NULL);
|
||||
|
||||
/* Decode color back into an ID, taking into account fb depth */
|
||||
id = pixel[2]>>(8-b) | pixel[1]<<b>>(8-g) | pixel[0]<<(g+b)>>(8-r);
|
||||
id = _clutter_pix_to_id (pixel);
|
||||
|
||||
return clutter_get_actor_by_gid (id);
|
||||
}
|
||||
@ -348,7 +346,10 @@ clutter_main (void)
|
||||
loop = g_main_loop_new (NULL, TRUE);
|
||||
main_loops = g_slist_prepend (main_loops, loop);
|
||||
|
||||
#ifdef HAVE_CLUTTER_FRUITY_FOO
|
||||
#ifdef HAVE_CLUTTER_FRUITY
|
||||
/* clutter fruity creates an application that forwards events and manually
|
||||
* spins the mainloop
|
||||
*/
|
||||
clutter_fruity_main ();
|
||||
#else
|
||||
if (g_main_loop_is_running (main_loops->data))
|
||||
|
Loading…
Reference in New Issue
Block a user