コード例 #1
0
ファイル: cogl-gst-video-sink.c プロジェクト: gcampax/cogl
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;
}
コード例 #2
0
void
test_custom_attributes (void)
{
  /* If shaders aren't supported then we can't run the test */
  if (cogl_has_feature (test_ctx, COGL_FEATURE_ID_GLSL))
    {
      CoglSnippet *snippet;
      TestState state;

      cogl_framebuffer_orthographic (test_fb,
                                     0, 0,
                                     cogl_framebuffer_get_width (test_fb),
                                     cogl_framebuffer_get_height (test_fb),
                                     -1,
                                     100);

      state.pipeline = cogl_pipeline_new (test_ctx);
      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                                  "attribute vec4 color;",
                                  "cogl_color_out = color;");
      cogl_pipeline_add_snippet (state.pipeline, snippet);

      paint (&state);

      cogl_object_unref (state.pipeline);
      cogl_object_unref (snippet);

      if (cogl_test_verbose ())
        g_print ("OK\n");
    }
  else if (cogl_test_verbose ())
    g_print ("Skipping\n");
}
コード例 #3
0
ファイル: cogl-pipeline-cache.c プロジェクト: GNOME/mutter
static void
create_pipelines (CoglPipeline **pipelines,
                  int n_pipelines)
{
  int i;

  for (i = 0; i < n_pipelines; i++)
    {
      char *source = g_strdup_printf ("  cogl_color_out = "
                                      "vec4 (%f, 0.0, 0.0, 1.0);\n",
                                      i / 255.0f);
      CoglSnippet *snippet =
        cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                          NULL, /* declarations */
                          source);

      g_free (source);

      pipelines[i] = cogl_pipeline_new (test_ctx);
      cogl_pipeline_add_snippet (pipelines[i], snippet);
      cogl_object_unref (snippet);
    }

  /* Test that drawing with them works. This should create the entries
   * in the cache */
  for (i = 0; i < n_pipelines; i++)
    {
      cogl_framebuffer_draw_rectangle (test_fb,
                                       pipelines[i],
                                       i, 0,
                                       i + 1, 1);
      test_utils_check_pixel_rgb (test_fb, i, 0, i, 0, 0);
    }

}
コード例 #4
0
ファイル: test-custom-attributes.c プロジェクト: 3v1n0/cogl
void
test_custom_attributes (void)
{
  CoglSnippet *snippet;
  TestState state;

  cogl_framebuffer_orthographic (test_fb,
                                 0, 0,
                                 cogl_framebuffer_get_width (test_fb),
                                 cogl_framebuffer_get_height (test_fb),
                                 -1,
                                 100);

  state.pipeline = cogl_pipeline_new (test_ctx);
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                              "attribute vec4 color;",
                              "cogl_color_out = color;");
  cogl_pipeline_add_snippet (state.pipeline, snippet);

  paint (&state);

  cogl_object_unref (state.pipeline);
  cogl_object_unref (snippet);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
コード例 #5
0
static void
clutter_colorize_effect_init (ClutterColorizeEffect *self)
{
  ClutterColorizeEffectClass *klass = CLUTTER_COLORIZE_EFFECT_GET_CLASS (self);

  if (G_UNLIKELY (klass->base_pipeline == NULL))
    {
      CoglSnippet *snippet;
      CoglContext *ctx =
        clutter_backend_get_cogl_context (clutter_get_default_backend ());

      klass->base_pipeline = cogl_pipeline_new (ctx);

      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                  colorize_glsl_declarations,
                                  colorize_glsl_source);
      cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
      cogl_object_unref (snippet);

      cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
    }

  self->pipeline = cogl_pipeline_copy (klass->base_pipeline);

  self->tint_uniform =
    cogl_pipeline_get_uniform_location (self->pipeline, "tint");

  self->tint = default_tint;

  update_tint_uniform (self);
}
コード例 #6
0
/**
 * 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);
}
コード例 #7
0
static void
clutter_desaturate_effect_init (ClutterDesaturateEffect *self)
{
  ClutterDesaturateEffectClass *klass = CLUTTER_DESATURATE_EFFECT_GET_CLASS (self);

  if (G_UNLIKELY (klass->base_pipeline == NULL))
    {
      CoglContext *ctx =
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
      CoglSnippet *snippet;

      klass->base_pipeline = cogl_pipeline_new (ctx);

      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                  desaturate_glsl_declarations,
                                  desaturate_glsl_source);
      cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
      cogl_object_unref (snippet);

      cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
                                            0, /* layer number */
                                            COGL_TEXTURE_TYPE_2D);
    }

  self->pipeline = cogl_pipeline_copy (klass->base_pipeline);

  self->factor_uniform =
    cogl_pipeline_get_uniform_location (self->pipeline, "factor");

  self->factor = 1.0;

  update_factor_uniform (self);
}
コード例 #8
0
ファイル: test-just-vertex-shader.c プロジェクト: 3v1n0/cogl
static void
paint (TestState *state)
{
  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
  CoglTexture *tex;
  CoglError *error = NULL;
  CoglSnippet *snippet;

  cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

  /* Set the primary vertex color as red */
  cogl_pipeline_set_color4f (pipeline, 1, 0, 0, 1);

  /* Override the vertex color in the texture environment with a
     constant green color provided by a texture */
  tex = create_dummy_texture ();
  cogl_pipeline_set_layer_texture (pipeline, 0, tex);
  cogl_object_unref (tex);
  if (!cogl_pipeline_set_layer_combine (pipeline, 0,
                                        "RGBA=REPLACE(TEXTURE)",
                                        &error))
    {
      g_warning ("Error setting layer combine: %s", error->message);
      g_assert_not_reached ();
    }

  /* Set up a dummy vertex shader that does nothing but the usual
     modelview-projection transform */
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                              NULL, /* no declarations */
                              NULL); /* no "post" code */
  cogl_snippet_set_replace (snippet,
                            "  cogl_position_out = "
                            "cogl_modelview_projection_matrix * "
                            "cogl_position_in;\n"
                            "  cogl_color_out = cogl_color_in;\n"
                            "  cogl_tex_coord0_out = cogl_tex_coord_in;\n");

  /* Draw something without the snippet */
  cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 50, 50);

  /* Draw it again using the snippet. It should look exactly the same */
  cogl_pipeline_add_snippet (pipeline, snippet);
  cogl_object_unref (snippet);

  cogl_framebuffer_draw_rectangle (test_fb, pipeline, 50, 0, 100, 50);

  cogl_object_unref (pipeline);
}
コード例 #9
0
ファイル: test-pipeline-uniforms.c プロジェクト: 3v1n0/cogl
static CoglPipeline *
create_pipeline_for_shader (TestState *state,
                            const char *declarations,
                            const char *fragment_source)
{
  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
  CoglSnippet *snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                           declarations,
                                           NULL);
  cogl_snippet_set_replace (snippet, fragment_source);

  cogl_pipeline_add_snippet (pipeline, snippet);
  cogl_object_unref (snippet);

  return pipeline;
}
コード例 #10
0
ファイル: edge-effect.c プロジェクト: bpeel/sprite-player
static void
create_pipeline (Data *data)
{
  CoglPipeline *pipeline;
  CoglSnippet *snippet;

  pipeline = cogl_pipeline_new (data->context);

  /* Disable blending */
  cogl_pipeline_set_blend (pipeline,
                           "RGBA = ADD (SRC_COLOR, 0)", NULL);

  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                              shader_declarations,
                              shader_source);
  cogl_pipeline_add_snippet (pipeline, snippet);
  cogl_object_unref (snippet);

  data->base_pipeline = pipeline;
}
コード例 #11
0
static void
test_short_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[1];
  CoglAttributeBuffer *buffer;
  CoglPipeline *pipeline, *pipeline2;
  CoglSnippet *snippet;

  static const ShortVert short_verts[] =
    {
      { -10, -10 },
      { -1, -10 },
      { -5, -1 }
    };

  pipeline = cogl_pipeline_new (test_ctx);
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
                              "attribute vec2 pos;",
                              NULL);
  cogl_snippet_set_replace (snippet,
                            "cogl_position_out = "
                            "cogl_modelview_projection_matrix * "
                            "vec4 (pos, 0.0, 1.0);");
  cogl_pipeline_add_snippet (pipeline, snippet);
  cogl_object_unref (snippet);

  cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (short_verts), short_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "pos",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f,
                              offset_y + 10.0f,
                              0.0f);

  cogl_framebuffer_draw_attributes (test_fb,
                                    pipeline,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    3, /* n_vertices */
                                    attributes,
                                    1 /* n_attributes */);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  /* Test again treating the attribute as unsigned */
  attributes[0] = cogl_attribute_new (buffer,
                                      "pos",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);

  pipeline2 = cogl_pipeline_copy (pipeline);
  cogl_pipeline_set_color4ub (pipeline2, 0, 255, 0, 255);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f - 65525.0f,
                              offset_y - 65525,
                              0.0f);

  cogl_framebuffer_draw_attributes (test_fb,
                                    pipeline2,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    3, /* n_vertices */
                                    attributes,
                                    1 /* n_attributes */);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  cogl_object_unref (pipeline2);
  cogl_object_unref (pipeline);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
コード例 #12
0
ファイル: test-custom-attributes.c プロジェクト: 3v1n0/cogl
static void
test_short_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer;
  CoglPipeline *pipeline, *pipeline2;
  CoglSnippet *snippet;
  CoglPrimitive *primitive;

  static const ShortVert short_verts[] =
    {
      { -10, -10, /**/ 0xffff, 0, 0, 0xffff },
      { -1, -10,  /**/ 0xffff, 0, 0, 0xffff },
      { -5, -1, /**/ 0xffff, 0, 0, 0xffff }
    };


  pipeline = cogl_pipeline_copy (state->pipeline);

  cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (short_verts), short_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);
  cogl_attribute_set_normalized (attributes[1], TRUE);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f,
                              offset_y + 10.0f,
                              0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  2); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, pipeline);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  /* Test again treating the attribute as unsigned */
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);

  /* XXX: this is a hack to force the pipeline to use the glsl backend
   * because we know it's not possible to test short vertex position
   * components with the legacy GL backend since which might otherwise
   * be used internally... */
  pipeline2 = cogl_pipeline_new (test_ctx);
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                              "attribute vec4 color;",
                              "cogl_color_out = vec4 (0.0, 1.0, 0.0, 1.0);");
  cogl_pipeline_add_snippet (pipeline2, snippet);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f - 65525.0f,
                              offset_y - 65525,
                              0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  1); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, pipeline2);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  cogl_object_unref (pipeline2);
  cogl_object_unref (pipeline);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
コード例 #13
0
ファイル: rig-renderer.c プロジェクト: sanyaade-mobiledev/rig
static CoglPipeline *
get_entity_color_pipeline (RigEngine *engine,
                           RutEntity *entity,
                           RutComponent *geometry,
                           CoglBool blended)
{
  CoglSnippet *snippet;
  CoglDepthState depth_state;
  RutMaterial *material;
  CoglTexture *texture = NULL;
  CoglTexture *normal_map = NULL;
  CoglTexture *alpha_mask = NULL;
  CoglPipeline *pipeline;
  CoglFramebuffer *shadow_fb;

  if (blended)
    pipeline = rut_entity_get_pipeline_cache (entity,
                                              CACHE_SLOT_COLOR_BLENDED);
  else
    pipeline = rut_entity_get_pipeline_cache (entity,
                                              CACHE_SLOT_COLOR_UNBLENDED);
  if (pipeline)
    {
      cogl_object_ref (pipeline);
      goto FOUND;
    }

  pipeline = cogl_pipeline_new (engine->ctx->cogl_context);

  material = rut_entity_get_component (entity, RUT_COMPONENT_TYPE_MATERIAL);
  if (material)
    {
      RutAsset *texture_asset = rut_material_get_texture_asset (material);
      RutAsset *normal_map_asset =
        rut_material_get_normal_map_asset (material);
      RutAsset *alpha_mask_asset =
        rut_material_get_alpha_mask_asset (material);

      if (texture_asset)
        texture = rut_asset_get_texture (texture_asset);
      if (texture)
        cogl_pipeline_set_layer_texture (pipeline, 1, texture);

      if (normal_map_asset)
        normal_map = rut_asset_get_texture (normal_map_asset);

      if (alpha_mask_asset)
        alpha_mask = rut_asset_get_texture (alpha_mask_asset);
    }

#if 0
  /* NB: Our texture colours aren't premultiplied */
  cogl_pipeline_set_blend (pipeline,
                           "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))"
                           "A   = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))",
                           NULL);
#endif

#if 0
  if (rut_object_get_type (geometry) == &rut_shape_type)
    rut_geometry_component_update_pipeline (geometry, pipeline);

  pipeline = cogl_pipeline_new (rut_cogl_context);
#endif

  cogl_pipeline_set_color4f (pipeline, 0.8f, 0.8f, 0.8f, 1.f);

  /* enable depth testing */
  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_test_enabled (&depth_state, TRUE);

  if (blended)
    cogl_depth_state_set_write_enabled (&depth_state, FALSE);

  cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);

  /* Vertex shader setup for lighting */
  cogl_pipeline_add_snippet (pipeline, engine->lighting_vertex_snippet);

  if (normal_map)
    cogl_pipeline_add_snippet (pipeline, engine->normal_map_vertex_snippet);

  if (rut_entity_get_receive_shadow (entity))
    cogl_pipeline_add_snippet (pipeline, engine->shadow_mapping_vertex_snippet);

  /* and fragment shader */

  /* XXX: ideally we wouldn't have to rely on conditionals + discards
   * in the fragment shader to differentiate blended and unblended
   * regions and instead we should let users mark out opaque regions
   * in geometry.
   */
  cogl_pipeline_add_snippet (pipeline,
                             blended ?
                             engine->blended_discard_snippet :
                             engine->unblended_discard_snippet);

  cogl_pipeline_add_snippet (pipeline, engine->unpremultiply_snippet);

  if (material)
    {
      if (alpha_mask)
        {
          /* We don't want this layer to be automatically modulated with the
           * previous layers so we set its combine mode to "REPLACE" so it
           * will be skipped past and we can sample its texture manually */
          cogl_pipeline_set_layer_combine (pipeline, 2, "RGBA=REPLACE(PREVIOUS)", NULL);
          cogl_pipeline_set_layer_texture (pipeline, 2, alpha_mask);

          cogl_pipeline_add_snippet (pipeline, engine->alpha_mask_snippet);
        }

      if (normal_map)
        {
          /* We don't want this layer to be automatically modulated with the
           * previous layers so we set its combine mode to "REPLACE" so it
           * will be skipped past and we can sample its texture manually */
          cogl_pipeline_set_layer_combine (pipeline, 5, "RGBA=REPLACE(PREVIOUS)", NULL);
          cogl_pipeline_set_layer_texture (pipeline, 5, normal_map);

          snippet = engine->normal_map_fragment_snippet;
        }
      else
        {
          snippet = engine->material_lighting_snippet;
        }
    }
  else
    {
      snippet = engine->simple_lighting_snippet;
    }

  cogl_pipeline_add_snippet (pipeline, snippet);

  if (rut_entity_get_receive_shadow (entity))
    {
      /* Hook the shadow map sampling */

      cogl_pipeline_set_layer_texture (pipeline, 7, engine->shadow_map);
      /* For debugging the shadow mapping... */
      //cogl_pipeline_set_layer_texture (pipeline, 7, engine->shadow_color);
      //cogl_pipeline_set_layer_texture (pipeline, 7, engine->gradient);

      /* We don't want this layer to be automatically modulated with the
       * previous layers so we set its combine mode to "REPLACE" so it
       * will be skipped past and we can sample its texture manually */
      cogl_pipeline_set_layer_combine (pipeline, 7, "RGBA=REPLACE(PREVIOUS)", NULL);

      /* Handle shadow mapping */
      cogl_pipeline_add_snippet (pipeline,
                                 engine->shadow_mapping_fragment_snippet);
    }

  cogl_pipeline_add_snippet (pipeline, engine->premultiply_snippet);

  if (rut_object_get_type (geometry) == &rut_shape_type)
    {
      CoglTexture *shape_texture;

      if (rut_shape_get_shaped (RUT_SHAPE (geometry)))
        {
          shape_texture =
            rut_shape_get_shape_texture (RUT_SHAPE (geometry));
          cogl_pipeline_set_layer_texture (pipeline, 0, shape_texture);
        }

      rut_shape_add_reshaped_callback (RUT_SHAPE (geometry),
                                       reshape_cb,
                                       NULL,
                                       NULL);
    }
  else if (rut_object_get_type (geometry) == &rut_diamond_type)
    rut_diamond_apply_mask (RUT_DIAMOND (geometry), pipeline);

  if (!blended)
    {
      cogl_pipeline_set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL);
      rut_entity_set_pipeline_cache (entity,
                                     CACHE_SLOT_COLOR_UNBLENDED, pipeline);
    }
  else
    {
      rut_entity_set_pipeline_cache (entity,
                                     CACHE_SLOT_COLOR_BLENDED, pipeline);
    }

FOUND:

  /* FIXME: there's lots to optimize about this! */
  shadow_fb = COGL_FRAMEBUFFER (engine->shadow_fb);

  /* update uniforms in pipelines */
  {
    CoglMatrix light_shadow_matrix, light_projection;
    CoglMatrix model_transform;
    const float *light_matrix;
    int location;

    cogl_framebuffer_get_projection_matrix (shadow_fb, &light_projection);

    /* XXX: This is pretty bad that we are having to do this. It would
     * be nicer if cogl exposed matrix-stacks publicly so we could
     * maintain the entity model_matrix incrementally as we traverse
     * the scenegraph. */
    rut_graphable_get_transform (entity, &model_transform);

    get_light_modelviewprojection (&model_transform,
                                   engine->light,
                                   &light_projection,
                                   &light_shadow_matrix);

    light_matrix = cogl_matrix_get_array (&light_shadow_matrix);

    location = cogl_pipeline_get_uniform_location (pipeline,
                                                   "light_shadow_matrix");
    cogl_pipeline_set_uniform_matrix (pipeline,
                                      location,
                                      4, 1,
                                      FALSE,
                                      light_matrix);
  }

  return pipeline;
}
コード例 #14
0
ファイル: rig-renderer.c プロジェクト: sanyaade-mobiledev/rig
static CoglPipeline *
get_entity_mask_pipeline (RigEngine *engine,
                          RutEntity *entity,
                          RutComponent *geometry)
{
  CoglPipeline *pipeline;

  pipeline = rut_entity_get_pipeline_cache (entity, CACHE_SLOT_SHADOW);
  if (pipeline)
    return cogl_object_ref (pipeline);

  /* TODO: move into init() somewhere */
  if (G_UNLIKELY (!engine->dof_pipeline_template))
    {
      CoglPipeline *pipeline;
      CoglDepthState depth_state;
      CoglSnippet *snippet;

      pipeline = cogl_pipeline_new (engine->ctx->cogl_context);

      cogl_pipeline_set_color_mask (pipeline, COGL_COLOR_MASK_ALPHA);

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

      cogl_depth_state_init (&depth_state);
      cogl_depth_state_set_test_enabled (&depth_state, TRUE);
      cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);

      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,

                                  /* definitions */
                                  "uniform float dof_focal_distance;\n"
                                  "uniform float dof_depth_of_field;\n"

                                  "varying float dof_blur;\n",
                                  //"varying vec4 world_pos;\n",

                                  /* compute the amount of bluriness we want */
                                  "vec4 world_pos = cogl_modelview_matrix * cogl_position_in;\n"
                                  //"world_pos = cogl_modelview_matrix * cogl_position_in;\n"
                                  "dof_blur = 1.0 - clamp (abs (world_pos.z - dof_focal_distance) /\n"
                                  "                  dof_depth_of_field, 0.0, 1.0);\n"
      );

      cogl_pipeline_add_snippet (pipeline, snippet);
      cogl_object_unref (snippet);

      /* This was used to debug the focal distance and bluriness amount in the DoF
       * effect: */
#if 0
      cogl_pipeline_set_color_mask (pipeline, COGL_COLOR_MASK_ALL);
      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                  "varying vec4 world_pos;\n"
                                  "varying float dof_blur;",

                                  "cogl_color_out = vec4(dof_blur,0,0,1);\n"
                                  //"cogl_color_out = vec4(1.0, 0.0, 0.0, 1.0);\n"
                                  //"if (world_pos.z < -30.0) cogl_color_out = vec4(0,1,0,1);\n"
                                  //"if (abs (world_pos.z + 30.f) < 0.1) cogl_color_out = vec4(0,1,0,1);\n"
                                  "cogl_color_out.a = dof_blur;\n"
                                  //"cogl_color_out.a = 1.0;\n"
      );

      cogl_pipeline_add_snippet (pipeline, snippet);
      cogl_object_unref (snippet);
#endif

      engine->dof_pipeline_template = pipeline;
    }

  /* TODO: move into init() somewhere */
  if (G_UNLIKELY (!engine->dof_diamond_pipeline))
    {
      CoglPipeline *dof_diamond_pipeline =
        cogl_pipeline_copy (engine->dof_pipeline_template);
      CoglSnippet *snippet;

      cogl_pipeline_set_layer_texture (dof_diamond_pipeline,
                                       0,
                                       engine->ctx->circle_texture);

      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                  /* declarations */
                                  "varying float dof_blur;",

                                  /* post */
                                  "if (cogl_color_out.a <= 0.0)\n"
                                  "  discard;\n"
                                  "\n"
                                  "cogl_color_out.a = dof_blur;\n");

      cogl_pipeline_add_snippet (dof_diamond_pipeline, snippet);
      cogl_object_unref (snippet);

      engine->dof_diamond_pipeline = dof_diamond_pipeline;
    }

  /* TODO: move into init() somewhere */
  if (G_UNLIKELY (!engine->dof_unshaped_pipeline))
    {
      CoglPipeline *dof_unshaped_pipeline =
        cogl_pipeline_copy (engine->dof_pipeline_template);
      CoglSnippet *snippet;

      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                  /* declarations */
                                  "varying float dof_blur;",

                                  /* post */
                                  "if (cogl_color_out.a < 0.25)\n"
                                  "  discard;\n"
                                  "\n"
                                  "cogl_color_out.a = dof_blur;\n");

      cogl_pipeline_add_snippet (dof_unshaped_pipeline, snippet);
      cogl_object_unref (snippet);

      engine->dof_unshaped_pipeline = dof_unshaped_pipeline;
    }

  /* TODO: move into init() somewhere */
  if (G_UNLIKELY (!engine->dof_pipeline))
    {
      CoglPipeline *dof_pipeline =
        cogl_pipeline_copy (engine->dof_pipeline_template);
      CoglSnippet *snippet;

      /* store the bluriness in the alpha channel */
      snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                                  "varying float dof_blur;",

                                  "cogl_color_out.a = dof_blur;\n"
      );
      cogl_pipeline_add_snippet (dof_pipeline, snippet);
      cogl_object_unref (snippet);

      engine->dof_pipeline = dof_pipeline;
    }

  if (rut_object_get_type (geometry) == &rut_diamond_type)
    {
      pipeline = cogl_object_ref (engine->dof_diamond_pipeline);
    }
  else if (rut_object_get_type (geometry) == &rut_shape_type)
    {
      RutMaterial *material =
        rut_entity_get_component (entity, RUT_COMPONENT_TYPE_MATERIAL);

      pipeline = cogl_pipeline_copy (engine->dof_unshaped_pipeline);

      if (rut_shape_get_shaped (RUT_SHAPE (geometry)))
        {
          CoglTexture *shape_texture =
            rut_shape_get_shape_texture (RUT_SHAPE (geometry));

          cogl_pipeline_set_layer_texture (pipeline, 0, shape_texture);
        }

      if (material)
        {
          RutAsset *texture_asset = rut_material_get_texture_asset (material);
          RutAsset *alpha_mask_asset =
            rut_material_get_alpha_mask_asset (material);

          if (texture_asset)
            cogl_pipeline_set_layer_texture (pipeline, 1,
                                             rut_asset_get_texture (texture_asset));

          if (alpha_mask_asset)
            {
              /* We don't want this layer to be automatically modulated with the
               * previous layers so we set its combine mode to "REPLACE" so it
               * will be skipped past and we can sample its texture manually */
              cogl_pipeline_set_layer_combine (pipeline, 2, "RGBA=REPLACE(PREVIOUS)", NULL);
              cogl_pipeline_set_layer_texture (pipeline, 2,
                                               rut_asset_get_texture (alpha_mask_asset));

              cogl_pipeline_add_snippet (pipeline, engine->alpha_mask_snippet);
            }
        }
    }
  else
    pipeline = cogl_object_ref (engine->dof_pipeline);

  rut_entity_set_pipeline_cache (entity, CACHE_SLOT_SHADOW, pipeline);

  return pipeline;
}