/** * 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 SnippetCacheEntry * add_cache_entry (CoglGstVideoSink *sink, SnippetCache *cache, const char *decl) { CoglGstVideoSinkPrivate *priv = sink->priv; SnippetCacheEntry *entry = g_slice_new (SnippetCacheEntry); char *default_source; entry->start_position = priv->custom_start; entry->vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS, decl, NULL /* post */); entry->fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS, decl, NULL /* post */); default_source = g_strdup_printf (" cogl_layer *= cogl_gst_sample_video%i " "(cogl_tex_coord%i_in.st);\n", priv->custom_start, priv->custom_start); entry->default_sample_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, NULL, /* declarations */ default_source); g_free (default_source); g_queue_push_head (&cache->entries, entry); return entry; }
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); }
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); }
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 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) { /* 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"); }
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"); }
CoglSnippet * meta_wayland_egl_stream_create_snippet (void) { CoglSnippet *snippet; snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, "uniform samplerExternalOES tex_external;", NULL); cogl_snippet_set_replace (snippet, "cogl_texel = texture2D (tex_external,\n" " cogl_tex_coord.xy);"); return snippet; }
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[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_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; }
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 do_test (CoglBool check_orientation, CoglBool use_glsl) { int fb_width = cogl_framebuffer_get_width (test_fb); int fb_height = cogl_framebuffer_get_height (test_fb); CoglPrimitive *prim; CoglError *error = NULL; CoglTexture2D *tex_2d; CoglPipeline *pipeline, *solid_pipeline; int tex_height; cogl_framebuffer_orthographic (test_fb, 0, 0, /* x_1, y_1 */ fb_width, /* x_2 */ fb_height /* y_2 */, -1, 100 /* near/far */); cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); /* If we're not checking the orientation of the point sprite then * we'll set the height of the texture to 1 so that the vertical * orientation does not matter */ if (check_orientation) tex_height = 2; else tex_height = 1; tex_2d = cogl_texture_2d_new_from_data (test_ctx, 2, tex_height, /* width/height */ COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, 6, /* row stride */ tex_data, &error); g_assert (tex_2d != NULL); g_assert (error == NULL); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d); cogl_pipeline_set_layer_filters (pipeline, 0, /* layer_index */ COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); cogl_pipeline_set_point_size (pipeline, POINT_SIZE); /* If we're using GLSL then we don't need to enable point sprite * coords and we can just directly reference cogl_point_coord in the * snippet */ if (use_glsl) { CoglSnippet *snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, NULL, /* declarations */ NULL /* post */); static const char source[] = " cogl_texel = texture2D (cogl_sampler, cogl_point_coord);\n"; cogl_snippet_set_replace (snippet, source); /* Keep a reference to the original pipeline because there is no * way to remove a snippet in order to recreate the solid * pipeline */ solid_pipeline = cogl_pipeline_copy (pipeline); cogl_pipeline_add_layer_snippet (pipeline, 0, snippet); cogl_object_unref (snippet); } else { CoglBool res = cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, /* layer_index */ 0, /* enable */ TRUE, &error); g_assert (res == TRUE); g_assert (error == NULL); solid_pipeline = cogl_pipeline_copy (pipeline); res = cogl_pipeline_set_layer_point_sprite_coords_enabled (solid_pipeline, /* layer_index */ 0, /* enable */ FALSE, &error); g_assert (res == TRUE); g_assert (error == NULL); } prim = cogl_primitive_new_p2t2 (test_ctx, COGL_VERTICES_MODE_POINTS, 1, /* n_vertices */ &point); cogl_primitive_draw (prim, test_fb, pipeline); /* Render the primitive again without point sprites to make sure disabling it works */ cogl_framebuffer_push_matrix (test_fb); cogl_framebuffer_translate (test_fb, POINT_SIZE * 2, /* x */ 0.0f, /* y */ 0.0f /* z */); cogl_primitive_draw (prim, test_fb, solid_pipeline); cogl_framebuffer_pop_matrix (test_fb); cogl_object_unref (prim); cogl_object_unref (solid_pipeline); cogl_object_unref (pipeline); cogl_object_unref (tex_2d); test_utils_check_pixel (test_fb, POINT_SIZE - POINT_SIZE / 4, POINT_SIZE - POINT_SIZE / 4, 0x0000ffff); test_utils_check_pixel (test_fb, POINT_SIZE + POINT_SIZE / 4, POINT_SIZE - POINT_SIZE / 4, 0x00ff00ff); test_utils_check_pixel (test_fb, POINT_SIZE - POINT_SIZE / 4, POINT_SIZE + POINT_SIZE / 4, check_orientation ? 0x00ffffff : 0x0000ffff); test_utils_check_pixel (test_fb, POINT_SIZE + POINT_SIZE / 4, POINT_SIZE + POINT_SIZE / 4, check_orientation ? 0xff0000ff : 0x00ff00ff); /* When rendering without the point sprites all of the texture coordinates should be 0,0 so it should get the top-left texel which is blue */ test_utils_check_region (test_fb, POINT_SIZE * 3 - POINT_SIZE / 2 + 1, POINT_SIZE - POINT_SIZE / 2 + 1, POINT_SIZE - 2, POINT_SIZE - 2, 0x0000ffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
static void st_background_effect_init (StBackgroundEffect *self) { CoglContext *ctx; StBackgroundEffectClass *klass = ST_BACKGROUND_EFFECT_GET_CLASS (self); if (G_UNLIKELY (klass->base_pipeline == NULL)) { ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); klass->base_pipeline = cogl_pipeline_new (ctx); } self->pipeline0 = cogl_pipeline_copy (klass->base_pipeline); self->pipeline1 = cogl_pipeline_copy (klass->base_pipeline); self->pipeline2 = cogl_pipeline_copy (klass->base_pipeline); self->pipeline3 = cogl_pipeline_copy (klass->base_pipeline); self->pipeline4 = cogl_pipeline_copy (klass->base_pipeline); CoglSnippet *snippet; snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, box_blur_glsl_declarations, NULL); cogl_snippet_set_replace (snippet, box_blur_glsl_shader); cogl_pipeline_add_layer_snippet (self->pipeline0, 0, snippet); cogl_pipeline_add_layer_snippet (self->pipeline1, 0, snippet); cogl_pipeline_add_layer_snippet (self->pipeline3, 0, snippet); cogl_object_unref (snippet); cogl_pipeline_set_layer_wrap_mode (self->pipeline0, 0, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); cogl_pipeline_set_layer_wrap_mode (self->pipeline0, 1, COGL_PIPELINE_WRAP_MODE_REPEAT); cogl_pipeline_set_layer_wrap_mode (self->pipeline1, 0, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); cogl_pipeline_set_layer_wrap_mode (self->pipeline2, 0, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); cogl_pipeline_set_layer_wrap_mode (self->pipeline3, 0, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); cogl_pipeline_set_layer_wrap_mode (self->pipeline4, 0, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); cogl_pipeline_set_cull_face_mode (self->pipeline0, COGL_PIPELINE_CULL_FACE_MODE_NONE); cogl_pipeline_set_cull_face_mode (self->pipeline1, COGL_PIPELINE_CULL_FACE_MODE_NONE); cogl_pipeline_set_cull_face_mode (self->pipeline2, COGL_PIPELINE_CULL_FACE_MODE_NONE); cogl_pipeline_set_cull_face_mode (self->pipeline3, COGL_PIPELINE_CULL_FACE_MODE_NONE); cogl_pipeline_set_cull_face_mode (self->pipeline4, COGL_PIPELINE_CULL_FACE_MODE_NONE); cogl_pipeline_set_layer_filters (self->pipeline0, 0, COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR); cogl_pipeline_set_layer_filters (self->pipeline0, 1, COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); cogl_pipeline_set_layer_filters (self->pipeline1, 0, COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR); cogl_pipeline_set_layer_filters (self->pipeline2, 0, COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR); cogl_pipeline_set_layer_filters (self->pipeline3, 0, COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR); cogl_pipeline_set_layer_filters (self->pipeline4, 0, COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR); cogl_pipeline_set_layer_null_texture (self->pipeline0, 0, COGL_TEXTURE_TYPE_2D); cogl_pipeline_set_layer_null_texture (self->pipeline1, 0, COGL_TEXTURE_TYPE_2D); cogl_pipeline_set_layer_null_texture (self->pipeline2, 0, COGL_TEXTURE_TYPE_2D); cogl_pipeline_set_layer_null_texture (self->pipeline3, 0, COGL_TEXTURE_TYPE_2D); cogl_pipeline_set_layer_null_texture (self->pipeline4, 0, COGL_TEXTURE_TYPE_2D); self->pixel_step_uniform0 = cogl_pipeline_get_uniform_location (self->pipeline0, "pixel_step"); self->BumpTex_uniform = cogl_pipeline_get_uniform_location (self->pipeline0, "BumpTex"); self->bump_step_uniform = cogl_pipeline_get_uniform_location (self->pipeline0, "bump_step"); self->pixel_step_uniform1 = cogl_pipeline_get_uniform_location (self->pipeline1, "pixel_step"); self->pixel_step_uniform2 = cogl_pipeline_get_uniform_location (self->pipeline3, "pixel_step"); cogl_pipeline_set_blend (self->pipeline0, "RGBA = ADD(SRC_COLOR, DST_COLOR*0)", NULL); cogl_pipeline_set_blend (self->pipeline1, "RGBA = ADD (SRC_COLOR*DST_COLOR[A], DST_COLOR*(1-DST_COLOR[A]))", NULL); cogl_pipeline_set_color4ub (self->pipeline1, 0xff, 0xff, 0xff, 0xff); cogl_pipeline_set_alpha_test_function (self->pipeline2, COGL_PIPELINE_ALPHA_FUNC_LESS, 0.004f); cogl_pipeline_set_color_mask (self->pipeline2, COGL_COLOR_MASK_ALPHA); cogl_pipeline_set_blend (self->pipeline2, "RGBA = ADD(SRC_COLOR, DST_COLOR*0)", NULL); cogl_pipeline_set_alpha_test_function (self->pipeline3, COGL_PIPELINE_ALPHA_FUNC_GEQUAL, 0.004f); cogl_pipeline_set_color_mask (self->pipeline3, COGL_COLOR_MASK_ALL); cogl_pipeline_set_blend (self->pipeline3, "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))", NULL); cogl_pipeline_set_alpha_test_function (self->pipeline4, COGL_PIPELINE_ALPHA_FUNC_GEQUAL, 0.004f); cogl_pipeline_set_color_mask (self->pipeline4, COGL_COLOR_MASK_ALL); cogl_pipeline_set_blend (self->pipeline4, "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))", NULL); self->bg_texture = NULL; self->bg_sub_texture = NULL; self->bumpmap_location = "/usr/share/cinnamon/bumpmaps/frost.png"; self->bg_bumpmap = st_cogl_texture_new_from_file_wrapper (self->bumpmap_location, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_RGBA_8888_PRE); if (self->bg_bumpmap != NULL) { self->bumptex_width_i = cogl_texture_get_width (self->bg_bumpmap); self->bumptex_height_i = cogl_texture_get_height (self->bg_bumpmap); cogl_pipeline_set_layer_texture (self->pipeline0, 1, self->bg_bumpmap); } else { cogl_pipeline_set_layer_null_texture (self->pipeline0, 1, COGL_TEXTURE_TYPE_2D); } cogl_pipeline_set_layer_combine (self->pipeline0,1, "RGBA = REPLACE (PREVIOUS)", NULL); self->old_time = 0; self->opacity = 0; }
static CoglPipeline * create_1d_gaussian_blur_pipeline (RutContext *ctx, int n_taps) { static GHashTable *pipeline_cache = NULL; CoglPipeline *pipeline; CoglSnippet *snippet; GString *shader; CoglDepthState depth_state; int i; /* initialize the pipeline cache. The shaders are only dependent on the * number of taps, not the sigma, so we cache the corresponding pipelines * in a hash table 'n_taps' => 'pipeline' */ if (G_UNLIKELY (pipeline_cache == NULL)) { pipeline_cache = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, /* key destroy notify */ (GDestroyNotify) cogl_object_unref); } pipeline = g_hash_table_lookup (pipeline_cache, GINT_TO_POINTER (n_taps)); if (pipeline) return cogl_object_ref (pipeline); shader = g_string_new (NULL); g_string_append_printf (shader, "uniform vec2 pixel_step;\n" "uniform float factors[%i];\n", n_taps); snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, shader->str, NULL /* post */); g_string_set_size (shader, 0); pipeline = cogl_pipeline_new (ctx->cogl_context); cogl_pipeline_set_layer_null_texture (pipeline, 0, /* layer_num */ COGL_TEXTURE_TYPE_2D); cogl_pipeline_set_layer_wrap_mode (pipeline, 0, /* layer_num */ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); cogl_pipeline_set_layer_filters (pipeline, 0, /* layer_num */ COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); for (i = 0; i < n_taps; i++) { g_string_append (shader, "cogl_texel "); if (i == 0) g_string_append (shader, "="); else g_string_append (shader, "+="); g_string_append_printf (shader, " texture2D (cogl_sampler, " "cogl_tex_coord.st"); if (i != (n_taps - 1) / 2) g_string_append_printf (shader, " + pixel_step * %f", (float) (i - ((n_taps - 1) / 2))); g_string_append_printf (shader, ") * factors[%i];\n", i); } cogl_snippet_set_replace (snippet, shader->str); g_string_free (shader, TRUE); cogl_pipeline_add_layer_snippet (pipeline, 0, snippet); cogl_object_unref (snippet); cogl_pipeline_set_blend (pipeline, "RGBA=ADD(SRC_COLOR, 0)", NULL); cogl_depth_state_init (&depth_state); cogl_depth_state_set_write_enabled (&depth_state, FALSE); cogl_depth_state_set_test_enabled (&depth_state, FALSE); cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL); g_hash_table_insert (pipeline_cache, GINT_TO_POINTER (n_taps), pipeline); return pipeline; }
void rig_renderer_init (RigEngine *engine) { /* We always want to use exactly the same snippets when creating * similar pipelines so that we can take advantage of Cogl's program * caching. The program cache only compares the snippet pointers, * not the contents of the snippets. Therefore we just create the * snippets we're going to use upfront and retain them */ engine->alpha_mask_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ "uniform float material_alpha_threshold;\n", /* post */ "if (texture2D(cogl_sampler2,\n" " cogl_tex_coord2_in.st).a <= \n" " material_alpha_threshold)\n" " discard;\n"); engine->lighting_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, /* definitions */ "uniform mat3 normal_matrix;\n" "varying vec3 normal, eye_direction;\n", /* post */ "normal = normalize(normal_matrix * cogl_normal_in);\n" "eye_direction = -vec3(cogl_modelview_matrix *\n" " cogl_position_in);\n" ); engine->normal_map_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, /* definitions */ "uniform vec3 light0_direction_norm;\n" "attribute vec3 tangent_in;\n" "varying vec3 light_direction;\n", /* post */ "vec3 tangent = normalize(normal_matrix * tangent_in);\n" "vec3 binormal = cross(normal, tangent);\n" /* Transform the light direction into tangent space */ "vec3 v;\n" "v.x = dot (light0_direction_norm, tangent);\n" "v.y = dot (light0_direction_norm, binormal);\n" "v.z = dot (light0_direction_norm, normal);\n" "light_direction = normalize (v);\n" /* Transform the eye direction into tangent space */ "v.x = dot (eye_direction, tangent);\n" "v.y = dot (eye_direction, binormal);\n" "v.z = dot (eye_direction, normal);\n" "eye_direction = normalize (v);\n"); /* Vertex shader setup for shadow mapping */ engine->shadow_mapping_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, /* definitions */ "uniform mat4 light_shadow_matrix;\n" "varying vec4 shadow_coords;\n", /* post */ "shadow_coords = light_shadow_matrix *\n" " cogl_position_in;\n"); engine->blended_discard_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ NULL, /* post */ "if (cogl_color_out.a <= 0.0 ||\n" " cogl_color_out.a >= " G_STRINGIFY (OPAQUE_THRESHOLD) ")\n" " discard;\n"); engine->unblended_discard_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ NULL, /* post */ "if (cogl_color_out.a < " G_STRINGIFY (OPAQUE_THRESHOLD) ")\n" " discard;\n"); engine->premultiply_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ NULL, /* post */ /* FIXME: Avoid premultiplying here by fiddling the * blend mode instead which should be more efficient */ "cogl_color_out.rgb *= cogl_color_out.a;\n"); engine->unpremultiply_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ NULL, /* post */ /* FIXME: We need to unpremultiply our colour at this * point to perform lighting, but this is obviously not * ideal and we should instead avoid being premultiplied * at this stage by not premultiplying our textures on * load for example. */ "cogl_color_out.rgb /= cogl_color_out.a;\n"); engine->normal_map_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ "uniform vec4 light0_ambient, light0_diffuse, light0_specular;\n" "uniform vec4 material_ambient, material_diffuse, material_specular;\n" "uniform float material_shininess;\n" "varying vec3 light_direction, eye_direction;\n", /* post */ "vec4 final_color;\n" "vec3 L = normalize(light_direction);\n" "vec3 N = texture2D(cogl_sampler5, cogl_tex_coord5_in.st).rgb;\n" "N = 2.0 * N - 1.0;\n" "N = normalize(N);\n" "vec4 ambient = light0_ambient * material_ambient;\n" "final_color = ambient * cogl_color_out;\n" "float lambert = dot(N, L);\n" "if (lambert > 0.0)\n" "{\n" " vec4 diffuse = light0_diffuse * material_diffuse;\n" " vec4 specular = light0_specular * material_specular;\n" " final_color += cogl_color_out * diffuse * lambert;\n" " vec3 E = normalize(eye_direction);\n" " vec3 R = reflect (-L, N);\n" " float specular_factor = pow (max(dot(R, E), 0.0),\n" " material_shininess);\n" " final_color += specular * specular_factor;\n" "}\n" "cogl_color_out.rgb = final_color.rgb;\n"); engine->material_lighting_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ "varying vec3 normal, eye_direction;\n" "uniform vec4 light0_ambient, light0_diffuse, light0_specular;\n" "uniform vec3 light0_direction_norm;\n" "uniform vec4 material_ambient, material_diffuse, material_specular;\n" "uniform float material_shininess;\n", /* post */ "vec4 final_color;\n" "vec3 L = light0_direction_norm;\n" "vec3 N = normalize(normal);\n" "vec4 ambient = light0_ambient * material_ambient;\n" "final_color = ambient * cogl_color_out;\n" "float lambert = dot(N, L);\n" "if (lambert > 0.0)\n" "{\n" " vec4 diffuse = light0_diffuse * material_diffuse;\n" " vec4 specular = light0_specular * material_specular;\n" " final_color += cogl_color_out * diffuse * lambert;\n" " vec3 E = normalize(eye_direction);\n" " vec3 R = reflect (-L, N);\n" " float specular_factor = pow (max(dot(R, E), 0.0),\n" " material_shininess);\n" " final_color += specular * specular_factor;\n" "}\n" "cogl_color_out.rgb = final_color.rgb;\n"); engine->simple_lighting_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* definitions */ "varying vec3 normal, eye_direction;\n" "uniform vec4 light0_ambient, light0_diffuse, light0_specular;\n" "uniform vec3 light0_direction_norm;\n", /* post */ "vec4 final_color;\n" "vec3 L = light0_direction_norm;\n" "vec3 N = normalize(normal);\n" "final_color = light0_ambient * cogl_color_out;\n" "float lambert = dot(N, L);\n" "if (lambert > 0.0)\n" "{\n" " final_color += cogl_color_out * light0_diffuse * lambert;\n" " vec3 E = normalize(eye_direction);\n" " vec3 R = reflect (-L, N);\n" " float specular = pow (max(dot(R, E), 0.0),\n" " 2.);\n" " final_color += light0_specular * vec4(.6, .6, .6, 1.0) *\n" " specular;\n" "}\n" "cogl_color_out.rgb = final_color.rgb;\n"); engine->shadow_mapping_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, /* declarations */ "varying vec4 shadow_coords;\n", /* post */ "vec4 texel7 = texture2D (cogl_sampler7,\n" " shadow_coords.xy);\n" "float distance_from_light = texel7.z + 0.0005;\n" "float shadow = 1.0;\n" "if (distance_from_light < shadow_coords.z)\n" " shadow = 0.5;\n" "cogl_color_out.rgb = shadow * cogl_color_out.rgb;\n"); }