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); }
CoglHandle _st_create_shadow_material_from_actor (StShadow *shadow_spec, ClutterActor *actor) { CoglHandle shadow_material = COGL_INVALID_HANDLE; if (CLUTTER_IS_TEXTURE (actor)) { CoglHandle texture; texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor)); shadow_material = _st_create_shadow_material (shadow_spec, texture); } else { CoglHandle buffer, offscreen; ClutterActorBox box; CoglColor clear_color; float width, height; clutter_actor_get_allocation_box (actor, &box); clutter_actor_box_get_size (&box, &width, &height); if (width == 0 || height == 0) return COGL_INVALID_HANDLE; buffer = st_cogl_texture_new_with_size_wrapper (width, height, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); if (buffer == COGL_INVALID_HANDLE) return COGL_INVALID_HANDLE; offscreen = cogl_offscreen_new_to_texture (buffer); if (offscreen == COGL_INVALID_HANDLE) { cogl_handle_unref (buffer); return COGL_INVALID_HANDLE; } cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); cogl_push_framebuffer (offscreen); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_translate (-box.x1, -box.y1, 0); cogl_ortho (0, width, height, 0, 0, 1.0); clutter_actor_paint (actor); cogl_pop_framebuffer (); cogl_handle_unref (offscreen); shadow_material = _st_create_shadow_material (shadow_spec, buffer); cogl_handle_unref (buffer); } return shadow_material; }
void cogl_set_source_color4ub (guint8 red, guint8 green, guint8 blue, guint8 alpha) { CoglColor c = { 0, }; cogl_color_set_from_4ub (&c, red, green, blue, alpha); cogl_set_source_color (&c); }
static void update_fps (ClutterActor *stage, GTimer *timer) { static PangoLayout *layout = NULL; static guint counter = 0; static CoglColor white; gdouble resolution; gchar *text; if (!layout) { PangoFontDescription *pango_font_desc; CoglPangoFontMap *pango_font_map; PangoContext *pango_context; cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff); pango_font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new()); resolution = clutter_backend_get_resolution (clutter_get_default_backend ()); cogl_pango_font_map_set_resolution (pango_font_map, resolution); cogl_pango_font_map_set_use_mipmapping (pango_font_map, TRUE); pango_context = cogl_pango_font_map_create_context (pango_font_map); pango_font_desc = pango_font_description_new (); pango_font_description_set_family (pango_font_desc, "Sans"); pango_font_description_set_size (pango_font_desc, 30 * PANGO_SCALE); layout = pango_layout_new (pango_context); pango_layout_set_font_description (layout, pango_font_desc); pango_font_description_free (pango_font_desc); g_object_unref (pango_context); } if (g_timer_elapsed (timer, NULL) > 0.5) { text = g_strdup_printf ("%dfps", counter * 2); pango_layout_set_text (layout, text, -1); g_free (text); g_timer_start (timer); counter = 0; } else counter++; cogl_pango_render_layout (layout, 0, 0, &white, 0); }
static void color_prop_value_cb (MxSlider *slider, GParamSpec *pspec, ColorPropComp *prop_comp) { float value = mx_slider_get_value (slider) * 255.0f + 0.5f; ColorProp *prop = prop_comp->prop; if (prop->object) { ClutterColor *color; g_object_get (prop->object, prop->prop_name, &color, NULL); ((guint8 *) color)[prop_comp->comp_num] = value; clutter_rectangle_set_color (CLUTTER_RECTANGLE (prop->rect), color); g_object_set (prop->object, prop->prop_name, color, NULL); clutter_color_free (color); } else { ClutterColor color; CoglColor cogl_color; prop->get_func (prop->material, &cogl_color); color.red = cogl_color_get_red_byte (&cogl_color); color.green = cogl_color_get_green_byte (&cogl_color); color.blue = cogl_color_get_blue_byte (&cogl_color); color.alpha = 255; ((guint8 *) &color)[prop_comp->comp_num] = value; cogl_color_set_from_4ub (&cogl_color, color.red, color.green, color.blue, 255); clutter_rectangle_set_color (CLUTTER_RECTANGLE (prop->rect), &color); prop->set_func (prop->material, &cogl_color); } update_prop_comp_label (prop_comp, value); }
static CoglHandle data_to_cogl_handle (const guchar *data, gboolean has_alpha, int width, int height, int rowstride, gboolean add_padding) { CoglHandle texture, offscreen; CoglColor clear_color; guint size; size = MAX (width, height); if (!add_padding || width == height) return cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE, has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, rowstride, data); texture = cogl_texture_new_with_size (size, size, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); offscreen = cogl_offscreen_new_to_texture (texture); cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); cogl_push_framebuffer (offscreen); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_pop_framebuffer (); cogl_handle_unref (offscreen); cogl_texture_set_region (texture, 0, 0, (size - width) / 2, (size - height) / 2, width, height, width, height, has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, rowstride, data); return texture; }
static CoglHandle pixbuf_to_cogl_handle (GdkPixbuf *pixbuf, gboolean add_padding) { CoglHandle texture, offscreen; CoglColor clear_color; int width, height; guint size; width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); size = MAX (width, height); if (!add_padding || width == height) return cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE, gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, gdk_pixbuf_get_rowstride (pixbuf), gdk_pixbuf_get_pixels (pixbuf)); texture = cogl_texture_new_with_size (size, size, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); offscreen = cogl_offscreen_new_to_texture (texture); cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); cogl_push_framebuffer (offscreen); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_pop_framebuffer (); cogl_handle_unref (offscreen); cogl_texture_set_region (texture, 0, 0, (size - width) / 2, (size - height) / 2, width, height, width, height, gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_rowstride (pixbuf), gdk_pixbuf_get_pixels (pixbuf)); return texture; }
void _display_loop (void) { context_switch_allegro (); ALLEGRO_BITMAP *bmp; bmp = al_create_bitmap (640, 480); int blah; for (blah=0; blah < 64; ++blah) { struct fbstate_data fbd; context_switch_cogl (); fbd = fbstate_get_data (); context_switch_allegro (); ALLEGRO_LOCKED_REGION *rgn; rgn = al_lock_bitmap (bmp, ALLEGRO_PIXEL_FORMAT_BGR_888, ALLEGRO_LOCK_READWRITE); int cnt; char *data; for (cnt=0,data=rgn->data; cnt < 480; ++cnt,data+=rgn->pitch) { memcpy (data, &fbd.data[cnt*640*3], 640*3); } al_unlock_bitmap (bmp); context_switch_cogl (); CoglColor clear_color; cogl_color_set_from_4ub (&clear_color, '0', '0', '0', 255); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); _example_draw_at (blah, blah); context_switch_allegro (); al_set_target_backbuffer (fbd.display); al_draw_bitmap (bmp, 0, 0, 0); al_flip_display (); al_rest (0.1f); } al_rest (2.0f); }
static void aisleriot_slot_renderer_set_material_for_card (AisleriotSlotRenderer *srend, CoglHandle tex, gboolean show_highlight) { AisleriotSlotRendererPrivate *priv = srend->priv; guint8 opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (srend)); if (priv->material == COGL_INVALID_HANDLE) priv->material = cogl_material_new (); if (show_highlight) { CoglColor color; /* The previous code for drawing the highlight rendered the normal card texture and then rendered the card again multiplied by the highlight color but with 50% transparency. The blend function is alpha*src+(1-alpha*dst) where src is effectively the tex times the highlight color and the dst is the original tex. Therefore the final color is 0.5*tex+0.5*tex*highlight which is the same as (0.5+highlight/2)*tex. We can precompute that value to avoid having to draw the card twice */ cogl_color_set_from_4ub (&color, MIN (priv->highlight_color.red / 2 + 128, 0xff), MIN (priv->highlight_color.green / 2 + 128, 0xff), MIN (priv->highlight_color.blue / 2 + 128, 0xff), opacity); cogl_color_premultiply (&color); cogl_material_set_color (priv->material, &color); } else cogl_material_set_color4ub (priv->material, opacity, opacity, opacity, opacity); cogl_material_set_layer (priv->material, 0, tex); cogl_set_source (priv->material); }
/** * meta_create_color_texture_4ub: * @red: * @green: * @blue: * @alpha: * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE; * %COGL_TEXTURE_NO_SLICING is useful if the texture will be * repeated to create a constant color fill, since hardware * repeat can't be used for a sliced texture. * * Creates a texture that is a single pixel with the specified * unpremultiplied color components. * * Return value: (transfer full): a newly created Cogl texture */ CoglHandle meta_create_color_texture_4ub (guint8 red, guint8 green, guint8 blue, guint8 alpha, CoglTextureFlags flags) { CoglColor color; guint8 pixel[4]; cogl_color_set_from_4ub (&color, red, green, blue, alpha); cogl_color_premultiply (&color); pixel[0] = cogl_color_get_red_byte (&color); pixel[1] = cogl_color_get_green_byte (&color); pixel[2] = cogl_color_get_blue_byte (&color); pixel[3] = cogl_color_get_alpha_byte (&color); return cogl_texture_new_from_data (1, 1, flags, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_PIXEL_FORMAT_ANY, 4, pixel); }
static void mx_deform_bow_tie_deform (MxDeformTexture *texture, CoglTextureVertex *vertex, gfloat width, gfloat height) { gfloat cx, cy, rx, ry, turn_angle, height_radius; guint shade; MxDeformBowTiePrivate *priv = ((MxDeformBowTie *)texture)->priv; cx = priv->period * (width + width/2); cy = height/2; rx = ((vertex->x - cx) * cos (0)) - ((vertex->y - cy) * sin (0)); ry = ((vertex->x - cx) * sin (0)) + ((vertex->y - cy) * cos (0)); /* Make angle as a function of distance from the curl ray */ turn_angle = MAX (-G_PI, MIN (0, (rx / (width/4)) * G_PI_2)); /* Add a gradient that makes it look like lighting */ shade = (cos (turn_angle * 2) * 96) + 159; cogl_color_set_from_4ub (&vertex->color, shade, shade, shade, 0xff); /* Calculate the point on a cone (note, a cone, not a right cone) */ height_radius = ry; /*ClutterFixed height_radius = clutter_qmulx (clutter_qdivx (ry, height/2), height/2);*/ ry = height_radius * cos (turn_angle); vertex->x = (rx * cos (0)) - (ry * sin (0)) + cx; vertex->y = (rx * sin (0)) + (ry * cos (0)) + cy; vertex->z = height_radius * sin (turn_angle); }
int main (int argc, char **argv) { CoglContext *ctx; CoglOnscreen *onscreen; CoglFramebuffer *fb; GError *error = NULL; Data data; PangoRectangle hello_label_size; float fovy, aspect, z_near, z_2d, z_far; CoglDepthState depth_state; CoglBool has_swap_notify; ctx = cogl_context_new (NULL, &error); if (!ctx) { fprintf (stderr, "Failed to create context: %s\n", error->message); return 1; } onscreen = cogl_onscreen_new (ctx, 640, 480); fb = COGL_FRAMEBUFFER (onscreen); data.fb = fb; data.framebuffer_width = cogl_framebuffer_get_width (fb); data.framebuffer_height = cogl_framebuffer_get_height (fb); data.timer = g_timer_new (); cogl_onscreen_show (onscreen); cogl_framebuffer_set_viewport (fb, 0, 0, data.framebuffer_width, data.framebuffer_height); fovy = 60; /* y-axis field of view */ aspect = (float)data.framebuffer_width/(float)data.framebuffer_height; z_near = 0.1; /* distance to near clipping plane */ z_2d = 1000; /* position to 2d plane */ z_far = 2000; /* distance to far clipping plane */ cogl_framebuffer_perspective (fb, fovy, aspect, z_near, z_far); /* Since the pango renderer emits geometry in pixel/device coordinates * and the anti aliasing is implemented with the assumption that the * geometry *really* does end up pixel aligned, we setup a modelview * matrix so that for geometry in the plane z = 0 we exactly map x * coordinates in the range [0,stage_width] and y coordinates in the * range [0,stage_height] to the framebuffer extents with (0,0) being * the top left. * * This is roughly what Clutter does for a ClutterStage, but this * demonstrates how it is done manually using Cogl. */ cogl_matrix_init_identity (&data.view); cogl_matrix_view_2d_in_perspective (&data.view, fovy, aspect, z_near, z_2d, data.framebuffer_width, data.framebuffer_height); cogl_framebuffer_set_modelview_matrix (fb, &data.view); /* Initialize some convenient constants */ cogl_matrix_init_identity (&identity); cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff); /* rectangle indices allow the GPU to interpret a list of quads (the * faces of our cube) as a list of triangles. * * Since this is a very common thing to do * cogl_get_rectangle_indices() is a convenience function for * accessing internal index buffers that can be shared. */ data.indices = cogl_get_rectangle_indices (ctx, 6 /* n_rectangles */); data.prim = cogl_primitive_new_p3t2 (ctx, COGL_VERTICES_MODE_TRIANGLES, G_N_ELEMENTS (vertices), vertices); /* Each face will have 6 indices so we have 6 * 6 indices in total... */ cogl_primitive_set_indices (data.prim, data.indices, 6 * 6); /* Load a jpeg crate texture from a file */ printf ("crate.jpg (CC by-nc-nd http://bit.ly/9kP45T) ShadowRunner27 http://bit.ly/m1YXLh\n"); data.texture = cogl_texture_new_from_file (COGL_EXAMPLES_DATA "crate.jpg", COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY, &error); if (!data.texture) g_error ("Failed to load texture: %s", error->message); /* a CoglPipeline conceptually describes all the state for vertex * processing, fragment processing and blending geometry. When * drawing the geometry for the crate this pipeline says to sample a * single texture during fragment processing... */ data.crate_pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_layer_texture (data.crate_pipeline, 0, data.texture); /* Since the box is made of multiple triangles that will overlap * when drawn and we don't control the order they are drawn in, we * enable depth testing to make sure that triangles that shouldn't * be visible get culled by the GPU. */ cogl_depth_state_init (&depth_state); cogl_depth_state_set_test_enabled (&depth_state, TRUE); cogl_pipeline_set_depth_state (data.crate_pipeline, &depth_state, NULL); /* Setup a Pango font map and context */ data.pango_font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new (ctx)); cogl_pango_font_map_set_use_mipmapping (data.pango_font_map, TRUE); data.pango_context = pango_font_map_create_context (PANGO_FONT_MAP (data.pango_font_map)); data.pango_font_desc = pango_font_description_new (); pango_font_description_set_family (data.pango_font_desc, "Sans"); pango_font_description_set_size (data.pango_font_desc, 30 * PANGO_SCALE); /* Setup the "Hello Cogl" text */ data.hello_label = pango_layout_new (data.pango_context); pango_layout_set_font_description (data.hello_label, data.pango_font_desc); pango_layout_set_text (data.hello_label, "Hello Cogl", -1); pango_layout_get_extents (data.hello_label, NULL, &hello_label_size); data.hello_label_width = PANGO_PIXELS (hello_label_size.width); data.hello_label_height = PANGO_PIXELS (hello_label_size.height); data.swap_ready = TRUE; has_swap_notify = cogl_has_feature (ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT); if (has_swap_notify) cogl_onscreen_add_swap_buffers_callback (COGL_ONSCREEN (fb), swap_notify_cb, &data); while (1) { CoglPollFD *poll_fds; int n_poll_fds; int64_t timeout; if (data.swap_ready) { paint (&data); cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb)); } cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout); if (!has_swap_notify) { /* If the winsys doesn't support swap event notification then we'll just redraw constantly */ data.swap_ready = TRUE; timeout = 0; } g_poll ((GPollFD *) poll_fds, n_poll_fds, timeout == -1 ? -1 : timeout / 1000); cogl_poll_dispatch (ctx, poll_fds, n_poll_fds); } return 0; }
static CoglHandle data_to_cogl_handle (const guchar *data, gboolean has_alpha, int width, int height, int rowstride, gboolean add_padding) { CoglHandle texture, offscreen; CoglColor clear_color; guint size; GError *error; size = MAX (width, height); if (!add_padding || width == height) return cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE, has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, rowstride, data); texture = cogl_texture_new_with_size (size, size, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); offscreen = cogl_offscreen_new_with_texture (texture); error = NULL; if (!cogl_framebuffer_allocate (offscreen, &error)) { g_warning ("Failed to allocate FBO (sized %d): %s", size, error->message); cogl_object_unref (texture); cogl_object_unref (offscreen); g_clear_error (&error); return cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE, has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, rowstride, data); } cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); cogl_push_framebuffer (offscreen); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_pop_framebuffer (); cogl_handle_unref (offscreen); cogl_texture_set_region (texture, 0, 0, (size - width) / 2, (size - height) / 2, width, height, width, height, has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, rowstride, data); return texture; }
static void paint (TestState *state) { CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); CoglTexture *tex; CoglColor color; CoglError *error = NULL; CoglHandle shader, program; cogl_color_init_from_4ub (&color, 0, 0, 0, 255); cogl_clear (&color, COGL_BUFFER_BIT_COLOR); /* Set the primary vertex color as red */ cogl_color_set_from_4ub (&color, 0xff, 0x00, 0x00, 0xff); cogl_pipeline_set_color (pipeline, &color); /* 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 fixed function transform */ shader = cogl_create_shader (COGL_SHADER_TYPE_VERTEX); cogl_shader_source (shader, "void\n" "main ()\n" "{\n" " cogl_position_out = " "cogl_modelview_projection_matrix * " "cogl_position_in;\n" " cogl_color_out = cogl_color_in;\n" " cogl_tex_coord_out[0] = cogl_tex_coord_in;\n" "}\n"); cogl_shader_compile (shader); if (!cogl_shader_is_compiled (shader)) { char *log = cogl_shader_get_info_log (shader); g_warning ("Shader compilation failed:\n%s", log); g_free (log); g_assert_not_reached (); } program = cogl_create_program (); cogl_program_attach_shader (program, shader); cogl_program_link (program); cogl_handle_unref (shader); /* Draw something without the program */ cogl_set_source (pipeline); cogl_rectangle (0, 0, 50, 50); /* Draw it again using the program. It should look exactly the same */ cogl_pipeline_set_user_program (pipeline, program); cogl_handle_unref (program); cogl_rectangle (50, 0, 100, 50); cogl_pipeline_set_user_program (pipeline, COGL_INVALID_HANDLE); cogl_object_unref (pipeline); }
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; }
static void mx_scroll_view_paint (ClutterActor *actor) { ClutterActorBox box; gfloat w, h; MxAdjustment *vadjustment = NULL, *hadjustment = NULL; MxScrollViewPrivate *priv = MX_SCROLL_VIEW (actor)->priv; ClutterColor *color; guint8 r, g, b; const gint shadow = 15; mx_stylable_get (MX_STYLABLE (actor), "background-color", &color, NULL); r = color->red; g = color->green; b = color->blue; clutter_color_free (color); /* MxBin will paint the child */ CLUTTER_ACTOR_CLASS (mx_scroll_view_parent_class)->paint (actor); clutter_actor_get_allocation_box (actor, &box); w = box.x2 - box.x1; h = box.y2 - box.y1; /* paint our custom children */ if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll)) { clutter_actor_paint (priv->hscroll); clutter_actor_get_allocation_box (priv->hscroll, &box); h -= (box.y2 - box.y1); hadjustment = mx_scroll_bar_get_adjustment (MX_SCROLL_BAR(priv->hscroll)); } if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll)) { clutter_actor_paint (priv->vscroll); clutter_actor_get_allocation_box (priv->vscroll, &box); w -= (box.x2 - box.x1); vadjustment = mx_scroll_bar_get_adjustment (MX_SCROLL_BAR(priv->vscroll)); } /* set up the matrial using dummy set source call */ cogl_set_source_color4ub (0, 0, 0, 0); if (vadjustment) { gdouble len; if ((len = mx_adjustment_get_value (vadjustment)) > 0) { CoglTextureVertex top[4] = { { 0,}, }; if (len > shadow) len = shadow; top[1].x = w; top[2].x = w; top[2].y = len; top[3].y = len; cogl_color_set_from_4ub (&top[0].color, r, g, b, 0xff); cogl_color_set_from_4ub (&top[1].color, r, g, b, 0xff); cogl_color_set_from_4ub (&top[2].color, 0, 0, 0, 0); cogl_color_set_from_4ub (&top[3].color, 0, 0, 0, 0); cogl_polygon (top, 4, TRUE); } if ((len = (mx_adjustment_get_upper (vadjustment) - mx_adjustment_get_page_size (vadjustment)) - mx_adjustment_get_value (vadjustment)) > 0) { CoglTextureVertex bottom[4] = { {0, }, }; if (len > shadow) len = shadow; bottom[0].x = w; bottom[0].y = h; bottom[1].y = h; bottom[2].y = h - len; bottom[3].x = w; bottom[3].y = h - len; cogl_color_set_from_4ub (&bottom[0].color, r, g, b, 0xff); cogl_color_set_from_4ub (&bottom[1].color, r, g, b, 0xff); cogl_color_set_from_4ub (&bottom[2].color, 0, 0, 0, 0); cogl_color_set_from_4ub (&bottom[3].color, 0, 0, 0, 0); cogl_polygon (bottom, 4, TRUE); } } if (hadjustment) { gdouble len; if ((len = mx_adjustment_get_value (hadjustment)) > 0) { CoglTextureVertex left[4] = { { 0, }, }; if (len > shadow) len = shadow; left[0].y = h; left[2].x = len; left[3].x = len; left[3].y = h; cogl_color_set_from_4ub (&left[0].color, r, g, b, 0xff); cogl_color_set_from_4ub (&left[1].color, r, g, b, 0xff); cogl_color_set_from_4ub (&left[2].color, 0, 0, 0, 0); cogl_color_set_from_4ub (&left[3].color, 0, 0, 0, 0); cogl_polygon (left, 4, TRUE); } if ((len = (mx_adjustment_get_upper (hadjustment) - mx_adjustment_get_page_size (hadjustment)) - mx_adjustment_get_value (hadjustment)) > 0) { CoglTextureVertex right[4] = { { 0, }, }; if (len > shadow) len = shadow; right[0].x = w; right[1].x = w; right[1].y = h; right[2].x = w - len; right[2].y = h; right[3].x = w - len; cogl_color_set_from_4ub (&right[0].color, r, g, b, 0xff); cogl_color_set_from_4ub (&right[1].color, r, g, b, 0xff); cogl_color_set_from_4ub (&right[2].color, 0, 0, 0, 0); cogl_color_set_from_4ub (&right[3].color, 0, 0, 0, 0); cogl_polygon (right, 4, TRUE); } } }
static void st_drawing_area_paint (ClutterActor *self) { StDrawingArea *area = ST_DRAWING_AREA (self); StDrawingAreaPrivate *priv = area->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self)); ClutterActorBox allocation_box; ClutterActorBox content_box; int width, height; CoglColor color; guint8 paint_opacity; (CLUTTER_ACTOR_CLASS (st_drawing_area_parent_class))->paint (self); clutter_actor_get_allocation_box (self, &allocation_box); st_theme_node_get_content_box (theme_node, &allocation_box, &content_box); width = (int)(0.5 + content_box.x2 - content_box.x1); height = (int)(0.5 + content_box.y2 - content_box.y1); if (priv->material == COGL_INVALID_HANDLE) priv->material = cogl_material_new (); if (priv->texture != COGL_INVALID_HANDLE && (width != cogl_texture_get_width (priv->texture) || height != cogl_texture_get_height (priv->texture))) { cogl_handle_unref (priv->texture); priv->texture = COGL_INVALID_HANDLE; } if (width > 0 && height > 0) { if (priv->texture == COGL_INVALID_HANDLE) { priv->texture = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NONE, CLUTTER_CAIRO_FORMAT_ARGB32); priv->needs_repaint = TRUE; } if (priv->needs_repaint) { cairo_surface_t *surface; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); priv->context = cairo_create (surface); priv->in_repaint = TRUE; priv->needs_repaint = FALSE; g_signal_emit ((GObject*)area, st_drawing_area_signals[REPAINT], 0); priv->in_repaint = FALSE; cairo_destroy (priv->context); priv->context = NULL; cogl_texture_set_region (priv->texture, 0, 0, 0, 0, width, height, width, height, CLUTTER_CAIRO_FORMAT_ARGB32, cairo_image_surface_get_stride (surface), cairo_image_surface_get_data (surface)); cairo_surface_destroy (surface); } } cogl_material_set_layer (priv->material, 0, priv->texture); if (priv->texture) { paint_opacity = clutter_actor_get_paint_opacity (self); cogl_color_set_from_4ub (&color, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_material_set_color (priv->material, &color); cogl_set_source (priv->material); cogl_rectangle_with_texture_coords (content_box.x1, content_box.y1, width, height, 0.0f, 0.0f, 1.0f, 1.0f); } }