Blame tests/conform/actor-shader-effect.c

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
)