Exemple #1
0
static void
setup_pipeline_from_cache_entry (CoglGstVideoSink *sink,
                                 CoglPipeline *pipeline,
                                 SnippetCacheEntry *cache_entry,
                                 int n_layers)
{
  CoglGstVideoSinkPrivate *priv = sink->priv;

  if (cache_entry)
    {
      int i;

      /* The global sampling function gets added to both the fragment
       * and vertex stages. The hope is that the GLSL compiler will
       * easily remove the dead code if it's not actually used */
      cogl_pipeline_add_snippet (pipeline, cache_entry->vertex_snippet);
      cogl_pipeline_add_snippet (pipeline, cache_entry->fragment_snippet);

      /* Set all of the layers to just directly copy from the previous
       * layer so that it won't redundantly generate code to sample
       * the intermediate textures */
      for (i = 0; i < n_layers; i++)
        cogl_pipeline_set_layer_combine (pipeline,
                                         priv->custom_start + i,
                                         "RGBA=REPLACE(PREVIOUS)",
                                         NULL);

      if (priv->default_sample)
        cogl_pipeline_add_layer_snippet (pipeline,
                                         priv->custom_start + n_layers - 1,
                                         cache_entry->default_sample_snippet);
    }

  priv->frame_dirty = TRUE;
}
static void
shell_anamorphosis_effect_init (ShellAnamorphosisEffect *self)
{
  static CoglPipeline *pipeline_template;

  ShellAnamorphosisEffectPrivate *priv = shell_anamorphosis_effect_get_instance_private (self);

  if (G_UNLIKELY (pipeline_template == NULL))
    {
      CoglSnippet *snippet;
      CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());

      pipeline_template = cogl_pipeline_new (ctx);

      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, anamorphosis_decls, NULL);
      cogl_snippet_set_pre (snippet, anamorphosis_pre);
      cogl_pipeline_add_layer_snippet (pipeline_template, 0, snippet);
      cogl_object_unref (snippet);

      cogl_pipeline_set_layer_null_texture (pipeline_template,
                                            0, /* layer number */
                                            COGL_TEXTURE_TYPE_2D);
    }

  priv->pipeline = cogl_pipeline_copy (pipeline_template);
  priv->tex_width_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "tex_width");
  priv->tex_height_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "tex_height");
  priv->_x_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "_x");
  priv->_y_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "_y");
  priv->_z_uniform = cogl_pipeline_get_uniform_location (priv->pipeline, "_z");

  update_uniforms (self);
}
/**
 * shell_glsl_quad_add_glsl_snippet:
 * @quad: a #ShellGLSLQuad
 * @hook: where to insert the code
 * @declarations: GLSL declarations
 * @code: GLSL code
 * @is_replace: wheter Cogl code should be replaced by the custom shader
 *
 * Adds a GLSL snippet to the pipeline used for drawing the actor texture.
 * See #CoglSnippet for details.
 *
 * This is only valid inside the a call to the build_pipeline() virtual
 * function.
 */
void
shell_glsl_quad_add_glsl_snippet (ShellGLSLQuad    *quad,
                                  ShellSnippetHook  hook,
                                  const char       *declarations,
                                  const char       *code,
                                  gboolean          is_replace)
{
  ShellGLSLQuadClass *klass = SHELL_GLSL_QUAD_GET_CLASS (quad);
  CoglSnippet *snippet;

  g_return_if_fail (klass->base_pipeline != NULL);

  if (is_replace)
    {
      snippet = cogl_snippet_new ((CoglSnippetHook)hook, declarations, NULL);
      cogl_snippet_set_replace (snippet, code);
    }
  else
    {
      snippet = cogl_snippet_new ((CoglSnippetHook)hook, declarations, code);
    }

  if (hook == SHELL_SNIPPET_HOOK_VERTEX ||
      hook == SHELL_SNIPPET_HOOK_FRAGMENT)
    cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
  else
    cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);

  cogl_object_unref (snippet);
}
static void
st_background_effect_init (StBackgroundEffect *self)
{
  CoglContext *ctx;
  StBackgroundEffectClass *klass = ST_BACKGROUND_EFFECT_GET_CLASS (self);

  if (G_UNLIKELY (klass->base_pipeline == NULL))
    {
      ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());

      klass->base_pipeline = cogl_pipeline_new (ctx);
    }
    
  self->pipeline0 = cogl_pipeline_copy (klass->base_pipeline);
  self->pipeline1 = cogl_pipeline_copy (klass->base_pipeline);
  self->pipeline2 = cogl_pipeline_copy (klass->base_pipeline);
  self->pipeline3 = cogl_pipeline_copy (klass->base_pipeline);
  self->pipeline4 = cogl_pipeline_copy (klass->base_pipeline);

  CoglSnippet *snippet;
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
                              box_blur_glsl_declarations,
                              NULL);

  cogl_snippet_set_replace (snippet, box_blur_glsl_shader);
  cogl_pipeline_add_layer_snippet (self->pipeline0, 0, snippet);
  cogl_pipeline_add_layer_snippet (self->pipeline1, 0, snippet);
  cogl_pipeline_add_layer_snippet (self->pipeline3, 0, snippet);
  cogl_object_unref (snippet);

  cogl_pipeline_set_layer_wrap_mode (self->pipeline0, 0,
                                     COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);

  cogl_pipeline_set_layer_wrap_mode (self->pipeline0, 1,
                                     COGL_PIPELINE_WRAP_MODE_REPEAT);

  cogl_pipeline_set_layer_wrap_mode (self->pipeline1, 0,
                                     COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);

  cogl_pipeline_set_layer_wrap_mode (self->pipeline2, 0,
                                     COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);

  cogl_pipeline_set_layer_wrap_mode (self->pipeline3, 0,
                                     COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);

  cogl_pipeline_set_layer_wrap_mode (self->pipeline4, 0,
                                     COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);

  cogl_pipeline_set_cull_face_mode (self->pipeline0,
                                    COGL_PIPELINE_CULL_FACE_MODE_NONE);

  cogl_pipeline_set_cull_face_mode (self->pipeline1,
                                    COGL_PIPELINE_CULL_FACE_MODE_NONE);

  cogl_pipeline_set_cull_face_mode (self->pipeline2,
                                    COGL_PIPELINE_CULL_FACE_MODE_NONE);

  cogl_pipeline_set_cull_face_mode (self->pipeline3,
                                    COGL_PIPELINE_CULL_FACE_MODE_NONE);

  cogl_pipeline_set_cull_face_mode (self->pipeline4,
                                    COGL_PIPELINE_CULL_FACE_MODE_NONE);

  cogl_pipeline_set_layer_filters (self->pipeline0, 0,
                                   COGL_PIPELINE_FILTER_LINEAR,
                                   COGL_PIPELINE_FILTER_LINEAR);

  cogl_pipeline_set_layer_filters (self->pipeline0, 1,
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);

  cogl_pipeline_set_layer_filters (self->pipeline1, 0,
                                   COGL_PIPELINE_FILTER_LINEAR,
                                   COGL_PIPELINE_FILTER_LINEAR);

  cogl_pipeline_set_layer_filters (self->pipeline2, 0,
                                   COGL_PIPELINE_FILTER_LINEAR,
                                   COGL_PIPELINE_FILTER_LINEAR);

  cogl_pipeline_set_layer_filters (self->pipeline3, 0,
                                   COGL_PIPELINE_FILTER_LINEAR,
                                   COGL_PIPELINE_FILTER_LINEAR);

  cogl_pipeline_set_layer_filters (self->pipeline4, 0,
                                   COGL_PIPELINE_FILTER_LINEAR,
                                   COGL_PIPELINE_FILTER_LINEAR);

  cogl_pipeline_set_layer_null_texture (self->pipeline0,
                                        0,
                                        COGL_TEXTURE_TYPE_2D);

  cogl_pipeline_set_layer_null_texture (self->pipeline1,
                                        0,
                                        COGL_TEXTURE_TYPE_2D);

  cogl_pipeline_set_layer_null_texture (self->pipeline2,
                                        0,
                                        COGL_TEXTURE_TYPE_2D);

  cogl_pipeline_set_layer_null_texture (self->pipeline3,
                                        0,
                                        COGL_TEXTURE_TYPE_2D);
  
  cogl_pipeline_set_layer_null_texture (self->pipeline4,
                                        0,
                                        COGL_TEXTURE_TYPE_2D);

  self->pixel_step_uniform0 =
    cogl_pipeline_get_uniform_location (self->pipeline0, "pixel_step");

  self->BumpTex_uniform =
    cogl_pipeline_get_uniform_location (self->pipeline0, "BumpTex");

  self->bump_step_uniform =
    cogl_pipeline_get_uniform_location (self->pipeline0, "bump_step");

  self->pixel_step_uniform1 =
    cogl_pipeline_get_uniform_location (self->pipeline1, "pixel_step");

  self->pixel_step_uniform2 =
    cogl_pipeline_get_uniform_location (self->pipeline3, "pixel_step");

  cogl_pipeline_set_blend (self->pipeline0,
                           "RGBA = ADD(SRC_COLOR, DST_COLOR*0)",
                           NULL);

  cogl_pipeline_set_blend (self->pipeline1,
                           "RGBA = ADD (SRC_COLOR*DST_COLOR[A], DST_COLOR*(1-DST_COLOR[A]))",
                           NULL);

  cogl_pipeline_set_color4ub (self->pipeline1,
                              0xff,
                              0xff,
                              0xff,
                              0xff);

  cogl_pipeline_set_alpha_test_function (self->pipeline2,
                                         COGL_PIPELINE_ALPHA_FUNC_LESS,
                                         0.004f);

  cogl_pipeline_set_color_mask (self->pipeline2,
                                COGL_COLOR_MASK_ALPHA);

  cogl_pipeline_set_blend (self->pipeline2,
                           "RGBA = ADD(SRC_COLOR, DST_COLOR*0)",
                           NULL);

  cogl_pipeline_set_alpha_test_function (self->pipeline3,
                                         COGL_PIPELINE_ALPHA_FUNC_GEQUAL,
                                         0.004f);
    
  cogl_pipeline_set_color_mask (self->pipeline3,
                                COGL_COLOR_MASK_ALL);

  cogl_pipeline_set_blend (self->pipeline3,
                           "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))",
                           NULL);

  cogl_pipeline_set_alpha_test_function (self->pipeline4,
                                         COGL_PIPELINE_ALPHA_FUNC_GEQUAL,
                                         0.004f);
    
  cogl_pipeline_set_color_mask (self->pipeline4,
                                COGL_COLOR_MASK_ALL);

  cogl_pipeline_set_blend (self->pipeline4,
                           "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))",
                           NULL);


  self->bg_texture = NULL;

  self->bg_sub_texture = NULL;

  self->bumpmap_location = "/usr/share/cinnamon/bumpmaps/frost.png";

  self->bg_bumpmap = st_cogl_texture_new_from_file_wrapper (self->bumpmap_location,
                                                            COGL_TEXTURE_NO_SLICING,
                                                            COGL_PIXEL_FORMAT_RGBA_8888_PRE);
  if (self->bg_bumpmap != NULL)
    {
      self->bumptex_width_i = cogl_texture_get_width (self->bg_bumpmap);
      self->bumptex_height_i = cogl_texture_get_height (self->bg_bumpmap);

      cogl_pipeline_set_layer_texture (self->pipeline0, 1, self->bg_bumpmap);
    }
  else
    {
      cogl_pipeline_set_layer_null_texture (self->pipeline0,
                                            1,
                                            COGL_TEXTURE_TYPE_2D);
    }

  cogl_pipeline_set_layer_combine (self->pipeline0,1,
                                   "RGBA = REPLACE (PREVIOUS)",
                                   NULL);

  self->old_time = 0;

  self->opacity = 0;

}
static CoglPipeline *
create_1d_gaussian_blur_pipeline (RutContext *ctx, int n_taps)
{
  static GHashTable *pipeline_cache = NULL;
  CoglPipeline *pipeline;
  CoglSnippet *snippet;
  GString *shader;
  CoglDepthState depth_state;
  int i;

  /* initialize the pipeline cache. The shaders are only dependent on the
   * number of taps, not the sigma, so we cache the corresponding pipelines
   * in a hash table 'n_taps' => 'pipeline' */
  if (G_UNLIKELY (pipeline_cache == NULL))
    {
      pipeline_cache =
        g_hash_table_new_full (g_direct_hash,
                               g_direct_equal,
                               NULL, /* key destroy notify */
                               (GDestroyNotify) cogl_object_unref);
    }

  pipeline = g_hash_table_lookup (pipeline_cache, GINT_TO_POINTER (n_taps));
  if (pipeline)
    return cogl_object_ref (pipeline);

  shader = g_string_new (NULL);

  g_string_append_printf (shader,
                          "uniform vec2 pixel_step;\n"
                          "uniform float factors[%i];\n",
                          n_taps);

  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
                              shader->str,
                              NULL /* post */);

  g_string_set_size (shader, 0);

  pipeline = cogl_pipeline_new (ctx->cogl_context);
  cogl_pipeline_set_layer_null_texture (pipeline,
                                        0, /* layer_num */
                                        COGL_TEXTURE_TYPE_2D);
  cogl_pipeline_set_layer_wrap_mode (pipeline,
                                     0, /* layer_num */
                                     COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
  cogl_pipeline_set_layer_filters (pipeline,
                                   0, /* layer_num */
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);

  for (i = 0; i < n_taps; i++)
    {
      g_string_append (shader, "cogl_texel ");

      if (i == 0)
        g_string_append (shader, "=");
      else
        g_string_append (shader, "+=");

      g_string_append_printf (shader,
                              " texture2D (cogl_sampler, "
                              "cogl_tex_coord.st");
      if (i != (n_taps - 1) / 2)
        g_string_append_printf (shader,
                                " + pixel_step * %f",
                                (float) (i - ((n_taps - 1) / 2)));
      g_string_append_printf (shader,
                              ") * factors[%i];\n",
                              i);
    }

  cogl_snippet_set_replace (snippet, shader->str);

  g_string_free (shader, TRUE);

  cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);

  cogl_object_unref (snippet);

  cogl_pipeline_set_blend (pipeline, "RGBA=ADD(SRC_COLOR, 0)", NULL);

  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_write_enabled (&depth_state, FALSE);
  cogl_depth_state_set_test_enabled (&depth_state, FALSE);
  cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);

  g_hash_table_insert (pipeline_cache, GINT_TO_POINTER (n_taps), pipeline);

  return pipeline;
}
Exemple #6
0
static void
do_test (CoglBool check_orientation,
         CoglBool use_glsl)
{
  int fb_width = cogl_framebuffer_get_width (test_fb);
  int fb_height = cogl_framebuffer_get_height (test_fb);
  CoglPrimitive *prim;
  CoglError *error = NULL;
  CoglTexture2D *tex_2d;
  CoglPipeline *pipeline, *solid_pipeline;
  int tex_height;

  cogl_framebuffer_orthographic (test_fb,
                                 0, 0, /* x_1, y_1 */
                                 fb_width, /* x_2 */
                                 fb_height /* y_2 */,
                                 -1, 100 /* near/far */);

  cogl_framebuffer_clear4f (test_fb,
                            COGL_BUFFER_BIT_COLOR,
                            1.0f, 1.0f, 1.0f, 1.0f);

  /* If we're not checking the orientation of the point sprite then
   * we'll set the height of the texture to 1 so that the vertical
   * orientation does not matter */
  if (check_orientation)
    tex_height = 2;
  else
    tex_height = 1;

  tex_2d = cogl_texture_2d_new_from_data (test_ctx,
                                          2, tex_height, /* width/height */
                                          COGL_PIXEL_FORMAT_RGB_888,
                                          COGL_PIXEL_FORMAT_ANY,
                                          6, /* row stride */
                                          tex_data,
                                          &error);
  g_assert (tex_2d != NULL);
  g_assert (error == NULL);

  pipeline = cogl_pipeline_new (test_ctx);
  cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d);

  cogl_pipeline_set_layer_filters (pipeline,
                                   0, /* layer_index */
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);
  cogl_pipeline_set_point_size (pipeline, POINT_SIZE);

  /* If we're using GLSL then we don't need to enable point sprite
   * coords and we can just directly reference cogl_point_coord in the
   * snippet */
  if (use_glsl)
    {
      CoglSnippet *snippet =
        cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
                          NULL, /* declarations */
                          NULL /* post */);
      static const char source[] =
        "  cogl_texel = texture2D (cogl_sampler, cogl_point_coord);\n";

      cogl_snippet_set_replace (snippet, source);

      /* Keep a reference to the original pipeline because there is no
       * way to remove a snippet in order to recreate the solid
       * pipeline */
      solid_pipeline = cogl_pipeline_copy (pipeline);

      cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);

      cogl_object_unref (snippet);
    }
  else
    {
      CoglBool res =
        cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline,
                                                             /* layer_index */
                                                             0,
                                                             /* enable */
                                                             TRUE,
                                                             &error);
      g_assert (res == TRUE);
      g_assert (error == NULL);

      solid_pipeline = cogl_pipeline_copy (pipeline);

      res =
        cogl_pipeline_set_layer_point_sprite_coords_enabled (solid_pipeline,
                                                             /* layer_index */
                                                             0,
                                                             /* enable */
                                                             FALSE,
                                                             &error);

      g_assert (res == TRUE);
      g_assert (error == NULL);
    }

  prim = cogl_primitive_new_p2t2 (test_ctx,
                                  COGL_VERTICES_MODE_POINTS,
                                  1, /* n_vertices */
                                  &point);

  cogl_primitive_draw (prim, test_fb, pipeline);

  /* Render the primitive again without point sprites to make sure
     disabling it works */

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              POINT_SIZE * 2, /* x */
                              0.0f, /* y */
                              0.0f /* z */);
  cogl_primitive_draw (prim, test_fb, solid_pipeline);
  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (prim);
  cogl_object_unref (solid_pipeline);
  cogl_object_unref (pipeline);
  cogl_object_unref (tex_2d);

  test_utils_check_pixel (test_fb,
                          POINT_SIZE - POINT_SIZE / 4,
                          POINT_SIZE - POINT_SIZE / 4,
                          0x0000ffff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE + POINT_SIZE / 4,
                          POINT_SIZE - POINT_SIZE / 4,
                          0x00ff00ff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE - POINT_SIZE / 4,
                          POINT_SIZE + POINT_SIZE / 4,
                          check_orientation ?
                          0x00ffffff :
                          0x0000ffff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE + POINT_SIZE / 4,
                          POINT_SIZE + POINT_SIZE / 4,
                          check_orientation ?
                          0xff0000ff :
                          0x00ff00ff);

  /* When rendering without the point sprites all of the texture
     coordinates should be 0,0 so it should get the top-left texel
     which is blue */
  test_utils_check_region (test_fb,
                           POINT_SIZE * 3 - POINT_SIZE / 2 + 1,
                           POINT_SIZE - POINT_SIZE / 2 + 1,
                           POINT_SIZE - 2, POINT_SIZE - 2,
                           0x0000ffff);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}