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; }
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"); }
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); } }
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"); }
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); }
/** * 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 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); }
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); }
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; }
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; }
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); }
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); }
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; }
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; }