2007-11-21 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/cogl/cogl.h: Add cogl_fog_set() abstracting the
	glFog() functions and enabling the GL_FOG flag.

	* clutter/cogl/gl/cogl.c: Add GL implementation of cogl_fog_set().
	
	* clutter/cogl/gles/cogl.c: Add GL/ES implementation of
	cogl_fog_set().

	* clutter.symbols: Add new symbols.

	* clutter/clutter-stage.h: Add API to enable depth cueing on
	the stage using a linear GL fog, and to set the parameters
	for it (#637).

	* clutter/clutter-stage.c (clutter_stage_paint): Enable the
	GL fog if the ClutterStage:use-fog property is true.

	* tests/test-depth.c: Test the new stage API.
This commit is contained in:
Emmanuele Bassi 2007-11-21 11:55:26 +00:00
parent a770e57193
commit 99acb8e9c1
10 changed files with 451 additions and 87 deletions

View File

@ -1,3 +1,24 @@
2007-11-21 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/cogl/cogl.h: Add cogl_fog_set() abstracting the
glFog() functions and enabling the GL_FOG flag.
* clutter/cogl/gl/cogl.c: Add GL implementation of cogl_fog_set().
* clutter/cogl/gles/cogl.c: Add GL/ES implementation of
cogl_fog_set().
* clutter.symbols: Add new symbols.
* clutter/clutter-stage.h: Add API to enable depth cueing on
the stage using a linear GL fog, and to set the parameters
for it (#637).
* clutter/clutter-stage.c (clutter_stage_paint): Enable the
GL fog if the ClutterStage:use-fog property is true.
* tests/test-depth.c: Test the new stage API.
2007-11-20 Øyvind Kolås <pippin@o-hand.com> 2007-11-20 Øyvind Kolås <pippin@o-hand.com>
* clutter/clutter-main.c: (event_click_count_generate): generalized * clutter/clutter-main.c: (event_click_count_generate): generalized

View File

@ -404,6 +404,12 @@ clutter_stage_get_title
clutter_stage_set_user_resizable clutter_stage_set_user_resizable
clutter_stage_get_user_resizable clutter_stage_get_user_resizable
clutter_stage_set_key_focus clutter_stage_set_key_focus
clutter_stage_set_use_fog
clutter_stage_get_use_fog
clutter_stage_set_fog
clutter_stage_get_fog
clutter_stage_set_fogx
clutter_stage_get_fogx
clutter_texture_error_quark clutter_texture_error_quark
clutter_texture_get_type clutter_texture_get_type
clutter_texture_new clutter_texture_new

View File

@ -57,11 +57,13 @@ struct _ClutterStagePrivate
{ {
ClutterColor color; ClutterColor color;
ClutterPerspective perspective; ClutterPerspective perspective;
ClutterFog fog;
guint is_fullscreen : 1; guint is_fullscreen : 1;
guint is_offscreen : 1; guint is_offscreen : 1;
guint is_cursor_visible : 1; guint is_cursor_visible : 1;
guint is_user_resizable : 1; guint is_user_resizable : 1;
guint use_fog : 1;
gchar *title; gchar *title;
ClutterActor *key_focused_actor; ClutterActor *key_focused_actor;
@ -77,7 +79,8 @@ enum
PROP_CURSOR_VISIBLE, PROP_CURSOR_VISIBLE,
PROP_PERSPECTIVE, PROP_PERSPECTIVE,
PROP_TITLE, PROP_TITLE,
PROP_USER_RESIZE PROP_USER_RESIZE,
PROP_USE_FOG
}; };
enum enum
@ -98,6 +101,14 @@ clutter_stage_paint (ClutterActor *self)
cogl_paint_init (&priv->color); cogl_paint_init (&priv->color);
if (priv->use_fog)
{
cogl_fog_set (&priv->color,
priv->fog.density,
priv->fog.z_near,
priv->fog.z_far);
}
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self); CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
} }
@ -169,6 +180,9 @@ clutter_stage_set_property (GObject *object,
case PROP_USER_RESIZE: case PROP_USER_RESIZE:
clutter_stage_set_user_resizable (stage, g_value_get_boolean (value)); clutter_stage_set_user_resizable (stage, g_value_get_boolean (value));
break; break;
case PROP_USE_FOG:
clutter_stage_set_use_fog (stage, 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;
@ -214,6 +228,9 @@ clutter_stage_get_property (GObject *object,
case PROP_USER_RESIZE: case PROP_USER_RESIZE:
g_value_set_boolean (value, priv->is_user_resizable); g_value_set_boolean (value, priv->is_user_resizable);
break; break;
case PROP_USE_FOG:
g_value_set_boolean (value, priv->use_fog);
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;
@ -309,6 +326,22 @@ clutter_stage_class_init (ClutterStageClass *klass)
"Stage Title", "Stage Title",
NULL, NULL,
CLUTTER_PARAM_READWRITE)); CLUTTER_PARAM_READWRITE));
/**
* ClutterStage:use-fog:
*
* Whether the stage should use a linear GL "fog" for creating the
* depth-cueing effect to enhance the perception of depth by fading
* actors farther from the viewpoing.
*
* Since: 0.6
*/
g_object_class_install_property (gobject_class,
PROP_USE_FOG,
g_param_spec_boolean ("use-fog",
"Use Fog",
"Whether to enable depth cueing",
FALSE,
CLUTTER_PARAM_READWRITE));
/** /**
* ClutterStage::fullscreen * ClutterStage::fullscreen
@ -326,7 +359,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /**
* ClutterStage::unfullscreen * ClutterStage::unfullscreen
* @stage: the stage which has left a fullscreen state. * @stage: the stage which has left a fullscreen state.
@ -344,8 +376,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /**
* ClutterStage::activate * ClutterStage::activate
* @stage: the stage which was activated * @stage: the stage which was activated
@ -363,7 +393,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
NULL, NULL, NULL, NULL,
clutter_marshal_VOID__VOID, clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /**
* ClutterStage::deactivate * ClutterStage::deactivate
* @stage: the stage which was deactivated * @stage: the stage which was deactivated
@ -399,6 +428,7 @@ clutter_stage_init (ClutterStage *self)
priv->is_fullscreen = FALSE; priv->is_fullscreen = FALSE;
priv->is_user_resizable = FALSE; priv->is_user_resizable = FALSE;
priv->is_cursor_visible = TRUE; priv->is_cursor_visible = TRUE;
priv->use_fog = FALSE;
priv->color.red = 0xff; priv->color.red = 0xff;
priv->color.green = 0xff; priv->color.green = 0xff;
@ -410,6 +440,11 @@ clutter_stage_init (ClutterStage *self)
priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (0.1); priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED (0.1);
priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (100.0); priv->perspective.z_far = CLUTTER_FLOAT_TO_FIXED (100.0);
/* depth cueing */
priv->fog.density = CLUTTER_FLOAT_TO_FIXED (0.1);
priv->fog.z_near = CLUTTER_FLOAT_TO_FIXED (1.0);
priv->fog.z_far = CLUTTER_FLOAT_TO_FIXED (2.0);
clutter_actor_set_size (CLUTTER_ACTOR (self), 640, 480); clutter_actor_set_size (CLUTTER_ACTOR (self), 640, 480);
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);
@ -460,7 +495,7 @@ clutter_stage_set_color (ClutterStage *stage,
priv->color.blue = color->blue; priv->color.blue = color->blue;
priv->color.alpha = color->alpha; priv->color.alpha = color->alpha;
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (stage))) if (CLUTTER_ACTOR_IS_VISIBLE (stage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
g_object_notify (G_OBJECT (stage), "color"); g_object_notify (G_OBJECT (stage), "color");
@ -504,12 +539,11 @@ clutter_stage_set_perspectivex (ClutterStage *stage,
ClutterStagePrivate *priv; ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage)); g_return_if_fail (CLUTTER_IS_STAGE (stage));
g_return_if_fail (perspective != NULL);
priv = stage->priv; priv = stage->priv;
priv->perspective.fovy = perspective->fovy;
priv->perspective.aspect = perspective->aspect; priv->perspective = *perspective;
priv->perspective.z_near = perspective->z_near;
priv->perspective.z_far = perspective->z_far;
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
} }
@ -525,15 +559,10 @@ void
clutter_stage_get_perspectivex (ClutterStage *stage, clutter_stage_get_perspectivex (ClutterStage *stage,
ClutterPerspective *perspective) ClutterPerspective *perspective)
{ {
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage)); g_return_if_fail (CLUTTER_IS_STAGE (stage));
g_return_if_fail (perspective != NULL);
priv = stage->priv; *perspective = stage->priv->perspective;
perspective->fovy = priv->perspective.fovy;
perspective->aspect = priv->perspective.aspect;
perspective->z_near = priv->perspective.z_near;
perspective->z_far = priv->perspective.z_far;
} }
/** /**
@ -560,6 +589,7 @@ clutter_stage_set_perspective (ClutterStage *stage,
g_return_if_fail (CLUTTER_IS_STAGE (stage)); g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv; priv = stage->priv;
priv->perspective.fovy = CLUTTER_FLOAT_TO_FIXED(fovy); priv->perspective.fovy = CLUTTER_FLOAT_TO_FIXED(fovy);
priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED(aspect); priv->perspective.aspect = CLUTTER_FLOAT_TO_FIXED(aspect);
priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED(z_near); priv->perspective.z_near = CLUTTER_FLOAT_TO_FIXED(z_near);
@ -991,21 +1021,183 @@ clutter_stage_get_key_focus (ClutterStage *stage)
return CLUTTER_ACTOR (stage); return CLUTTER_ACTOR (stage);
} }
/**
* clutter_stage_get_use_fog:
* @stage: the #ClutterStage
*
* Gets whether the depth cueing effect is enabled on @stage.
*
* Return value: %TRUE if the the depth cueing effect is enabled
*
* Since: 0.6
*/
gboolean
clutter_stage_get_use_fog (ClutterStage *stage)
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
return stage->priv->use_fog;
}
/**
* clutter_stage_set_use_fog:
* @stage: the #ClutterStage
* @fog: %TRUE for enabling the depth cueing effect
*
* Sets whether the depth cueing effect on the stage should be enabled
* or not.
*
* Depth cueing is a 3D effect that makes actors farther away from the
* viewing point less opaque, by fading them with the stage color.
* The parameters of the GL fog used can be changed using the
* clutter_stage_set_fog() function.
*
* Since: 0.6
*/
void
clutter_stage_set_use_fog (ClutterStage *stage,
gboolean fog)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
if (priv->use_fog != fog)
{
priv->use_fog = fog;
CLUTTER_NOTE (MISC, "%s depth-cueing inside stage",
priv->use_fog ? "enabling" : "disabling");
if (CLUTTER_ACTOR_IS_VISIBLE (stage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
g_object_notify (G_OBJECT (stage), "use-fog");
}
}
/**
* clutter_stage_get_fog:
* @stage: a #ClutterStage
* @density: return location for the intensity dampening
* @z_near: return location for the starting point of the depth cueing
* @z_far: return location for the ending point of the depth cueing
*
* Retrieves the settings used by the GL fog to create the
* depth cueing effect on the @stage.
*
* Since: 0.6
*/
void
clutter_stage_get_fog (ClutterStage *stage,
gdouble *density,
gdouble *z_near,
gdouble *z_far)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
if (density)
*density = CLUTTER_FIXED_TO_FLOAT (priv->fog.density);
if (z_near)
*z_near = CLUTTER_FIXED_TO_FLOAT (priv->fog.z_near);
if (z_far)
*z_far = CLUTTER_FIXED_TO_FLOAT (priv->fog.z_far);
}
/**
* clutter_stage_set_fog:
* @stage: the #ClutterStage
* @density: density of the intensity dampening
* @z_near: starting point of the depth cueing
* @z_far: ending point of the depth cueing
*
* Sets the GL fog settings used to create the depth cueing effect
* on the @stage.
*
* If the actors are all near the view point you will need a higher @density
* and a smaller interval between @z_near and @z_far. On the other hand, if
* actors are placed far away from the view point you will need a lower
* @density but a bigger interval between @z_near and @z_far.
*
* Since: 0.6
*/
void
clutter_stage_set_fog (ClutterStage *stage,
gdouble density,
gdouble z_near,
gdouble z_far)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
priv->fog.density = CLUTTER_FLOAT_TO_FIXED (density);
priv->fog.z_near = CLUTTER_FLOAT_TO_FIXED (z_near);
priv->fog.z_far = CLUTTER_FLOAT_TO_FIXED (z_far);
if (priv->use_fog && CLUTTER_ACTOR_IS_VISIBLE (stage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
/**
* clutter_stage_set_fogx:
* @stage: the #ClutterStage
* @fog: a #ClutterFog structure
*
* Sets the depth cueing settings for the @stage. This is the fixed point
* version of clutter_stage_set_fog().
*
* Since: 0.6
*/
void
clutter_stage_set_fogx (ClutterStage *stage,
ClutterFog *fog)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
g_return_if_fail (fog != NULL);
priv = stage->priv;
priv->fog = *fog;
if (priv->use_fog && CLUTTER_ACTOR_IS_VISIBLE (stage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
/**
* clutter_stage_get_fogx:
* @stage: the #ClutterStage
* @fog: return location for a #ClutterFog structure
*
* Retrieves the current depth cueing settings from the stage. This is the
* fixed point version of clutter_stage_get_fog().
*
* Since: 0.6
*/
void
clutter_stage_get_fogx (ClutterStage *stage,
ClutterFog *fog)
{
g_return_if_fail (CLUTTER_IS_STAGE (stage));
g_return_if_fail (fog != NULL);
*fog = stage->priv->fog;
}
/*** Perspective boxed type ******/ /*** Perspective boxed type ******/
/** static ClutterPerspective *
* clutter_perspective_copy:
* @perspective: a #ClutterPerspective
*
* Makes a copy of the perspective structure. The result must be
* freed using clutter_perspective_free().
*
* Return value: an allocated copy of @perspective.
*
* Since: 0.4
*/
ClutterPerspective *
clutter_perspective_copy (const ClutterPerspective *perspective) clutter_perspective_copy (const ClutterPerspective *perspective)
{ {
ClutterPerspective *result; ClutterPerspective *result;
@ -1018,19 +1210,10 @@ clutter_perspective_copy (const ClutterPerspective *perspective)
return result; return result;
} }
/** static void
* clutter_perspective_free:
* @perspective: a #ClutterPerspective
*
* Frees a perspective structure created with clutter_perspective_copy().
*
* Since: 0.4
*/
void
clutter_perspective_free (ClutterPerspective *perspective) clutter_perspective_free (ClutterPerspective *perspective)
{ {
g_return_if_fail (perspective != NULL); if (G_LIKELY (perspective))
g_slice_free (ClutterPerspective, perspective); g_slice_free (ClutterPerspective, perspective);
} }
@ -1040,10 +1223,43 @@ clutter_perspective_get_type (void)
static GType our_type = 0; static GType our_type = 0;
if (!our_type) if (!our_type)
our_type = g_boxed_type_register_static our_type =
("ClutterPerspective", g_boxed_type_register_static ("ClutterPerspective",
(GBoxedCopyFunc) clutter_perspective_copy, (GBoxedCopyFunc) clutter_perspective_copy,
(GBoxedFreeFunc) clutter_perspective_free); (GBoxedFreeFunc) clutter_perspective_free);
return our_type; return our_type;
} }
static ClutterFog *
clutter_fog_copy (const ClutterFog *fog)
{
ClutterFog *copy;
g_return_val_if_fail (fog != NULL, NULL);
copy = g_slice_new0 (ClutterFog);
*copy = *fog;
return copy;
}
static void
clutter_fog_free (ClutterFog *fog)
{
if (G_LIKELY (fog))
g_slice_free (ClutterFog, fog);
}
GType
clutter_fog_get_type (void)
{
static GType our_type = 0;
if (G_UNLIKELY (our_type == 0))
our_type =
g_boxed_type_register_static ("ClutterFog",
(GBoxedCopyFunc) clutter_fog_copy,
(GBoxedFreeFunc) clutter_fog_free);
return our_type;
}

View File

@ -34,6 +34,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_PERSPECTIVE (clutter_perspective_get_type ()) #define CLUTTER_TYPE_PERSPECTIVE (clutter_perspective_get_type ())
#define CLUTTER_TYPE_FOG (clutter_fog_get_type ())
#define CLUTTER_TYPE_STAGE (clutter_stage_get_type()) #define CLUTTER_TYPE_STAGE (clutter_stage_get_type())
#define CLUTTER_STAGE(obj) \ #define CLUTTER_STAGE(obj) \
@ -63,6 +64,8 @@ G_BEGIN_DECLS
clutter_actor_get_height (clutter_stage_get_default ()) clutter_actor_get_height (clutter_stage_get_default ())
typedef struct _ClutterPerspective ClutterPerspective; typedef struct _ClutterPerspective ClutterPerspective;
typedef struct _ClutterFog ClutterFog;
typedef struct _ClutterStage ClutterStage; typedef struct _ClutterStage ClutterStage;
typedef struct _ClutterStageClass ClutterStageClass; typedef struct _ClutterStageClass ClutterStageClass;
typedef struct _ClutterStagePrivate ClutterStagePrivate; typedef struct _ClutterStagePrivate ClutterStagePrivate;
@ -118,7 +121,7 @@ struct _ClutterStageClass
* @z_near: FIXME * @z_near: FIXME
* @z_far: FIXME * @z_far: FIXME
* *
* Stage perspective definition * Stage perspective definition.
* *
* Since: 0.4 * Since: 0.4
*/ */
@ -130,10 +133,26 @@ struct _ClutterPerspective
ClutterFixed z_far; ClutterFixed z_far;
}; };
GType clutter_perspective_get_type (void) G_GNUC_CONST; /**
ClutterPerspective *clutter_perspective_copy (const ClutterPerspective *perspective); * ClutterFog:
void clutter_perspective_free (ClutterPerspective *perspective); * @density: density of the fog
* @z_near: start point of the depth cueing
* @z_far: end point of the depth cueing
*
* Fog settings used to create the depth cueing effect. This
* structure is useful only when using the fixed point API.
*
* Since: 0.6
*/
struct _ClutterFog
{
ClutterFixed density;
ClutterFixed z_near;
ClutterFixed z_far;
};
GType clutter_perspective_get_type (void) G_GNUC_CONST;
GType clutter_fog_get_type (void) G_GNUC_CONST;
GType clutter_stage_get_type (void) G_GNUC_CONST; GType clutter_stage_get_type (void) G_GNUC_CONST;
ClutterActor *clutter_stage_get_default (void); ClutterActor *clutter_stage_get_default (void);
@ -177,14 +196,26 @@ G_CONST_RETURN gchar *clutter_stage_get_title (ClutterStage *stage);
void clutter_stage_set_user_resizable (ClutterStage *stage, void clutter_stage_set_user_resizable (ClutterStage *stage,
gboolean resizable); gboolean resizable);
gboolean clutter_stage_get_user_resizable (ClutterStage *stage); gboolean clutter_stage_get_user_resizable (ClutterStage *stage);
void clutter_stage_set_use_fog (ClutterStage *stage,
gboolean fog);
gboolean clutter_stage_get_use_fog (ClutterStage *stage);
void clutter_stage_set_fog (ClutterStage *stage,
gdouble density,
gdouble z_near,
gdouble z_far);
void clutter_stage_get_fog (ClutterStage *stage,
gdouble *density,
gdouble *z_near,
gdouble *z_far);
void clutter_stage_set_fogx (ClutterStage *stage,
ClutterFog *fog);
void clutter_stage_get_fogx (ClutterStage *stage,
ClutterFog *fog);
/* New experiental calls */ /* New experiental calls */
void void clutter_stage_set_key_focus (ClutterStage *stage,
clutter_stage_set_key_focus (ClutterStage *stage,
ClutterActor *actor); ClutterActor *actor);
ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage);
ClutterActor*
clutter_stage_get_key_focus (ClutterStage *stage);
G_END_DECLS G_END_DECLS

View File

@ -201,6 +201,12 @@ cogl_get_viewport (ClutterFixed v[4]);
void void
cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha); cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha);
void
cogl_fog_set (const ClutterColor *fog_color,
ClutterFixed density,
ClutterFixed z_near,
ClutterFixed z_far);
G_END_DECLS G_END_DECLS
#endif /* __COGL_H__ */ #endif /* __COGL_H__ */

View File

@ -165,7 +165,10 @@ cogl_paint_init (const ClutterColor *color)
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);
glDisable (GL_LIGHTING); glDisable (GL_LIGHTING);
glDisable (GL_DEPTH_TEST); glDisable (GL_FOG);
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LEQUAL);
cogl_enable (CGL_ENABLE_BLEND); cogl_enable (CGL_ENABLE_BLEND);
@ -234,9 +237,10 @@ cogl_enable (gulong flags)
{ {
glEnable (GL_BLEND); glEnable (GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
__enable_flags |= CGL_ENABLE_BLEND; __enable_flags |= CGL_ENABLE_BLEND;
} }
}
else if (__enable_flags & CGL_ENABLE_BLEND) else if (__enable_flags & CGL_ENABLE_BLEND)
{ {
glDisable (GL_BLEND); glDisable (GL_BLEND);
@ -246,9 +250,11 @@ cogl_enable (gulong flags)
if (flags & CGL_ENABLE_TEXTURE_2D) if (flags & CGL_ENABLE_TEXTURE_2D)
{ {
if (!(__enable_flags & CGL_ENABLE_TEXTURE_2D)) if (!(__enable_flags & CGL_ENABLE_TEXTURE_2D))
{
glEnable (GL_TEXTURE_2D); glEnable (GL_TEXTURE_2D);
__enable_flags |= CGL_ENABLE_TEXTURE_2D; __enable_flags |= CGL_ENABLE_TEXTURE_2D;
} }
}
else if (__enable_flags & CGL_ENABLE_TEXTURE_2D) else if (__enable_flags & CGL_ENABLE_TEXTURE_2D)
{ {
glDisable (GL_TEXTURE_2D); glDisable (GL_TEXTURE_2D);
@ -259,9 +265,11 @@ cogl_enable (gulong flags)
if (flags & CGL_ENABLE_TEXTURE_RECT) if (flags & CGL_ENABLE_TEXTURE_RECT)
{ {
if (!(__enable_flags & CGL_ENABLE_TEXTURE_RECT)) if (!(__enable_flags & CGL_ENABLE_TEXTURE_RECT))
{
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
__enable_flags |= CGL_ENABLE_TEXTURE_RECT; __enable_flags |= CGL_ENABLE_TEXTURE_RECT;
} }
}
else if (__enable_flags & CGL_ENABLE_TEXTURE_RECT) else if (__enable_flags & CGL_ENABLE_TEXTURE_RECT)
{ {
glDisable (GL_TEXTURE_RECTANGLE_ARB); glDisable (GL_TEXTURE_RECTANGLE_ARB);
@ -272,10 +280,11 @@ cogl_enable (gulong flags)
if (flags & CGL_ENABLE_ALPHA_TEST) if (flags & CGL_ENABLE_ALPHA_TEST)
{ {
if (!(__enable_flags & CGL_ENABLE_ALPHA_TEST)) if (!(__enable_flags & CGL_ENABLE_ALPHA_TEST))
{
glEnable (GL_ALPHA_TEST); glEnable (GL_ALPHA_TEST);
__enable_flags |= CGL_ENABLE_ALPHA_TEST; __enable_flags |= CGL_ENABLE_ALPHA_TEST;
} }
}
else if (__enable_flags & CGL_ENABLE_ALPHA_TEST) else if (__enable_flags & CGL_ENABLE_ALPHA_TEST)
{ {
glDisable (GL_ALPHA_TEST); glDisable (GL_ALPHA_TEST);
@ -712,3 +721,28 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
*alpha = value; *alpha = value;
} }
} }
void
cogl_fog_set (const ClutterColor *fog_color,
ClutterFixed density,
ClutterFixed start,
ClutterFixed stop)
{
GLfloat fogColor[4];
fogColor[0] = ((float) fog_color->red / 0xff * 1.0);
fogColor[1] = ((float) fog_color->green / 0xff * 1.0);
fogColor[2] = ((float) fog_color->blue / 0xff * 1.0);
fogColor[3] = ((float) fog_color->alpha / 0xff * 1.0);
glEnable (GL_FOG);
glFogfv (GL_FOG_COLOR, fogColor);
glFogi (GL_FOG_MODE, GL_LINEAR);
glHint (GL_FOG_HINT, GL_NICEST);
glFogf (GL_FOG_DENSITY, CLUTTER_FIXED_TO_FLOAT (density));
glFogf (GL_FOG_START, CLUTTER_FIXED_TO_FLOAT (start));
glFogf (GL_FOG_END, CLUTTER_FIXED_TO_FLOAT (stop));
}

View File

@ -116,7 +116,10 @@ cogl_paint_init (const ClutterColor *color)
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);
glDisable (GL_LIGHTING); glDisable (GL_LIGHTING);
glDisable (GL_DEPTH_TEST); glDisable (GL_FOG);
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LEQUAL);
cogl_enable (CGL_ENABLE_BLEND); cogl_enable (CGL_ENABLE_BLEND);
@ -602,3 +605,28 @@ cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
if (alpha) if (alpha)
GE( glGetIntegerv(GL_ALPHA_BITS, alpha ) ); GE( glGetIntegerv(GL_ALPHA_BITS, alpha ) );
} }
void
cogl_fog_set (const ClutterColor *fog_color,
ClutterFixed density,
ClutterFixed z_near,
ClutterFixed z_far)
{
GLfixed fogColor[4];
fogColor[0] = (fog_color->red << 16) / 0xff;
fogColor[1] = (fog_color->green << 16) / 0xff;
fogColor[2] = (fog_color->blue << 16) / 0xff;
fogColor[3] = (fog_color->alpha << 16) / 0xff;
glEnable (GL_FOG);
glFogxv (GL_FOG_COLOR, fogColor);
glFogi (GL_FOG_MODE, GL_LINEAR);
glHint (GL_FOG_HINT, GL_NICEST);
glFogx (GL_FOG_DENSITY, (GLfixed) density);
glFogx (GL_FOG_START, (GLfixed) z_near);
glFogx (GL_FOG_STOP, (GLfixed) z_far);
}

View File

@ -1,3 +1,7 @@
2007-11-21 Emmanuele Bassi <ebassi@openedhand.com>
* clutter-sections.txt: Add the new ClutterStage fog API.
2007-11-19 Emmanuele Bassi <ebassi@openedhand.com> 2007-11-19 Emmanuele Bassi <ebassi@openedhand.com>
* clutter-sections.txt: Add ClutterScore symbols and * clutter-sections.txt: Add ClutterScore symbols and

View File

@ -456,13 +456,11 @@ clutter_stage_hide_cursor
clutter_stage_get_actor_at_pos clutter_stage_get_actor_at_pos
clutter_stage_snapshot clutter_stage_snapshot
clutter_stage_event clutter_stage_event
clutter_stage_get_key_focus
clutter_stage_set_key_focus clutter_stage_set_key_focus
clutter_stage_get_key_focus
<SUBSECTION> <SUBSECTION>
ClutterPerspective ClutterPerspective
clutter_perspective_copy
clutter_perspective_free
clutter_stage_set_perspective clutter_stage_set_perspective
clutter_stage_set_perspectivex clutter_stage_set_perspectivex
clutter_stage_get_perspective clutter_stage_get_perspective
@ -473,6 +471,16 @@ clutter_stage_set_title
clutter_stage_get_title clutter_stage_get_title
clutter_stage_set_user_resizable clutter_stage_set_user_resizable
clutter_stage_get_user_resizable clutter_stage_get_user_resizable
<SUBSECTION>
ClutterFog
clutter_stage_set_use_fog
clutter_stage_get_use_fog
clutter_stage_set_fog
clutter_stage_get_fog
clutter_stage_set_fogx
clutter_stage_get_fogx
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_STAGE CLUTTER_STAGE
CLUTTER_IS_STAGE CLUTTER_IS_STAGE
@ -485,6 +493,7 @@ CLUTTER_TYPE_PERSPECTIVE
ClutterStagePrivate ClutterStagePrivate
clutter_stage_get_type clutter_stage_get_type
clutter_perspective_get_type clutter_perspective_get_type
clutter_fog_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>

View File

@ -12,14 +12,14 @@ timeline_completed (ClutterTimeline *timeline,
if (zoom_in) if (zoom_in)
{ {
depth_start = 100; depth_start = 0;
depth_end = 0; depth_end = -500;
zoom_in = FALSE; zoom_in = FALSE;
} }
else else
{ {
depth_start = 0; depth_start = -500;
depth_end = 100; depth_end = 0;
zoom_in = TRUE; zoom_in = TRUE;
} }
@ -37,8 +37,9 @@ main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterActor *stage; ClutterActor *stage;
ClutterActor *hand, *label; ClutterActor *hand, *label, *rect;
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff }; ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
ClutterColor rect_color = { 0, 0, 0, 0x88 };
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
GError *error; GError *error;
@ -51,22 +52,29 @@ main (int argc, char *argv[])
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE);
g_signal_connect (stage, g_signal_connect (stage,
"button-press-event", G_CALLBACK (clutter_main_quit), "button-press-event", G_CALLBACK (clutter_main_quit),
NULL); NULL);
label = clutter_label_new_with_text ("Mono 26", "Clutter");
clutter_actor_set_position (label, 40, 140);
clutter_actor_show (label);
hand = clutter_texture_new_from_pixbuf (pixbuf); hand = clutter_texture_new_from_pixbuf (pixbuf);
clutter_actor_set_position (hand, 240, 140); clutter_actor_set_position (hand, 240, 140);
clutter_actor_show (hand); clutter_actor_show (hand);
label = clutter_label_new_with_text ("Mono 26", "Clutter"); rect = clutter_rectangle_new_with_color (&rect_color);
clutter_actor_set_position (label, 100, 100); clutter_actor_set_position (rect, 440, 140);
clutter_actor_show (label); clutter_actor_set_size (rect, 200, 200);
clutter_actor_show (rect);
clutter_container_add (CLUTTER_CONTAINER (stage), hand, label, NULL); clutter_container_add (CLUTTER_CONTAINER (stage), hand, label, rect, NULL);
/* five seconds, at 50 fps */ /* 3 seconds, at 60 fps */
timeline = clutter_timeline_new (250, 50); timeline = clutter_timeline_new (180, 60);
g_signal_connect (timeline, g_signal_connect (timeline,
"completed", G_CALLBACK (timeline_completed), "completed", G_CALLBACK (timeline_completed),
NULL); NULL);
@ -74,9 +82,10 @@ main (int argc, char *argv[])
d_behave = clutter_behaviour_depth_new (clutter_alpha_new_full (timeline, d_behave = clutter_behaviour_depth_new (clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC, CLUTTER_ALPHA_RAMP_INC,
NULL, NULL), NULL, NULL),
0, 100); -500, 0);
clutter_behaviour_apply (d_behave, hand); clutter_behaviour_apply (d_behave, hand);
clutter_behaviour_apply (d_behave, label); clutter_behaviour_apply (d_behave, label);
clutter_behaviour_apply (d_behave, rect);
clutter_actor_show (stage); clutter_actor_show (stage);