Exemplo n.º 1
0
static void
init_state (TestState *state)
{
  int uniform_location;

  state->pipeline_red = create_pipeline_for_shader (state, color_source);

  uniform_location =
    cogl_pipeline_get_uniform_location (state->pipeline_red, "red");
  cogl_pipeline_set_uniform_1f (state->pipeline_red, uniform_location, 1.0f);
  uniform_location =
    cogl_pipeline_get_uniform_location (state->pipeline_red, "green");
  cogl_pipeline_set_uniform_1f (state->pipeline_red, uniform_location, 0.0f);
  uniform_location =
    cogl_pipeline_get_uniform_location (state->pipeline_red, "blue");
  cogl_pipeline_set_uniform_1f (state->pipeline_red, uniform_location, 0.0f);

  state->pipeline_green = cogl_pipeline_copy (state->pipeline_red);
  uniform_location =
    cogl_pipeline_get_uniform_location (state->pipeline_green, "green");
  cogl_pipeline_set_uniform_1f (state->pipeline_green, uniform_location, 1.0f);

  state->pipeline_blue = cogl_pipeline_copy (state->pipeline_red);
  uniform_location =
    cogl_pipeline_get_uniform_location (state->pipeline_blue, "blue");
  cogl_pipeline_set_uniform_1f (state->pipeline_blue, uniform_location, 1.0f);

  state->matrix_pipeline = create_pipeline_for_shader (state, matrix_source);
  state->vector_pipeline = create_pipeline_for_shader (state, vector_source);
  state->int_pipeline = create_pipeline_for_shader (state, int_source);

  state->long_pipeline = NULL;
}
Exemplo n.º 2
0
static void
paint_vector_pipeline (CoglPipeline *pipeline)
{
  float vector_array_values[] = { 1.0f, 0.0f, 0.0f, 0.0f,
                                  0.0f, 1.0f, 0.0f, 0.0f };
  float short_vector_values[] = { 0.0f, 0.0f, 1.0f };
  int uniform_location;

  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "vector_array");
  cogl_pipeline_set_uniform_float (pipeline,
                                   uniform_location,
                                   4, /* n_components */
                                   2, /* count */
                                   vector_array_values);

  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "short_vector");
  cogl_pipeline_set_uniform_float (pipeline,
                                   uniform_location,
                                   3, /* n_components */
                                   1, /* count */
                                   short_vector_values);

  paint_pipeline (pipeline, 13);
}
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);
}
Exemplo n.º 4
0
static void
set_focal_parameters (CoglPipeline *pipeline,
                      float focal_distance,
                      float depth_of_field)
{
  int location;
  float distance;

  /* I want to have the focal distance as positive when it's in front of the
   * camera (it seems more natural, but as, in OpenGL, the camera is facing
   * the negative Ys, the actual value to give to the shader has to be
   * negated */
  distance = -focal_distance;

  location = cogl_pipeline_get_uniform_location (pipeline,
                                                 "dof_focal_distance");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   1 /* n_components */, 1 /* count */,
                                   &distance);

  location = cogl_pipeline_get_uniform_location (pipeline,
                                                 "dof_depth_of_field");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   1 /* n_components */, 1 /* count */,
                                   &depth_of_field);
}
Exemplo n.º 5
0
static void
paint_matrix_pipeline (CoglPipeline *pipeline)
{
  CoglMatrix matrices[4];
  float matrix_floats[16 * 4];
  int uniform_location;
  int i;

  for (i = 0; i < 4; i++)
    cogl_matrix_init_identity (matrices + i);

  /* Use the first matrix to make the color red */
  cogl_matrix_translate (matrices + 0, 1.0f, 0.0f, 0.0f);

  /* Rotate the vertex so that it ends up green */
  cogl_matrix_rotate (matrices + 1, 90.0f, 0.0f, 0.0f, 1.0f);

  /* Scale the vertex so it ends up halved */
  cogl_matrix_scale (matrices + 2, 0.5f, 0.5f, 0.5f);

  /* Add a blue component in the final matrix. The final matrix is
     uploaded as transposed so we need to transpose first to cancel
     that out */
  cogl_matrix_translate (matrices + 3, 0.0f, 0.0f, 1.0f);
  cogl_matrix_transpose (matrices + 3);

  for (i = 0; i < 4; i++)
    memcpy (matrix_floats + i * 16,
            cogl_matrix_get_array (matrices + i),
            sizeof (float) * 16);

  /* Set the first three matrices as transposed */
  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "matrix_array");
  cogl_pipeline_set_uniform_matrix (pipeline,
                                    uniform_location,
                                    4, /* dimensions */
                                    3, /* count */
                                    FALSE, /* not transposed */
                                    matrix_floats);

  /* Set the last matrix as untransposed */
  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "matrix_array[3]");
  cogl_pipeline_set_uniform_matrix (pipeline,
                                    uniform_location,
                                    4, /* dimensions */
                                    1, /* count */
                                    TRUE, /* transposed */
                                    matrix_floats + 16 * 3);

  paint_pipeline (pipeline, 12);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
static void
paint_color_pipelines (TestState *state)
{
  CoglPipeline *temp_pipeline;
  int uniform_location;
  int i;

  /* Paint with the first pipeline that sets the uniforms to bright
     red */
  paint_pipeline (state->pipeline_red, 0);

  /* Paint with the two other pipelines. These inherit from the red
     pipeline and only override one other component. The values for
     the two other components should be inherited from the red
     pipeline. */
  paint_pipeline (state->pipeline_green, 1);
  paint_pipeline (state->pipeline_blue, 2);

  /* Try modifying a single pipeline for multiple rectangles */
  temp_pipeline = cogl_pipeline_copy (state->pipeline_green);
  uniform_location = cogl_pipeline_get_uniform_location (temp_pipeline,
                                                         "green");

  for (i = 0; i <= 8; i++)
    {
      cogl_pipeline_set_uniform_1f (temp_pipeline, uniform_location,
                                    i / 8.0f);
      paint_pipeline (temp_pipeline, i + 3);
    }

  cogl_object_unref (temp_pipeline);
}
Exemplo n.º 8
0
static void
set_blurrer_pipeline_texture (CoglPipeline *pipeline,
                              CoglTexture *source,
                              float x_pixel_step,
                              float y_pixel_step)
{
  float pixel_step[2];
  int pixel_step_location;

  /* our input in the source texture */
  cogl_pipeline_set_layer_texture (pipeline,
                                   0, /* layer_num */
                                   source);

  pixel_step[0] = x_pixel_step;
  pixel_step[1] = y_pixel_step;
  pixel_step_location =
    cogl_pipeline_get_uniform_location (pipeline, "pixel_step");
  g_assert (pixel_step_location);
  cogl_pipeline_set_uniform_float (pipeline,
                                   pixel_step_location,
                                   2, /* n_components */
                                   1, /* count */
                                   pixel_step);
}
Exemplo n.º 9
0
static void
set_blurrer_pipeline_factors (CoglPipeline *pipeline, int n_taps)
{
  int i, radius;
  float *factors, sigma;
  int location;
  float sum;
  float scale;

  radius = n_taps / 2; /* which is (n_taps - 1) / 2 as well */

  factors = g_alloca (n_taps * sizeof (float));
  sigma = n_taps_to_sigma (n_taps);

  sum = 0;
  for (i = -radius; i <= radius; i++)
    {
      factors[i + radius] = gaussian (sigma, i);
      sum += factors[i + radius];
    }

  /* So that we don't loose any brightness when blurring, we
   * normalized the factors... */
  scale = 1.0 / sum;
  for (i = -radius; i <= radius; i++)
    factors[i + radius] *= scale;

  location = cogl_pipeline_get_uniform_location (pipeline, "factors");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   1 /* n_components */,
                                   n_taps /* count */,
                                   factors);
}
Exemplo n.º 10
0
/**
 * shell_glsl_quad_get_uniform_location:
 * @quad: a #ShellGLSLQuad
 * @name: the uniform name
 *
 * Returns: the location of the uniform named @name, that can be
 *          passed to shell_glsl_quad_set_uniform_float().
 */
int
shell_glsl_quad_get_uniform_location (ShellGLSLQuad *quad,
                                      const char    *name)
{
  ShellGLSLQuadPrivate *priv = shell_glsl_quad_get_instance_private (quad);
  return cogl_pipeline_get_uniform_location (priv->pipeline, name);
}
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);
}
Exemplo n.º 12
0
void
rut_light_set_uniforms (RutLight *light,
                        CoglPipeline *pipeline)
{
  RutComponentableProps *component =
    rut_object_get_properties (light, RUT_INTERFACE_ID_COMPONENTABLE);
  RutEntity *entity = component->entity;
  float origin[3] = {0, 0, 0};
  float norm_direction[3] = {0, 0, 1};
  int location;

  rut_entity_get_transformed_position (entity, origin);
  rut_entity_get_transformed_position (entity, norm_direction);
  cogl_vector3_subtract (norm_direction, norm_direction, origin);
  cogl_vector3_normalize (norm_direction);

  location = cogl_pipeline_get_uniform_location (pipeline,
                                                 "light0_direction_norm");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   3, 1,
                                   norm_direction);

  location = cogl_pipeline_get_uniform_location (pipeline,
                                                 "light0_ambient");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   4, 1,
                                   get_color_array (&light->ambient));

  location = cogl_pipeline_get_uniform_location (pipeline,
                                                 "light0_diffuse");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   4, 1,
                                   get_color_array (&light->diffuse));

  location = cogl_pipeline_get_uniform_location (pipeline,
                                                 "light0_specular");
  cogl_pipeline_set_uniform_float (pipeline,
                                   location,
                                   4, 1,
                                   get_color_array (&light->specular));
}
Exemplo n.º 13
0
static void
paint (CoglFramebuffer *fb,
       const CoglGstRectangle *video_output,
       void *user_data)
{
  Data *data = user_data;
  CoglPipeline *pipeline;

  pipeline = cogl_pipeline_copy (data->pipeline);
  cogl_gst_video_sink_attach_frame (data->sink, pipeline);
  cogl_object_unref (data->pipeline);
  data->pipeline = pipeline;

  if (data->last_output_width != video_output->width ||
      data->last_output_height != video_output->height)
    {
      int location =
        cogl_pipeline_get_uniform_location (pipeline, "pixel_step");

      if (location != -1)
        {
          float value[2] =
            {
              1.0f / video_output->width,
              1.0f / video_output->height
            };

          cogl_pipeline_set_uniform_float (pipeline,
                                           location,
                                           2, /* n_components */
                                           1, /* count */
                                           value);
        }

      data->last_output_width = video_output->width;
      data->last_output_height = video_output->height;
    }


  borders_draw (data->borders, fb, video_output);

  cogl_framebuffer_draw_rectangle (fb,
                                   pipeline,
                                   video_output->x,
                                   video_output->y,
                                   video_output->x +
                                   video_output->width,
                                   video_output->y +
                                   video_output->height);
}
Exemplo n.º 14
0
static void
paint_int_pipeline (CoglPipeline *pipeline)
{
  int vector_array_values[] = { 0x00, 0x00, 0xff, 0x00,
                                0x00, 0xff, 0x00, 0x00 };
  int single_value = 0x80;
  int uniform_location;

  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "vector_array");
  cogl_pipeline_set_uniform_int (pipeline,
                                 uniform_location,
                                 4, /* n_components */
                                 2, /* count */
                                 vector_array_values);

  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "single_value");
  cogl_pipeline_set_uniform_1i (pipeline,
                                uniform_location,
                                single_value);

  paint_pipeline (pipeline, 14);
}
Exemplo n.º 15
0
static void
init_long_pipeline_state (TestState *state)
{
  int i;

  state->long_pipeline = create_pipeline_for_shader (state, long_source);

  /* This tries to lookup a large number of uniform names to make sure
     that the bitmask of overriden uniforms flows over the size of a
     single long so that it has to resort to allocating it */
  for (i = 0; i < LONG_ARRAY_SIZE; i++)
    {
      char *uniform_name = g_strdup_printf ("long_array[%i]", i);
      state->long_uniform_locations[i] =
        cogl_pipeline_get_uniform_location (state->long_pipeline,
                                            uniform_name);
      g_free (uniform_name);
    }
}
Exemplo n.º 16
0
static void
rig_journal_flush (GArray *journal,
                   RigPaintContext *paint_ctx)
{
  RutPaintContext *rut_paint_ctx = &paint_ctx->_parent;
  RutCamera *camera = rut_paint_ctx->camera;
  CoglFramebuffer *fb = rut_camera_get_framebuffer (camera);
  int start, dir, end;
  int i;

  /* TODO: use an inline qsort implementation */
  g_array_sort (journal, (void *)sort_entry_cb);

  /* We draw opaque geometry front-to-back so we are more likely to be
   * able to discard later fragments earlier by depth testing.
   *
   * We draw transparent geometry back-to-front so it blends
   * correctly.
   */
  if ( paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
    {
      start = 0;
      dir = 1;
      end = journal->len;
    }
  else
    {
      start = journal->len - 1;
      dir = -1;
      end = -1;
    }

  cogl_framebuffer_push_matrix (fb);

  for (i = start; i != end; i += dir)
    {
      RigJournalEntry *entry = &g_array_index (journal, RigJournalEntry, i);
      RutEntity *entity = entry->entity;
      RutComponent *geometry =
        rut_entity_get_component (entity, RUT_COMPONENT_TYPE_GEOMETRY);
      CoglPipeline *pipeline;
      CoglPrimitive *primitive;
      float normal_matrix[9];
      RutMaterial *material;

      pipeline = get_entity_pipeline (paint_ctx->engine,
                                      entity,
                                      geometry,
                                      paint_ctx->pass);

      if (paint_ctx->pass == RIG_PASS_DOF_DEPTH ||
          paint_ctx->pass == RIG_PASS_SHADOW)
        {
          /* FIXME: avoid updating these uniforms for every primitive if
           * the focal parameters haven't change! */
          set_focal_parameters (pipeline,
                                camera->focal_distance,
                                camera->depth_of_field);
        }
      else if (paint_ctx->pass == RIG_PASS_COLOR_UNBLENDED ||
               paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
        {
          int location;
          RutLight *light = rut_entity_get_component (paint_ctx->engine->light,
                                                      RUT_COMPONENT_TYPE_LIGHT);
          /* FIXME: only update the lighting uniforms when the light has
           * actually moved! */
          rut_light_set_uniforms (light, pipeline);

          /* FIXME: only update the material uniforms when the material has
           * actually changed! */
          material = rut_entity_get_component (entity, RUT_COMPONENT_TYPE_MATERIAL);
          if (material)
            rut_material_flush_uniforms (material, pipeline);

          get_normal_matrix (&entry->matrix, normal_matrix);

          location = cogl_pipeline_get_uniform_location (pipeline, "normal_matrix");
          cogl_pipeline_set_uniform_matrix (pipeline,
                                            location,
                                            3, /* dimensions */
                                            1, /* count */
                                            FALSE, /* don't transpose again */
                                            normal_matrix);
        }

      if (rut_object_is (geometry, RUT_INTERFACE_ID_PRIMABLE))
        {
          primitive = rut_primable_get_primitive (geometry);
          cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix);
          cogl_framebuffer_draw_primitive (fb,
                                           pipeline,
                                           primitive);
        }
      else if (rut_object_get_type (geometry) == &rut_text_type &&
               paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
        {
          cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix);
          rut_paintable_paint (geometry, rut_paint_ctx);
        }

      cogl_object_unref (pipeline);

      rut_refable_unref (entry->entity);
    }

  cogl_framebuffer_pop_matrix (fb);

  g_array_set_size (journal, 0);
}
Exemplo n.º 17
0
/**
 * shell_glsl_quad_get_uniform_location:
 * @quad: a #ShellGLSLQuad
 * @name: the uniform name
 *
 * Returns: the location of the uniform named @name, that can be
 *          passed to shell_glsl_quad_set_uniform_float().
 */
int
shell_glsl_quad_get_uniform_location (ShellGLSLQuad *quad,
                                      const char    *name)
{
  return cogl_pipeline_get_uniform_location (quad->priv->pipeline, name);
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;

}