void _st_paint_shadow_with_opacity (StShadow *shadow_spec, CoglHandle shadow_material, ClutterActorBox *box, guint8 paint_opacity) { ClutterActorBox shadow_box; CoglColor color; g_return_if_fail (shadow_spec != NULL); g_return_if_fail (shadow_material != COGL_INVALID_HANDLE); st_shadow_get_box (shadow_spec, box, &shadow_box); cogl_color_set_from_4ub (&color, shadow_spec->color.red * paint_opacity / 255, shadow_spec->color.green * paint_opacity / 255, shadow_spec->color.blue * paint_opacity / 255, shadow_spec->color.alpha * paint_opacity / 255); cogl_color_premultiply (&color); cogl_material_set_layer_combine_constant (shadow_material, 0, &color); cogl_set_source (shadow_material); cogl_rectangle_with_texture_coords (shadow_box.x1, shadow_box.y1, shadow_box.x2, shadow_box.y2, 0, 0, 1, 1); }
static void mx_fade_effect_paint_target (ClutterOffscreenEffect *effect) { guint8 opacity; CoglColor color; ClutterActor *actor; CoglMaterial *material = clutter_offscreen_effect_get_target (effect); MxFadeEffect *self = MX_FADE_EFFECT (effect); MxFadeEffectPrivate *priv = self->priv; if (priv->update_vbo) mx_fade_effect_update_vbo (self); if (!priv->vbo || !priv->indices || !material) return; /* Set the blend string if the material has changed so we can blend with * the paint opacity. */ if (material != priv->old_material) { GError *error = NULL; priv->old_material = material; if (!cogl_material_set_layer_combine (material, 1, "RGBA = MODULATE(PREVIOUS,CONSTANT)", &error)) { g_warning (G_STRLOC ": Error setting layer combine blend string: %s", error->message); g_error_free (error); } } /* Set the layer-combine constant so the texture is blended with the paint * opacity when painted. */ actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); opacity = clutter_actor_get_paint_opacity (actor); cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity); cogl_material_set_layer_combine_constant (material, 1, &color); /* Draw the texture */ cogl_set_source (material); cogl_vertex_buffer_draw_elements (priv->vbo, COGL_VERTICES_MODE_TRIANGLES, priv->indices, 0, (priv->n_quads * 4) - 1, 0, priv->n_quads * 6); }
void st_theme_node_transition_paint (StThemeNodeTransition *transition, ClutterActorBox *allocation, guint8 paint_opacity) { StThemeNodeTransitionPrivate *priv = transition->priv; CoglColor constant; float tex_coords[] = { 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, }; g_return_if_fail (ST_IS_THEME_NODE (priv->old_theme_node)); g_return_if_fail (ST_IS_THEME_NODE (priv->new_theme_node)); if (!clutter_actor_box_equal (allocation, &priv->last_allocation)) priv->needs_setup = TRUE; if (priv->needs_setup) { priv->last_allocation = *allocation; calculate_offscreen_box (transition, allocation); priv->needs_setup = !setup_framebuffers (transition, allocation); if (priv->needs_setup) /* setting up framebuffers failed */ return; } cogl_color_set_from_4f (&constant, 0., 0., 0., clutter_timeline_get_progress (priv->timeline)); cogl_material_set_layer_combine_constant (priv->material, 1, &constant); cogl_material_set_color4ub (priv->material, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_set_source (priv->material); cogl_rectangle_with_multitexture_coords (priv->offscreen_box.x1, priv->offscreen_box.y1, priv->offscreen_box.x2, priv->offscreen_box.y2, tex_coords, 8); }
int main (int argc, char **argv) { ClutterActor *stage = stage; ClutterActor *side_box; ClutterActor *button_box; ClutterActor *box; ClutterAnimation *anim; MashLightSet *light_set; MxStyle *style; GError *error = NULL; Data data; int i; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; style = mx_style_get_default (); if (!mx_style_load_from_file (style, "lights.css", &error)) { g_warning ("Error setting style: %s", error->message); g_clear_error (&error); } stage = clutter_stage_get_default (); clutter_actor_set_size (stage, 800, 600); side_box = mx_table_new (); clutter_actor_set_name (side_box, "side-box"); clutter_container_add_actor (CLUTTER_CONTAINER (stage), side_box); clutter_actor_set_size (side_box, 300, clutter_actor_get_height (stage)); clutter_actor_set_x (side_box, clutter_actor_get_width (stage) - clutter_actor_get_width (side_box)); button_box = mx_table_new (); mx_table_add_actor (MX_TABLE (side_box), button_box, 0, 0); data.notebook = mx_notebook_new (); mx_table_add_actor (MX_TABLE (side_box), data.notebook, 1, 0); data.model = mash_model_new_from_file (MASH_DATA_NONE, argc > 1 ? argv[1] : "suzanne.ply", &error); if (data.model == NULL) { g_warning ("Error loading model: %s", error->message); g_clear_error (&error); return 1; } light_set = mash_light_set_new (); box = clutter_box_new (clutter_fixed_layout_new ()); clutter_actor_set_size (data.model, 400, 400); clutter_actor_set_position (data.model, 50.0, 100.0); clutter_container_add_actor (CLUTTER_CONTAINER (box), data.model); clutter_container_add_actor (CLUTTER_CONTAINER (stage), box); g_signal_connect_swapped (box, "paint", G_CALLBACK (cogl_set_depth_test_enabled), GINT_TO_POINTER (TRUE)); g_signal_connect_data (box, "paint", G_CALLBACK (cogl_set_depth_test_enabled), GINT_TO_POINTER (FALSE), NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED); data.light_marker_material = cogl_material_new (); { CoglColor color; cogl_color_set_from_4ub (&color, 255, 0, 0, 255); /* Use the layer state to ignore the vertex color from the shader so that the light marker won't itself be lit */ cogl_material_set_layer_combine_constant (data.light_marker_material, 0, &color); cogl_material_set_layer_combine (data.light_marker_material, 0, "RGBA = REPLACE(CONSTANT)", NULL); } clutter_actor_set_rotation (data.model, CLUTTER_Y_AXIS, 0.0f, clutter_actor_get_width (data.model) / 2.0f, 0.0f, 0.0f); anim = clutter_actor_animate (data.model, CLUTTER_LINEAR, 3000, "rotation-angle-y", 360.0f, NULL); clutter_animation_set_loop (anim, TRUE); for (i = 0; i < N_LIGHTS; i++) { ClutterActor *table = mx_table_new (); ClutterActor *button; static ClutterActor *(* constructors[N_LIGHTS]) (void) = { mash_directional_light_new, mash_point_light_new, mash_spot_light_new }; static const ClutterColor black = { 0, 0, 0, 255 }; data.lights[i] = constructors[i] (); button = mx_button_new_with_label (G_OBJECT_TYPE_NAME (data.lights[i])); mx_table_add_actor (MX_TABLE (button_box), button, i, 0); /* Default to disable all of the lights */ g_object_set (data.lights[i], "ambient", &black, "diffuse", &black, "specular", &black, NULL); data.notebook_buttons[i] = button; clutter_container_add_actor (CLUTTER_CONTAINER (box), data.lights[i]); mash_light_set_add_light (light_set, MASH_LIGHT (data.lights[i])); add_color_prop (table, "ambient light", G_OBJECT (data.lights[i]), "ambient"); add_color_prop (table, "diffuse light", G_OBJECT (data.lights[i]), "diffuse"); add_color_prop (table, "specular light", G_OBJECT (data.lights[i]), "specular"); if (MASH_IS_POINT_LIGHT (data.lights[i])) { add_float_prop (table, "constant attenuation", G_OBJECT (data.lights[i]), "constant-attenuation", 0.0f, 10.0f); add_float_prop (table, "linear attenuation", G_OBJECT (data.lights[i]), "linear-attenuation", 0.0f, 10.0f); add_float_prop (table, "quadratic attenuation", G_OBJECT (data.lights[i]), "quadratic-attenuation", 0.0f, 10.0f); } if (MASH_IS_SPOT_LIGHT (data.lights[i])) { clutter_actor_set_x (data.lights[i], 250); add_float_prop (table, "spot cutoff", G_OBJECT (data.lights[i]), "spot-cutoff", 0.0f, 90.0f); add_float_prop (table, "spot exponent", G_OBJECT (data.lights[i]), "spot-exponent", 0.0f, 128.0f); } clutter_container_add_actor (CLUTTER_CONTAINER (data.notebook), table); data.notebook_pages[i] = table; } { ClutterActor *button; ClutterActor *table; CoglHandle material; float maximum_shininess; material = mash_model_get_pipeline (MASH_MODEL (data.model)); /* Before version 1.3.10 on the 1.3 branch and 1.2.14 on the 1.2 branch Cogl would remap the shininess property to the range [0,1]. After this it is just a value greater or equal to zero (but GL imposes a limit of 128.0) */ if (clutter_check_version (1, 3, 9) || (clutter_major_version == 1 && clutter_minor_version == 2 && clutter_micro_version >= 13)) maximum_shininess = 128.0f; else maximum_shininess = 1.0f; cogl_material_set_shininess (material, maximum_shininess); button = mx_button_new_with_label ("Material"); data.notebook_buttons[i] = button; mx_table_add_actor (MX_TABLE (button_box), button, i, 0); table = mx_table_new (); data.notebook_pages[i] = table; clutter_container_add_actor (CLUTTER_CONTAINER (data.notebook), table); add_material_color_prop (table, "emission", material, cogl_material_set_emission, cogl_material_get_emission); add_material_color_prop (table, "diffuse", material, cogl_material_set_diffuse, cogl_material_get_diffuse); add_material_color_prop (table, "ambient", material, cogl_material_set_ambient, cogl_material_get_ambient); add_material_color_prop (table, "specular", material, cogl_material_set_specular, cogl_material_get_specular); add_material_float_prop (table, "shininess", material, 0.0f, maximum_shininess, cogl_material_set_shininess, cogl_material_get_shininess); } mash_model_set_light_set (MASH_MODEL (data.model), light_set); g_object_unref (light_set); for (i = 0; i < N_PAGES; i++) { g_signal_connect (data.notebook_buttons[i], "notify::toggled", G_CALLBACK (notebook_button_cb), &data); mx_button_set_is_toggle (MX_BUTTON (data.notebook_buttons[i]), TRUE); } mx_button_set_toggled (MX_BUTTON (data.notebook_buttons[0]), TRUE); g_signal_connect (stage, "motion-event", G_CALLBACK (motion_event_cb), &data); clutter_actor_show (stage); clutter_main (); cogl_handle_unref (data.light_marker_material); return 0; }