|
Packit |
31ecd5 |
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
|
Packit |
31ecd5 |
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
|
Packit |
31ecd5 |
#include <clutter/clutter.h>
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/****************************************************************
|
|
Packit |
31ecd5 |
Old style shader effect
|
|
Packit |
31ecd5 |
This uses clutter_shader_effect_set_source
|
|
Packit |
31ecd5 |
****************************************************************/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static const gchar
|
|
Packit |
31ecd5 |
old_shader_effect_source[] =
|
|
Packit |
31ecd5 |
"uniform vec3 override_color;\n"
|
|
Packit |
31ecd5 |
"\n"
|
|
Packit |
31ecd5 |
"void\n"
|
|
Packit |
31ecd5 |
"main ()\n"
|
|
Packit |
31ecd5 |
"{\n"
|
|
Packit |
31ecd5 |
" cogl_color_out = vec4 (override_color, 1.0);\n"
|
|
Packit |
31ecd5 |
"}";
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
typedef struct _FooOldShaderEffectClass
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffectClass parent_class;
|
|
Packit |
31ecd5 |
} FooOldShaderEffectClass;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
typedef struct _FooOldShaderEffect
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffect parent;
|
|
Packit |
31ecd5 |
} FooOldShaderEffect;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
GType foo_old_shader_effect_get_type (void);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
G_DEFINE_TYPE (FooOldShaderEffect,
|
|
Packit |
31ecd5 |
foo_old_shader_effect,
|
|
Packit |
31ecd5 |
CLUTTER_TYPE_SHADER_EFFECT);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
|
|
Packit |
31ecd5 |
old_shader_effect_source);
|
|
Packit |
31ecd5 |
clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
|
|
Packit |
31ecd5 |
"override_color",
|
|
Packit |
31ecd5 |
G_TYPE_FLOAT, 3,
|
|
Packit |
31ecd5 |
1.0f, 0.0f, 0.0f);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)->
|
|
Packit |
31ecd5 |
paint_target (effect);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_old_shader_effect_class_init (FooOldShaderEffectClass *klass)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterOffscreenEffectClass *offscreen_effect_class =
|
|
Packit |
31ecd5 |
CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
offscreen_effect_class->paint_target = foo_old_shader_effect_paint_target;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_old_shader_effect_init (FooOldShaderEffect *self)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/****************************************************************
|
|
Packit |
31ecd5 |
New style shader effect
|
|
Packit |
31ecd5 |
This overrides get_static_shader_source()
|
|
Packit |
31ecd5 |
****************************************************************/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static const gchar
|
|
Packit |
31ecd5 |
new_shader_effect_source[] =
|
|
Packit |
31ecd5 |
"uniform vec3 override_color;\n"
|
|
Packit |
31ecd5 |
"\n"
|
|
Packit |
31ecd5 |
"void\n"
|
|
Packit |
31ecd5 |
"main ()\n"
|
|
Packit |
31ecd5 |
"{\n"
|
|
Packit |
31ecd5 |
" cogl_color_out = (vec4 (override_color, 1.0) +\n"
|
|
Packit |
31ecd5 |
" vec4 (0.0, 0.0, 1.0, 0.0));\n"
|
|
Packit |
31ecd5 |
"}";
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
typedef struct _FooNewShaderEffectClass
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffectClass parent_class;
|
|
Packit |
31ecd5 |
} FooNewShaderEffectClass;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
typedef struct _FooNewShaderEffect
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffect parent;
|
|
Packit |
31ecd5 |
} FooNewShaderEffect;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
GType foo_new_shader_effect_get_type (void);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
G_DEFINE_TYPE (FooNewShaderEffect,
|
|
Packit |
31ecd5 |
foo_new_shader_effect,
|
|
Packit |
31ecd5 |
CLUTTER_TYPE_SHADER_EFFECT);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gchar *
|
|
Packit |
31ecd5 |
foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
static gboolean already_called = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* This should only be called once even though we have two actors
|
|
Packit |
31ecd5 |
using this effect */
|
|
Packit |
31ecd5 |
g_assert (!already_called);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
already_called = TRUE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return g_strdup (new_shader_effect_source);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
|
|
Packit |
31ecd5 |
"override_color",
|
|
Packit |
31ecd5 |
G_TYPE_FLOAT, 3,
|
|
Packit |
31ecd5 |
0.0f, 1.0f, 0.0f);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)->
|
|
Packit |
31ecd5 |
paint_target (effect);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_new_shader_effect_class_init (FooNewShaderEffectClass *klass)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterOffscreenEffectClass *offscreen_effect_class =
|
|
Packit |
31ecd5 |
CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
|
Packit |
31ecd5 |
ClutterShaderEffectClass *shader_effect_class =
|
|
Packit |
31ecd5 |
CLUTTER_SHADER_EFFECT_CLASS (klass);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
offscreen_effect_class->paint_target = foo_new_shader_effect_paint_target;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
shader_effect_class->get_static_shader_source =
|
|
Packit |
31ecd5 |
foo_new_shader_effect_get_static_source;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_new_shader_effect_init (FooNewShaderEffect *self)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/****************************************************************
|
|
Packit |
31ecd5 |
Another new style shader effect
|
|
Packit |
31ecd5 |
This is the same but with a different shader. This is just
|
|
Packit |
31ecd5 |
sanity check that each class gets its own copy of the private
|
|
Packit |
31ecd5 |
data
|
|
Packit |
31ecd5 |
****************************************************************/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static const gchar
|
|
Packit |
31ecd5 |
another_new_shader_effect_source[] =
|
|
Packit |
31ecd5 |
"\n"
|
|
Packit |
31ecd5 |
"void\n"
|
|
Packit |
31ecd5 |
"main ()\n"
|
|
Packit |
31ecd5 |
"{\n"
|
|
Packit |
31ecd5 |
" cogl_color_out = vec4 (1.0, 0.0, 1.0, 1.0);\n"
|
|
Packit |
31ecd5 |
"}";
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
typedef struct _FooAnotherNewShaderEffectClass
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffectClass parent_class;
|
|
Packit |
31ecd5 |
} FooAnotherNewShaderEffectClass;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
typedef struct _FooAnotherNewShaderEffect
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffect parent;
|
|
Packit |
31ecd5 |
} FooAnotherNewShaderEffect;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
GType foo_another_new_shader_effect_get_type (void);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
G_DEFINE_TYPE (FooAnotherNewShaderEffect,
|
|
Packit |
31ecd5 |
foo_another_new_shader_effect,
|
|
Packit |
31ecd5 |
CLUTTER_TYPE_SHADER_EFFECT);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gchar *
|
|
Packit |
31ecd5 |
foo_another_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
return g_strdup (another_new_shader_effect_source);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_another_new_shader_effect_class_init (FooAnotherNewShaderEffectClass *klass)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterShaderEffectClass *shader_effect_class =
|
|
Packit |
31ecd5 |
CLUTTER_SHADER_EFFECT_CLASS (klass);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
shader_effect_class->get_static_shader_source =
|
|
Packit |
31ecd5 |
foo_another_new_shader_effect_get_static_source;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
foo_another_new_shader_effect_init (FooAnotherNewShaderEffect *self)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/****************************************************************/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static ClutterActor *
|
|
Packit |
31ecd5 |
make_actor (GType shader_type)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterActor *rect;
|
|
Packit |
31ecd5 |
const ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
rect = clutter_rectangle_new ();
|
|
Packit |
31ecd5 |
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect), &white);
|
|
Packit |
31ecd5 |
clutter_actor_set_size (rect, 50, 50);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
clutter_actor_add_effect (rect, g_object_new (shader_type, NULL));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return rect;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static guint32
|
|
Packit |
31ecd5 |
get_pixel (int x, int y)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
guint8 data[4];
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
cogl_read_pixels (x, y, 1, 1,
|
|
Packit |
31ecd5 |
COGL_READ_PIXELS_COLOR_BUFFER,
|
|
Packit |
31ecd5 |
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
|
Packit |
31ecd5 |
data);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return (((guint32) data[0] << 16) |
|
|
Packit |
31ecd5 |
((guint32) data[1] << 8) |
|
|
Packit |
31ecd5 |
data[2]);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
rpm-build |
2560ec |
after_paint_cb (ClutterStage *stage,
|
|
rpm-build |
2560ec |
gpointer data)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gboolean *was_painted = data;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* old shader effect */
|
|
Packit |
31ecd5 |
g_assert_cmpint (get_pixel (50, 50), ==, 0xff0000);
|
|
Packit |
31ecd5 |
/* new shader effect */
|
|
Packit |
31ecd5 |
g_assert_cmpint (get_pixel (150, 50), ==, 0x00ffff);
|
|
Packit |
31ecd5 |
/* another new shader effect */
|
|
Packit |
31ecd5 |
g_assert_cmpint (get_pixel (250, 50), ==, 0xff00ff);
|
|
Packit |
31ecd5 |
/* new shader effect */
|
|
Packit |
31ecd5 |
g_assert_cmpint (get_pixel (350, 50), ==, 0x00ffff);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
*was_painted = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
rpm-build |
2560ec |
paint_cb (ClutterStage *stage,
|
|
rpm-build |
2560ec |
gpointer data)
|
|
rpm-build |
2560ec |
{
|
|
rpm-build |
2560ec |
g_signal_connect (stage, "after-paint",
|
|
rpm-build |
2560ec |
G_CALLBACK (after_paint_cb),
|
|
rpm-build |
2560ec |
data);
|
|
rpm-build |
2560ec |
}
|
|
rpm-build |
2560ec |
|
|
rpm-build |
2560ec |
static void
|
|
Packit |
31ecd5 |
actor_shader_effect (void)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterActor *stage;
|
|
Packit |
31ecd5 |
ClutterActor *rect;
|
|
Packit |
31ecd5 |
gboolean was_painted;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
stage = clutter_stage_new ();
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
rect = make_actor (foo_old_shader_effect_get_type ());
|
|
Packit |
31ecd5 |
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
rect = make_actor (foo_new_shader_effect_get_type ());
|
|
Packit |
31ecd5 |
clutter_actor_set_x (rect, 100);
|
|
Packit |
31ecd5 |
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
rect = make_actor (foo_another_new_shader_effect_get_type ());
|
|
Packit |
31ecd5 |
clutter_actor_set_x (rect, 200);
|
|
Packit |
31ecd5 |
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
rect = make_actor (foo_new_shader_effect_get_type ());
|
|
Packit |
31ecd5 |
clutter_actor_set_x (rect, 300);
|
|
Packit |
31ecd5 |
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
clutter_actor_show (stage);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
was_painted = FALSE;
|
|
rpm-build |
2560ec |
g_signal_connect (stage, "paint",
|
|
Packit |
31ecd5 |
G_CALLBACK (paint_cb),
|
|
Packit |
31ecd5 |
&was_painted);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
while (!was_painted)
|
|
Packit |
31ecd5 |
g_main_context_iteration (NULL, FALSE);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_TEST_SUITE (
|
|
Packit |
31ecd5 |
CLUTTER_TEST_UNIT ("/actor/shader-effect", actor_shader_effect)
|
|
Packit |
31ecd5 |
)
|