Add lightness, brightness, and contrast effects

Added three classes for new clutter effects:  inverse lightness,
modify brightness, and modify contrast.

https://bugzilla.gnome.org/show_bug.cgi?id=656156
This commit is contained in:
Joseph Scheuhammer 2011-09-27 13:01:36 -04:00
parent ac8e174eca
commit 4829ae1c79
10 changed files with 1260 additions and 0 deletions

View File

@ -71,6 +71,7 @@ source_h = \
$(srcdir)/clutter-blur-effect.h \
$(srcdir)/clutter-box.h \
$(srcdir)/clutter-box-layout.h \
$(srcdir)/clutter-brightness-effect.h \
$(srcdir)/clutter-cairo-texture.h \
$(srcdir)/clutter-child-meta.h \
$(srcdir)/clutter-click-action.h \
@ -80,6 +81,7 @@ source_h = \
$(srcdir)/clutter-colorize-effect.h \
$(srcdir)/clutter-constraint.h \
$(srcdir)/clutter-container.h \
$(srcdir)/clutter-contrast-effect.h \
$(srcdir)/clutter-deform-effect.h \
$(srcdir)/clutter-deprecated.h \
$(srcdir)/clutter-desaturate-effect.h \
@ -96,6 +98,7 @@ source_h = \
$(srcdir)/clutter-gesture-action.h \
$(srcdir)/clutter-group.h \
$(srcdir)/clutter-input-device.h \
$(srcdir)/clutter-invert-lightness-effect.h \
$(srcdir)/clutter-interval.h \
$(srcdir)/clutter-keysyms.h \
$(srcdir)/clutter-keysyms-compat.h \
@ -158,6 +161,7 @@ source_c = \
$(srcdir)/clutter-blur-effect.c \
$(srcdir)/clutter-box.c \
$(srcdir)/clutter-box-layout.c \
$(srcdir)/clutter-brightness-effect.c \
$(srcdir)/clutter-cairo-texture.c \
$(srcdir)/clutter-child-meta.c \
$(srcdir)/clutter-click-action.c \
@ -166,6 +170,7 @@ source_c = \
$(srcdir)/clutter-colorize-effect.c \
$(srcdir)/clutter-constraint.c \
$(srcdir)/clutter-container.c \
$(srcdir)/clutter-contrast-effect.c \
$(srcdir)/clutter-deform-effect.c \
$(srcdir)/clutter-desaturate-effect.c \
$(srcdir)/clutter-device-manager.c \
@ -182,6 +187,7 @@ source_c = \
$(srcdir)/clutter-gesture-action.c \
$(srcdir)/clutter-group.c \
$(srcdir)/clutter-input-device.c \
$(srcdir)/clutter-invert-lightness-effect.c \
$(srcdir)/clutter-interval.c \
$(srcdir)/clutter-keysyms-table.c \
$(srcdir)/clutter-layout-manager.c \

View File

@ -0,0 +1,380 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010, 2011 Inclusive Design Research Centre, OCAD University.
*
* 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:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
/**
* SECTION:clutter-brightness-effect
* @short_description: Increase/decrease brightness of actor.
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterBrightnessEffect is a sub-class of #ClutterEffect that changes the
* overall brightness of a #ClutterActor.
*
* #ClutterBrightnessEffect is available since Clutter 1.10
*/
#define CLUTTER_BRIGHTNESS_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BRIGHTNESS_EFFECT, ClutterBrightnessEffectClass))
#define CLUTTER_IS_BRIGHTNESS_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BRIGHTNESS_EFFECT))
#define CLUTTER_BRIGHTNESS_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BRIGHTNESS_EFFECT, ClutterBrightnessEffectClass))
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-brightness-effect.h"
#include "clutter-actor.h"
#include "clutter-feature.h"
#include "clutter-offscreen-effect.h"
#include "clutter-private.h"
struct _ClutterBrightnessEffect
{
ClutterOffscreenEffect parent_instance;
/* a back pointer to our actor, so that we can query it */
ClutterActor *actor;
CoglHandle shader;
CoglHandle program;
/* Brightness changes. */
ClutterColor brightness;
gint tex_uniform;
gint brightness_uniform;
guint is_compiled : 1;
};
struct _ClutterBrightnessEffectClass
{
ClutterOffscreenEffectClass parent_class;
};
/* Brightness effects in GLSL.
*/
static const gchar *brightness_glsl_shader =
"uniform sampler2D tex;\n"
"uniform vec3 brightness;\n"
"\n"
"void main ()\n"
"{\n"
" vec4 color = cogl_color_in * texture2D (tex, vec2 (cogl_tex_coord_in[0].xy));\n"
" vec3 effect = vec3 (color);\n"
"\n"
" effect = clamp (effect + brightness, 0.0, 1.0);\n"
"\n"
"\n"
" cogl_color_out = vec4 (effect, color.a);\n"
"}\n";
/* No brightness change. */
static const ClutterColor same_brightness = { 0x7f, 0x7f, 0x7f, 0xff };
enum
{
PROP_0,
PROP_BRIGHTNESS,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (ClutterBrightnessEffect,
clutter_brightness_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
clutter_brightness_effect_pre_paint (ClutterEffect *effect)
{
ClutterBrightnessEffect *self = CLUTTER_BRIGHTNESS_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (self->actor == NULL)
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
if (self->shader == COGL_INVALID_HANDLE)
{
self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT);
cogl_shader_source (self->shader, brightness_glsl_shader);
self->is_compiled = FALSE;
self->tex_uniform = -1;
self->brightness_uniform = -1;
}
if (self->program == COGL_INVALID_HANDLE)
self->program = cogl_create_program ();
if (!self->is_compiled)
{
g_assert (self->shader != COGL_INVALID_HANDLE);
g_assert (self->program != COGL_INVALID_HANDLE);
cogl_shader_compile (self->shader);
if (!cogl_shader_is_compiled (self->shader))
{
gchar *log_buf = cogl_shader_get_info_log (self->shader);
g_warning (G_STRLOC ": Unable to compile the brightness effects shader: %s",
log_buf);
g_free (log_buf);
cogl_handle_unref (self->shader);
cogl_handle_unref (self->program);
self->shader = COGL_INVALID_HANDLE;
self->program = COGL_INVALID_HANDLE;
}
else
{
cogl_program_attach_shader (self->program, self->shader);
cogl_program_link (self->program);
cogl_handle_unref (self->shader);
self->is_compiled = TRUE;
self->tex_uniform =
cogl_program_get_uniform_location (self->program, "tex");
self->brightness_uniform =
cogl_program_get_uniform_location (self->program, "brightness");
}
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_brightness_effect_parent_class);
return parent_class->pre_paint (effect);
}
static void
clutter_brightness_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBrightnessEffect *self = CLUTTER_BRIGHTNESS_EFFECT (effect);
ClutterOffscreenEffectClass *parent;
CoglHandle material;
if (self->program == COGL_INVALID_HANDLE)
goto out;
if (self->tex_uniform > -1)
cogl_program_set_uniform_1i (self->program, self->tex_uniform, 0);
if (self->brightness_uniform > -1)
{
float brightness[3] = {
(self->brightness.red / 127.0) - 1.0,
(self->brightness.green / 127.0) - 1.0,
(self->brightness.blue / 127.0) - 1.0
};
cogl_program_set_uniform_float (self->program, self->brightness_uniform,
3, 1,
brightness);
}
material = clutter_offscreen_effect_get_target (effect);
cogl_material_set_user_program (material, self->program);
out:
parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_brightness_effect_parent_class);
parent->paint_target (effect);
}
static void
clutter_brightness_effect_dispose (GObject *gobject)
{
ClutterBrightnessEffect *self = CLUTTER_BRIGHTNESS_EFFECT (gobject);
if (self->program != COGL_INVALID_HANDLE)
{
cogl_handle_unref (self->program);
self->program = COGL_INVALID_HANDLE;
self->shader = COGL_INVALID_HANDLE;
}
self->actor = NULL;
G_OBJECT_CLASS (clutter_brightness_effect_parent_class)->dispose (gobject);
}
static void
clutter_brightness_effect_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterBrightnessEffect *effect = CLUTTER_BRIGHTNESS_EFFECT (gobject);
switch (prop_id)
{
case PROP_BRIGHTNESS:
clutter_brightness_effect_set_brightness (effect,
clutter_value_get_color (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_brightness_effect_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterBrightnessEffect *effect = CLUTTER_BRIGHTNESS_EFFECT (gobject);
ClutterColor brightness;
switch (prop_id)
{
case PROP_BRIGHTNESS:
clutter_brightness_effect_get_brightness (effect, &brightness);
clutter_value_set_color (value, &brightness);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_brightness_effect_class_init (ClutterBrightnessEffectClass *klass)
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->paint_target = clutter_brightness_effect_paint_target;
effect_class->pre_paint = clutter_brightness_effect_pre_paint;
gobject_class->set_property = clutter_brightness_effect_set_property;
gobject_class->get_property = clutter_brightness_effect_get_property;
gobject_class->dispose = clutter_brightness_effect_dispose;
/**
* ClutterBrightnessEffect:brightness:
*
* The brightness change to apply to the actor
*
* Since: 1.10
*/
obj_props[PROP_BRIGHTNESS] =
clutter_param_spec_color ("brightness",
P_("Brightness"),
P_("The brightness change to apply"),
&same_brightness,
G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
}
static void
clutter_brightness_effect_init (ClutterBrightnessEffect *self)
{
self->brightness = same_brightness;
}
/**
* clutter_brightness_effect_new:
*
* Creates a new #ClutterBrightnessEffect to be used with
* clutter_actor_add_effect()
*
* Return value: (transfer full): the newly created #ClutterBrightnessEffect or
* or %NULL. Use g_object_unref() when done.
*
* Since: 1.10
*/
ClutterEffect *
clutter_brightness_effect_new (void)
{
return g_object_new (CLUTTER_TYPE_BRIGHTNESS_EFFECT,
NULL);
}
/**
* clutter_brightness_effect_set_brightness:
* @effect: a #ClutterBrightnessEffect
* @brightness: ClutterColor governing the brightness change.
*
* Add each of the red, green, blue components of the @brightness to
* the red, greeen, or blue components of the actor's colors.
*
* Since: 1.10
*/
void
clutter_brightness_effect_set_brightness (ClutterBrightnessEffect *effect,
const ClutterColor *brightness)
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_EFFECT (effect));
if (clutter_color_equal (&effect->brightness, brightness))
return;
effect->brightness = *brightness;
if (effect->actor != NULL)
clutter_actor_queue_redraw (effect->actor);
}
/**
* clutter_brightness_effect_get_brightness:
* @effect: a #ClutterBrightnessEffect
* @brightness: (out caller-allocates): return location for the brightness.
*
* Retrieves the brightness value used by @effect
*
* Since: 1.10
*/
void
clutter_brightness_effect_get_brightness (ClutterBrightnessEffect *effect,
ClutterColor *brightness)
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_EFFECT (effect));
g_return_if_fail (brightness != NULL);
*brightness = effect->brightness;
}

View File

@ -0,0 +1,63 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010, 2011 Inclusive Design Research Centre, OCAD University.
*
* 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:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_BRIGHTNESS_EFFECT_H__
#define __CLUTTER_BRIGHTNESS_EFFECT_H__
#include <clutter/clutter-color.h>
#include <clutter/clutter-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BRIGHTNESS_EFFECT (clutter_brightness_effect_get_type ())
#define CLUTTER_BRIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BRIGHTNESS_EFFECT, ClutterBrightnessEffect))
#define CLUTTER_IS_BRIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BRIGHTNESS_EFFECT))
/**
* ClutterBrightnessEffect:
*
* <structname>ClutterBrightnessEffect</structname> is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.10
*/
typedef struct _ClutterBrightnessEffect ClutterBrightnessEffect;
typedef struct _ClutterBrightnessEffectClass ClutterBrightnessEffectClass;
GType clutter_brightness_effect_get_type (void) G_GNUC_CONST;
ClutterEffect *clutter_brightness_effect_new (void);
void clutter_brightness_effect_set_brightness (ClutterBrightnessEffect *effect,
const ClutterColor *brightness);
void clutter_brightness_effect_get_brightness (ClutterBrightnessEffect *effect,
ClutterColor *brightness);
G_END_DECLS
#endif /* __CLUTTER_BRIGHTNESS_EFFECT_H__ */

View File

@ -0,0 +1,395 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010, 2011 Inclusive Design Research Centre, OCAD University.
*
* 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:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
/**
* SECTION:clutter-contrast-effect
* @short_description: Increase/decrease contrast of actor.
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterContrastEffect is a sub-class of #ClutterEffect that changes the
* overall contrast of a #ClutterActor.
*
* #ClutterContrastEffect is available since Clutter 1.10
*/
#define CLUTTER_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CONTRAST_EFFECT, ClutterContrastEffectClass))
#define CLUTTER_IS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CONTRAST_EFFECT))
#define CLUTTER_CONTRAST_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CONTRAST_EFFECT, ClutterContrastEffectClass))
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-contrast-effect.h"
#include "clutter-actor.h"
#include "clutter-feature.h"
#include "clutter-offscreen-effect.h"
#include "clutter-private.h"
struct _ClutterContrastEffect
{
ClutterOffscreenEffect parent_instance;
/* a back pointer to our actor, so that we can query it */
ClutterActor *actor;
CoglHandle shader;
CoglHandle program;
/* Contrast changes. */
ClutterColor contrast;
gint tex_uniform;
gint contrast_uniform;
guint is_compiled : 1;
};
struct _ClutterContrastEffectClass
{
ClutterOffscreenEffectClass parent_class;
};
/* Contrast effects in GLSL.
*/
static const gchar *contrast_glsl_shader =
"uniform sampler2D tex;\n"
"uniform vec3 contrast;\n"
"\n"
"void main ()\n"
"{\n"
" vec4 color = cogl_color_in * texture2D (tex, vec2 (cogl_tex_coord_in[0].xy));\n"
" vec3 effect = vec3 (color);\n"
"\n"
" if (effect.r < 0.5)\n"
" effect.r = clamp (effect.r - contrast.r, 0.0, 0.5);\n"
" else\n"
" effect.r = clamp (effect.r + contrast.r, 0.5, 1.0);\n"
"\n"
" if (effect.g < 0.5)\n"
" effect.g = clamp (effect.g - contrast.g, 0.0, 0.5);\n"
" else\n"
" effect.g = clamp (effect.g + contrast.g, 0.5, 1.0);\n"
"\n"
" if (effect.b < 0.5)\n"
" effect.b = clamp (effect.b - contrast.b, 0.0, 0.5);\n"
" else\n"
" effect.b = clamp (effect.b + contrast.b, 0.5, 1.0);\n"
"\n"
" cogl_color_out = vec4 (effect, color.a);\n"
"}\n";
/* No contrast change. */
static const ClutterColor same_contrast = { 0x7f, 0x7f, 0x7f, 0xff };
enum
{
PROP_0,
PROP_CONTRAST,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (ClutterContrastEffect,
clutter_contrast_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
clutter_contrast_effect_pre_paint (ClutterEffect *effect)
{
ClutterContrastEffect *self = CLUTTER_CONTRAST_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (self->actor == NULL)
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
if (self->shader == COGL_INVALID_HANDLE)
{
self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT);
cogl_shader_source (self->shader, contrast_glsl_shader);
self->is_compiled = FALSE;
self->tex_uniform = -1;
self->contrast_uniform = -1;
}
if (self->program == COGL_INVALID_HANDLE)
self->program = cogl_create_program ();
if (!self->is_compiled)
{
g_assert (self->shader != COGL_INVALID_HANDLE);
g_assert (self->program != COGL_INVALID_HANDLE);
cogl_shader_compile (self->shader);
if (!cogl_shader_is_compiled (self->shader))
{
gchar *log_buf = cogl_shader_get_info_log (self->shader);
g_warning (G_STRLOC ": Unable to compile the contrast effects shader: %s",
log_buf);
g_free (log_buf);
cogl_handle_unref (self->shader);
cogl_handle_unref (self->program);
self->shader = COGL_INVALID_HANDLE;
self->program = COGL_INVALID_HANDLE;
}
else
{
cogl_program_attach_shader (self->program, self->shader);
cogl_program_link (self->program);
cogl_handle_unref (self->shader);
self->is_compiled = TRUE;
self->tex_uniform =
cogl_program_get_uniform_location (self->program, "tex");
self->contrast_uniform =
cogl_program_get_uniform_location (self->program, "contrast");
}
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_contrast_effect_parent_class);
return parent_class->pre_paint (effect);
}
static void
clutter_contrast_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterContrastEffect *self = CLUTTER_CONTRAST_EFFECT (effect);
ClutterOffscreenEffectClass *parent;
CoglHandle material;
if (self->program == COGL_INVALID_HANDLE)
goto out;
if (self->tex_uniform > -1)
cogl_program_set_uniform_1i (self->program, self->tex_uniform, 0);
if (self->contrast_uniform > -1)
{
float contrast[3] = {
(self->contrast.red / 255.0) - 0.5,
(self->contrast.green / 255.0) - 0.5,
(self->contrast.blue / 255.0) - 0.5
};
cogl_program_set_uniform_float (self->program, self->contrast_uniform,
3, 1,
contrast);
}
material = clutter_offscreen_effect_get_target (effect);
cogl_material_set_user_program (material, self->program);
out:
parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_contrast_effect_parent_class);
parent->paint_target (effect);
}
static void
clutter_contrast_effect_dispose (GObject *gobject)
{
ClutterContrastEffect *self = CLUTTER_CONTRAST_EFFECT (gobject);
if (self->program != COGL_INVALID_HANDLE)
{
cogl_handle_unref (self->program);
self->program = COGL_INVALID_HANDLE;
self->shader = COGL_INVALID_HANDLE;
}
self->actor = NULL;
G_OBJECT_CLASS (clutter_contrast_effect_parent_class)->dispose (gobject);
}
static void
clutter_contrast_effect_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterContrastEffect *effect = CLUTTER_CONTRAST_EFFECT (gobject);
switch (prop_id)
{
case PROP_CONTRAST:
clutter_contrast_effect_set_contrast (effect,
clutter_value_get_color (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_contrast_effect_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterContrastEffect *effect = CLUTTER_CONTRAST_EFFECT (gobject);
ClutterColor contrast;
switch (prop_id)
{
case PROP_CONTRAST:
clutter_contrast_effect_get_contrast (effect, &contrast);
clutter_value_set_color (value, &contrast);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_contrast_effect_class_init (ClutterContrastEffectClass *klass)
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->paint_target = clutter_contrast_effect_paint_target;
effect_class->pre_paint = clutter_contrast_effect_pre_paint;
gobject_class->set_property = clutter_contrast_effect_set_property;
gobject_class->get_property = clutter_contrast_effect_get_property;
gobject_class->dispose = clutter_contrast_effect_dispose;
/**
* ClutterContrastEffect:contrast:
*
* The contrast change to apply to the actor
*
* Since: 1.10
*/
obj_props[PROP_CONTRAST] =
clutter_param_spec_color ("contrast",
P_("Contrast"),
P_("The contrast change to apply"),
&same_contrast,
G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
}
static void
clutter_contrast_effect_init (ClutterContrastEffect *self)
{
self->contrast = same_contrast;
}
/**
* clutter_contrast_effect_new:
*
* Creates a new #ClutterContrastEffect to be used with
* clutter_actor_add_effect()
*
* Return value: (transfer full): the newly created #ClutterContrastEffect or
* %NULL. User g_object_unref() when done.
*
* Since: 1.10
*/
ClutterEffect *
clutter_contrast_effect_new (void)
{
return g_object_new (CLUTTER_TYPE_CONTRAST_EFFECT,
NULL);
}
/**
* clutter_contrast_effect_set_contrast:
* @effect: a #ClutterContrastEffect
* @contrast: A ClutterColor governing the change in contrast.
*
* Add or subtract each of the red, green, blue components of the @contrast to
* the red, greeen, or blue component of the actor's colors. If the actor's
* color is less than the midpoint, subtract the contrast; otherwise, add the
* contrast.
*
* Since: 1.10
*/
void
clutter_contrast_effect_set_contrast (ClutterContrastEffect *effect,
const ClutterColor *contrast)
{
g_return_if_fail (CLUTTER_IS_CONTRAST_EFFECT (effect));
if (clutter_color_equal (&effect->contrast, contrast))
return;
effect->contrast = *contrast;
if (effect->actor != NULL)
clutter_actor_queue_redraw (effect->actor);
}
/**
* clutter_contrast_effect_get_contrast:
* @effect: a #ClutterContrastEffect
* @contrast: (out caller-allocates): return location for the contrast change.
*
* Retrieves the contrast value used by @effect
*
* Since 1.10
*/
void
clutter_contrast_effect_get_contrast (ClutterContrastEffect *effect,
ClutterColor *contrast)
{
g_return_if_fail (CLUTTER_IS_CONTRAST_EFFECT (effect));
g_return_if_fail (contrast != NULL);
*contrast = effect->contrast;
}

View File

@ -0,0 +1,63 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010, 2011 Inclusive Design Research Centre, OCAD University.
*
* 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:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_CONTRAST_EFFECT_H__
#define __CLUTTER_CONTRAST_EFFECT_H__
#include <clutter/clutter-color.h>
#include <clutter/clutter-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CONTRAST_EFFECT (clutter_contrast_effect_get_type ())
#define CLUTTER_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONTRAST_EFFECT, ClutterContrastEffect))
#define CLUTTER_IS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTRAST_EFFECT))
/**
* ClutterContrastEffect:
*
* <structname>ClutterContrastEffect</structname> is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.10
*/
typedef struct _ClutterContrastEffect ClutterContrastEffect;
typedef struct _ClutterContrastEffectClass ClutterContrastEffectClass;
GType clutter_contrast_effect_get_type (void) G_GNUC_CONST;
ClutterEffect *clutter_contrast_effect_new (void);
void clutter_contrast_effect_set_contrast (ClutterContrastEffect *effect,
const ClutterColor *contrast);
void clutter_contrast_effect_get_contrast (ClutterContrastEffect *effect,
ClutterColor *contrast);
G_END_DECLS
#endif /* __CLUTTER_CONTRAST_EFFECT_H__ */

View File

@ -0,0 +1,243 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010, 2011 Inclusive Design Research Centre, OCAD University.
*
* 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:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
/**
* SECTION:clutter-invert-lightness-effect
* @short_description: A colorization effect where lightness is inverted but
* color is not.
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
*
* #ClutterInvertLightnessEffect is a sub-class of #ClutterEffect that enhances
* the appearance of a clutter actor. Specifically it inverts the lightness
* of a #ClutterActor (e.g., darker colors become lighter, white becomes black,
* and white, black).
*
* #ClutterInvertLightnessEffect is available since Clutter 1.10
*/
#define CLUTTER_INVERT_LIGHTNESS_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT, ClutterInvertLightnessEffectClass))
#define CLUTTER_IS_INVERT_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT))
#define CLUTTER_INVERT_LIGHTNESS_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_INVERT_LIGHTNESS_EFFEC, ClutterInvertLightnessEffectClass))
#include "clutter-invert-lightness-effect.h"
#include "clutter-actor.h"
#include "clutter-feature.h"
#include "clutter-offscreen-effect.h"
struct _ClutterInvertLightnessEffect
{
ClutterOffscreenEffect parent_instance;
/* a back pointer to our actor, so that we can query it */
ClutterActor *actor;
CoglHandle shader;
CoglHandle program;
gint tex_uniform;
guint is_compiled : 1;
};
struct _ClutterInvertLightnessEffectClass
{
ClutterOffscreenEffectClass parent_class;
};
/* Lightness inversion in GLSL.
*/
static const gchar *invert_lightness_glsl_shader =
"uniform sampler2D tex;\n"
"\n"
"void main ()\n"
"{\n"
" vec4 color = cogl_color_in * texture2D (tex, vec2 (cogl_tex_coord_in[0].xy));\n"
" vec3 effect = vec3 (color);\n"
"\n"
" float maxColor = max (color.r, max (color.g, color.b));\n"
" float minColor = min (color.r, min (color.g, color.b));\n"
" float lightness = (maxColor + minColor) / 2.0;\n"
"\n"
" float delta = (1.0 - lightness) - lightness;\n"
" effect.rgb = (effect.rgb + delta);\n"
"\n"
" cogl_color_out = vec4 (effect, color.a);\n"
"}\n";
G_DEFINE_TYPE (ClutterInvertLightnessEffect,
clutter_invert_lightness_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean
clutter_invert_lightness_effect_pre_paint (ClutterEffect *effect)
{
ClutterInvertLightnessEffect *self = CLUTTER_INVERT_LIGHTNESS_EFFECT (effect);
ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (self->actor == NULL)
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
if (self->shader == COGL_INVALID_HANDLE)
{
self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT);
cogl_shader_source (self->shader, invert_lightness_glsl_shader);
self->is_compiled = FALSE;
self->tex_uniform = -1;
}
if (self->program == COGL_INVALID_HANDLE)
self->program = cogl_create_program ();
if (!self->is_compiled)
{
g_assert (self->shader != COGL_INVALID_HANDLE);
g_assert (self->program != COGL_INVALID_HANDLE);
cogl_shader_compile (self->shader);
if (!cogl_shader_is_compiled (self->shader))
{
gchar *log_buf = cogl_shader_get_info_log (self->shader);
g_warning (G_STRLOC ": Unable to compile the invert-lightness effects shader: %s",
log_buf);
g_free (log_buf);
cogl_handle_unref (self->shader);
cogl_handle_unref (self->program);
self->shader = COGL_INVALID_HANDLE;
self->program = COGL_INVALID_HANDLE;
}
else
{
cogl_program_attach_shader (self->program, self->shader);
cogl_program_link (self->program);
cogl_handle_unref (self->shader);
self->is_compiled = TRUE;
self->tex_uniform =
cogl_program_get_uniform_location (self->program, "tex");
}
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_invert_lightness_effect_parent_class);
return parent_class->pre_paint (effect);
}
static void
clutter_invert_lightness_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterInvertLightnessEffect *self = CLUTTER_INVERT_LIGHTNESS_EFFECT (effect);
ClutterOffscreenEffectClass *parent;
CoglHandle material;
if (self->program == COGL_INVALID_HANDLE)
goto out;
if (self->tex_uniform > -1)
cogl_program_set_uniform_1i (self->program, self->tex_uniform, 0);
material = clutter_offscreen_effect_get_target (effect);
cogl_material_set_user_program (material, self->program);
out:
parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_invert_lightness_effect_parent_class);
parent->paint_target (effect);
}
static void
clutter_invert_lightness_effect_dispose (GObject *gobject)
{
ClutterInvertLightnessEffect *self = CLUTTER_INVERT_LIGHTNESS_EFFECT (gobject);
if (self->program != COGL_INVALID_HANDLE)
{
cogl_handle_unref (self->program);
self->program = COGL_INVALID_HANDLE;
self->shader = COGL_INVALID_HANDLE;
}
self->actor = NULL;
G_OBJECT_CLASS (clutter_invert_lightness_effect_parent_class)->dispose (gobject);
}
static void
clutter_invert_lightness_effect_class_init (ClutterInvertLightnessEffectClass *klass)
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->paint_target = clutter_invert_lightness_effect_paint_target;
effect_class->pre_paint = clutter_invert_lightness_effect_pre_paint;
gobject_class->dispose = clutter_invert_lightness_effect_dispose;
}
static void
clutter_invert_lightness_effect_init (ClutterInvertLightnessEffect *self)
{
}
/**
* clutter_invert_lightness_effect_new:
*
* Creates a new #ClutterInvertLightnessEffect to be used with
* clutter_actor_add_effect()
*
* Return value: (transfer full): the newly created
* #ClutterInvertLightnessEffect or %NULL. Use g_object_unref() when done.
*
* Since: 1.10
*/
ClutterEffect *
clutter_invert_lightness_effect_new (void)
{
return g_object_new (CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT,
NULL);
}

View File

@ -0,0 +1,57 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010, 2011 Inclusive Design Research Centre, OCAD University.
*
* 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:
* Joseph Scheuhammer <clown@alum.mit.edu>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_INVERT_LIGHTNESS_EFFECT_H__
#define __CLUTTER_INVERT_LIGHTNESS_EFFECT_H__
#include <clutter/clutter-effect.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT (clutter_invert_lightness_effect_get_type ())
#define CLUTTER_INVERT_LIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT, ClutterInvertLightnessEffect))
#define CLUTTER_IS_INVERT_LIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT))
/**
* ClutterInvertLightnessEffect:
*
* <structname>ClutterInvertLightnessEffect</structname> is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.10
*/
typedef struct _ClutterInvertLightnessEffect ClutterInvertLightnessEffect;
typedef struct _ClutterInvertLightnessEffectClass ClutterInvertLightnessEffectClass;
GType clutter_invert_lightness_effect_get_type (void) G_GNUC_CONST;
ClutterEffect *clutter_invert_lightness_effect_new (void);
G_END_DECLS
#endif /* __CLUTTER_INVERT_LIGHTNESS_EFFECT_H__ */

View File

@ -120,8 +120,11 @@
<xi:include href="xml/clutter-deform-effect.xml"/>
<xi:include href="xml/clutter-blur-effect.xml"/>
<xi:include href="xml/clutter-brightness-effect.xml"/>
<xi:include href="xml/clutter-colorize-effect.xml"/>
<xi:include href="xml/clutter-contrast-effect.xml"/>
<xi:include href="xml/clutter-desaturate-effect.xml"/>
<xi:include href="xml/clutter-invert-lightness-effect.xml"/>
<xi:include href="xml/clutter-page-turn-effect.xml"/>
</chapter>

View File

@ -2640,6 +2640,53 @@ ClutterPageTurnEffectClass
clutter_page_turn_effect_get_type
</SECTION>
<SECTION>
<TITLE>ClutterBrightnessEffect</TITLE>
<FILE>clutter-brightness-effect</FILE>
ClutterBrightnessEffect
clutter_brightness_effect_new
clutter_brightness_effect_set_brightness
clutter_brightness_effect_get_brightness
<SUBSECTION Standard>
CLUTTER_TYPE_BRIGHTNESS_EFFECT
CLUTTER_BRIGHTNESS_EFFECT
CLUTTER_IS_BRIGHTNESS_EFFECT
<SUBSECTION Private>
ClutterBrightnessEffectClass
clutter_brightness_effect_get_type
</SECTION>
<SECTION>
<TITLE>ClutterContrastEffect</TITLE>
<FILE>clutter-contrast-effect</FILE>
ClutterContrastEffect
clutter_contrast_effect_new
clutter_contrast_effect_set_contrast
clutter_contrast_effect_get_contrast
<SUBSECTION Standard>
CLUTTER_TYPE_CONTRAST_EFFECT
CLUTTER_CONTRAST_EFFECT
CLUTTER_IS_CONTRAST_EFFECT
<SUBSECTION Private>
ClutterContrastEffectClass
clutter_contrast_effect_get_type
</SECTION>
<SECTION>
<TITLE>ClutterInvertLightnessEffect</TITLE>
<FILE>clutter-invert-lightness-effect</FILE>
ClutterInvertLightnessEffect
clutter_contrast_effect_new
<SUBSECTION Standard>
CLUTTER_TYPE_INVERT_LIGHTNESS_EFFECT
CLUTTER_INVERT_LIGHTNESS_EFFECT
CLUTTER_IS_INVERT_LIGHTNESS_EFFECT
<SUBSECTION Private>
ClutterInvertLightnessEffectClass
clutter_invert_lightness_effect_get_type
</SECTION>
<SECTION>
<FILE>clutter-settings</FILE>
ClutterSettings

View File

@ -21,12 +21,14 @@ clutter_bin_layout_get_type
clutter_blur_effect_get_type
clutter_box_get_type
clutter_box_layout_get_type
clutter_brightness_effect_get_type
clutter_cairo_texture_get_type
clutter_child_meta_get_type
clutter_click_action_get_type
clutter_clone_get_type
clutter_colorize_effect_get_type
clutter_constraint_get_type
clutter_contrast_effect_get_type
clutter_deform_effect_get_type
clutter_desaturate_effect_get_type
clutter_device_manager_get_type
@ -39,6 +41,7 @@ clutter_gesture_action_get_type
clutter_group_get_type
clutter_input_device_get_type
clutter_interval_get_type
clutter_invert_lightness_effect_get_type
clutter_layout_manager_get_type
clutter_layout_meta_get_type
clutter_list_model_get_type