int main (int argc, char *argv[]) { ClutterActor *stage, *box, *bg, *icon, *emblem, *label; ClutterLayoutManager *layout; ClutterContent *canvas, *image; ClutterColor *color; ClutterAction *action; GdkPixbuf *pixbuf; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; /* prepare the stage */ stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "BinLayout"); clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium2); clutter_actor_set_size (stage, 640, 480); clutter_actor_show (stage); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); /* this is our BinLayout, with its default alignments */ layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, CLUTTER_BIN_ALIGNMENT_CENTER); /* the main container; this actor will use the BinLayout to lay * out its children; we use the anchor point to keep it centered * on the same position even when we change its size */ box = clutter_actor_new (); clutter_actor_set_layout_manager (box, layout); clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); clutter_actor_set_position (box, 320, 240); clutter_actor_set_reactive (box, TRUE); clutter_actor_set_name (box, "box"); clutter_actor_add_child (stage, box); /* the background is drawn using a canvas content */ canvas = clutter_canvas_new (); g_signal_connect (canvas, "draw", G_CALLBACK (on_canvas_draw), NULL); clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 200, 200); /* this is the background actor; we want it to fill the whole * of the allocation given to it by its parent */ bg = clutter_actor_new (); clutter_actor_set_name (bg, "background"); clutter_actor_set_size (bg, 200, 200); clutter_actor_set_content (bg, canvas); clutter_actor_set_x_expand (bg, TRUE); clutter_actor_set_y_expand (bg, TRUE); clutter_actor_set_x_align (bg, CLUTTER_ACTOR_ALIGN_FILL); clutter_actor_set_y_align (bg, CLUTTER_ACTOR_ALIGN_FILL); clutter_actor_add_child (box, bg); /* we use the ::transitions-completed signal to get notification * of the end of the sizing animation; this allows us to redraw * the canvas only once the animation has stopped */ g_signal_connect (box, "transitions-completed", G_CALLBACK (redraw_canvas), canvas); /* we use GdkPixbuf to load an image from our data directory */ pixbuf = gdk_pixbuf_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", NULL); image = clutter_image_new (); clutter_image_set_data (CLUTTER_IMAGE (image), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), NULL); g_object_unref (pixbuf); /* this is the icon; it's going to be centered inside the box actor. * we use the content gravity to keep the aspect ratio of the image, * and the scaling filters to get a better result when scaling the * image down. */ icon = clutter_actor_new (); clutter_actor_set_name (icon, "icon"); clutter_actor_set_size (icon, 196, 196); clutter_actor_set_x_expand (icon, TRUE); clutter_actor_set_y_expand (icon, TRUE); clutter_actor_set_x_align (icon, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_align (icon, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_content_gravity (icon, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT); clutter_actor_set_content_scaling_filters (icon, CLUTTER_SCALING_FILTER_TRILINEAR, CLUTTER_SCALING_FILTER_LINEAR); clutter_actor_set_content (icon, image); clutter_actor_add_child (box, icon); color = clutter_color_new (g_random_int_range (0, 255), g_random_int_range (0, 255), g_random_int_range (0, 255), 224); /* this is the emblem: a small rectangle with a random color, that we * want to put in the bottom right corner */ emblem = clutter_actor_new (); clutter_actor_set_name (emblem, "emblem"); clutter_actor_set_size (emblem, 48, 48); clutter_actor_set_background_color (emblem, color); clutter_actor_set_x_expand (emblem, TRUE); clutter_actor_set_y_expand (emblem, TRUE); clutter_actor_set_x_align (emblem, CLUTTER_ACTOR_ALIGN_END); clutter_actor_set_y_align (emblem, CLUTTER_ACTOR_ALIGN_END); clutter_actor_set_reactive (emblem, TRUE); clutter_actor_set_opacity (emblem, 0); clutter_actor_add_child (box, emblem); clutter_color_free (color); /* when clicking on the emblem, we want to perform an action */ action = clutter_click_action_new (); clutter_actor_add_action (emblem, action); g_signal_connect (action, "clicked", G_CALLBACK (on_emblem_clicked), box); g_signal_connect (action, "long-press", G_CALLBACK (on_emblem_long_press), box); /* whenever the pointer enters the box, we show the emblem; we hide * the emblem when the pointer leaves the box */ g_signal_connect (box, "enter-event", G_CALLBACK (on_box_enter), emblem); g_signal_connect (box, "leave-event", G_CALLBACK (on_box_leave), emblem); /* a label, that we want to position at the top and center of the box */ label = clutter_text_new (); clutter_actor_set_name (label, "text"); clutter_text_set_text (CLUTTER_TEXT (label), "A simple test"); clutter_actor_set_x_expand (label, TRUE); clutter_actor_set_x_align (label, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_expand (label, TRUE); clutter_actor_set_y_align (label, CLUTTER_ACTOR_ALIGN_START); clutter_actor_add_child (box, label); clutter_main (); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { ClutterActor *video; /* So we can fade out at the end. */ clutter_x11_set_use_argb_visual (TRUE); if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; if (argc < 2) { g_print ("Usage: %s [OPTIONS] <video file>\n", argv[0]); return EXIT_FAILURE; } if (!clutter_color_from_string (&bg_color, BG_COLOR)) { g_warning ("Invalid BG_COLOR"); exit (1); } stage = clutter_stage_new (); /* Clutter's full-screening code does not allow us to * set both that and _NET_WM_STATE_ABOVE, so do the state * management ourselves for now. */ #if 0 clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), TRUE); #endif /* Clutter will set maximum size restrictions (meaning not * full screen) unless I set this. */ clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_background_color (stage, &bg_color); clutter_actor_set_layout_manager (stage, clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FIXED, CLUTTER_BIN_ALIGNMENT_FIXED)); clutter_actor_realize (stage); set_above_and_fullscreen (); video = clutter_gst_video_texture_new (); clutter_actor_set_x_expand (video, TRUE); clutter_actor_set_y_expand (video, TRUE); clutter_actor_set_x_align (video, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_align (video, CLUTTER_ACTOR_ALIGN_CENTER); set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (video)); g_signal_connect (video, "eos", G_CALLBACK (on_video_texture_eos), NULL); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_media_set_filename (CLUTTER_MEDIA (video), argv[1]); clutter_stage_hide_cursor (CLUTTER_STAGE (stage)); clutter_actor_add_child (stage, video); g_signal_connect (stage, "key-press-event", G_CALLBACK (key_press_cb), NULL); clutter_media_set_playing (CLUTTER_MEDIA (video), TRUE); clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *widget, *vbox, *bbox, *button, *viewport, *image; ChamplainView *view; ChamplainMarkerLayer *layer; ClutterActor *scale; ChamplainLicense *license_actor; if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; /* create the main, top level, window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* give the window a 10px wide border */ gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* give it the title */ gtk_window_set_title (GTK_WINDOW (window), "libchamplain Gtk+ demo"); /* Connect the destroy event of the window with our on_destroy function * When the window is about to be destroyed we get a notificaiton and * stop the main GTK loop */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (on_destroy), NULL); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10); widget = gtk_champlain_embed_new (); view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (widget)); clutter_actor_set_reactive (CLUTTER_ACTOR (view), TRUE); g_signal_connect (view, "button-release-event", G_CALLBACK (mouse_click_cb), view); g_object_set (G_OBJECT (view), "kinetic-mode", TRUE, "zoom-level", 5, NULL); g_object_set_data (G_OBJECT (view), "window", window); scale = champlain_scale_new (); champlain_scale_connect_view (CHAMPLAIN_SCALE (scale), view); /* align to the bottom left */ clutter_actor_set_x_expand (scale, TRUE); clutter_actor_set_y_expand (scale, TRUE); clutter_actor_set_x_align (scale, CLUTTER_ACTOR_ALIGN_START); clutter_actor_set_y_align (scale, CLUTTER_ACTOR_ALIGN_END); clutter_actor_add_child (CLUTTER_ACTOR (view), scale); license_actor = champlain_view_get_license_actor (view); champlain_license_set_extra_text (license_actor, "Don't eat cereals with orange juice\nIt tastes bad"); champlain_view_center_on (CHAMPLAIN_VIEW (view), 45.466, -73.75); layer = create_marker_layer (view, &path); champlain_view_add_layer (view, CHAMPLAIN_LAYER (path)); champlain_view_add_layer (view, CHAMPLAIN_LAYER (layer)); path_layer = champlain_path_layer_new (); /* Cheap approx of Highway 10 */ append_point (path_layer, 45.4095, -73.3197); append_point (path_layer, 45.4104, -73.2846); append_point (path_layer, 45.4178, -73.2239); append_point (path_layer, 45.4176, -73.2181); append_point (path_layer, 45.4151, -73.2126); append_point (path_layer, 45.4016, -73.1926); append_point (path_layer, 45.3994, -73.1877); append_point (path_layer, 45.4000, -73.1815); append_point (path_layer, 45.4151, -73.1218); champlain_view_add_layer (view, CHAMPLAIN_LAYER (path_layer)); gtk_widget_set_size_request (widget, 640, 481); bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10); button = gtk_button_new (); image = gtk_image_new_from_icon_name ("zoom-in", GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button), image); gtk_button_set_label (GTK_BUTTON (button), "Zoom In"); g_signal_connect (button, "clicked", G_CALLBACK (zoom_in), view); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_button_new (); image = gtk_image_new_from_icon_name ("zoom-out", GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button), image); gtk_button_set_label (GTK_BUTTON (button), "Zoom Out"); g_signal_connect (button, "clicked", G_CALLBACK (zoom_out), view); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_toggle_button_new_with_label ("Markers"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); g_signal_connect (button, "toggled", G_CALLBACK (toggle_layer), layer); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_toggle_button_new_with_label ("Toggle wrap"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), champlain_view_get_horizontal_wrap (view)); g_signal_connect (button, "toggled", G_CALLBACK (toggle_wrap), view); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_combo_box_new (); build_combo_box (GTK_COMBO_BOX (button)); gtk_combo_box_set_active (GTK_COMBO_BOX (button), 0); g_signal_connect (button, "changed", G_CALLBACK (map_source_changed), view); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_spin_button_new_with_range (0, 20, 1); gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), champlain_view_get_zoom_level (view)); g_signal_connect (button, "changed", G_CALLBACK (zoom_changed), view); g_signal_connect (view, "notify::zoom-level", G_CALLBACK (map_zoom_changed), button); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_button_new (); image = gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button), image); g_signal_connect (button, "clicked", G_CALLBACK (add_clicked), view); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_button_new (); image = gtk_image_new_from_icon_name ("camera-photo-symbolic", GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button), image); g_signal_connect (button, "clicked", G_CALLBACK (export_png), view); gtk_container_add (GTK_CONTAINER (bbox), button); button = gtk_image_new (); gtk_widget_set_size_request (button, 22, -1); g_signal_connect (view, "notify::state", G_CALLBACK (view_state_changed), button); gtk_box_pack_end (GTK_BOX (bbox), button, FALSE, FALSE, 0); viewport = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (viewport), widget); gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (vbox), viewport); /* and insert it into the main window */ gtk_container_add (GTK_CONTAINER (window), vbox); /* make sure that everything, window and label, are visible */ gtk_widget_show_all (window); /* start the main loop */ gtk_main (); return 0; }
int main (int argc, char *argv[]) { ClutterActor *stage, *box, *instructions; ClutterLayoutManager *stage_layout, *grid_layout; GError *error = NULL; if (clutter_init_with_args (&argc, &argv, NULL, entries, NULL, &error) != CLUTTER_INIT_SUCCESS) { g_print ("Unable to run grid-layout: %s", error->message); g_error_free (error); return EXIT_FAILURE; } stage = clutter_stage_new (); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); stage_layout = clutter_box_layout_new (); clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (stage_layout), CLUTTER_ORIENTATION_VERTICAL); clutter_actor_set_layout_manager (stage, stage_layout); grid_layout = clutter_grid_layout_new (); if (is_vertical) clutter_grid_layout_set_orientation (CLUTTER_GRID_LAYOUT (grid_layout), CLUTTER_ORIENTATION_VERTICAL); box = clutter_actor_new (); clutter_actor_set_background_color (box, CLUTTER_COLOR_LightGray); clutter_actor_set_x_expand (box, TRUE); clutter_actor_set_y_expand (box, TRUE); clutter_actor_set_layout_manager (box, grid_layout); clutter_actor_add_child (stage, box); clutter_actor_set_x_align (box, CLUTTER_ACTOR_ALIGN_FILL); clutter_actor_set_y_align (box, CLUTTER_ACTOR_ALIGN_FILL); add_actor (box, 0, 0, 1, 1); add_actor (box, 1, 0, 1, 1); add_actor (box, 2, 0, 1, 1); add_actor (box, 0, 1, 1, 1); add_actor (box, 1, 1, 2, 1); add_actor (box, 0, 2, 3, 1); add_actor (box, 0, 3, 2, 2); add_actor (box, 2, 3, 1, 1); add_actor (box, 2, 4, 1, 1); instructions = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS); clutter_actor_set_margin_top (instructions, 4); clutter_actor_set_margin_left (instructions, 4); clutter_actor_set_margin_bottom (instructions, 4); clutter_actor_add_child (stage, instructions); clutter_actor_set_x_align (instructions, CLUTTER_ACTOR_ALIGN_FILL); clutter_actor_set_y_align (instructions, CLUTTER_ACTOR_ALIGN_CENTER); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); g_signal_connect (stage, "key-release-event", G_CALLBACK (key_release_cb), box); clutter_actor_show (stage); clutter_main (); return 0; }
static void add_actor (ClutterActor *box, gint left, gint top, gint width, gint height) { ClutterLayoutManager *layout; ClutterActor *rect, *text; ClutterColor color; clutter_color_from_hls (&color, g_random_double_range (0.0, 360.0), 0.5, 0.5); color.alpha = 255; rect = clutter_actor_new (); clutter_actor_set_layout_manager (rect, clutter_bin_layout_new ()); clutter_actor_set_background_color (rect, &color); clutter_actor_set_reactive (rect, TRUE); if (random_size) clutter_actor_set_size (rect, g_random_int_range (40, 80), g_random_int_range (40, 80)); else clutter_actor_set_size (rect, 60, 60); clutter_actor_set_x_expand (rect, default_expand); clutter_actor_set_y_expand (rect, default_expand); if (!default_expand) { clutter_actor_set_x_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); } if (random_align) { clutter_actor_set_x_align (rect, g_random_int_range (0, 3)); clutter_actor_set_y_align (rect, g_random_int_range (0, 3)); } text = clutter_text_new_with_text ("Sans 8px", NULL); clutter_text_set_line_alignment (CLUTTER_TEXT (text), PANGO_ALIGN_CENTER); clutter_actor_add_child (rect, text); g_signal_connect (rect, "button-release-event", G_CALLBACK (button_release_cb), NULL); g_signal_connect (rect, "notify::x-expand", G_CALLBACK (changed_cb), text); g_signal_connect (rect, "notify::y-expand", G_CALLBACK (changed_cb), text); g_signal_connect (rect, "notify::x-align", G_CALLBACK (changed_cb), text); g_signal_connect (rect, "notify::y-align", G_CALLBACK (changed_cb), text); layout = clutter_actor_get_layout_manager (box); if (use_box) clutter_actor_add_child (box, rect); else clutter_grid_layout_attach (CLUTTER_GRID_LAYOUT (layout), rect, left, top, width, height); changed_cb (rect, NULL, text); }
Animation::Animation(ClutterActor *stage, TCLControl *tcl) { printf("Building animation tools...\n"); //==================== // On screen display: // Build the Actor that will display what's going to the lights: lightDisplay = clutter_actor_new(); // Build the color delegate for the lightDisplay's content/texture: colors = clutter_image_new(); // Error object for GDK/Clutter calls that need them error = NULL; // Load image data from some other data source...: // guchar *data = // GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data); // Load image data from a file: // const char *img_path = "./wut.png"; // GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (img_path, WIDTH, HEIGHT, &error); // Build the color buffer we'll store the actual colors in: pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, WIDTH, HEIGHT); pixels = gdk_pixbuf_get_pixels(pixbuf); // Grab it's pixels... rowstride = gdk_pixbuf_get_rowstride(pixbuf); // figure out the width of the buffer... // And put some RED into the buffer to start off with for (int x = 0; x < WIDTH; x++) { for (int y = 0; y < HEIGHT; y++) { // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built... // and bind it to a pointer to a char... unsigned char *pixel = &pixels[y * rowstride + x * 3]; // And directly update that memory location with a new color // This AUTOMATICALLY updates the color of the pixbuf! // It's just hitting the memory directly! pixel[0] = 255;//red pixel[1] = 0x0;//green pixel[2] = 0x0;//blue } } // Dump the colors from the color buffer into the ClutterContent delegate! if (pixbuf != NULL) { clutter_image_set_data(CLUTTER_IMAGE(colors), gdk_pixbuf_get_pixels (pixbuf), COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), &error); } // Tell the lightDisplay that it's content should be whatever we've dumped in the content delegate: clutter_actor_set_content(lightDisplay, colors); // Define the size of the On Screen Display: clutter_actor_set_x_expand(lightDisplay, TRUE); clutter_actor_set_y_expand(lightDisplay, TRUE); clutter_actor_set_position(lightDisplay, 0, WIDTH*(osd_scale+7)+WIDTH); clutter_actor_set_size(lightDisplay, WIDTH, HEIGHT); clutter_actor_set_scale(lightDisplay, osd_scale, osd_scale+7); clutter_actor_set_rotation_angle(lightDisplay, CLUTTER_Z_AXIS, -90); // Actually add that actor to the stage! clutter_actor_add_child(stage, lightDisplay); // Allow for UI events on this crazy thing! clutter_actor_set_reactive(lightDisplay, TRUE); // Wire up the event listener on this lightDisplay actor. TouchData *touch_data; touch_data = g_slice_new(TouchData); // reserve memory for it... touch_data->lightDisplay = lightDisplay; // Place the button actor itself inside the struct touch_data->tcl = tcl; // TCLControl *tcl is just a POINTER here (unlike in main.cpp) touch_data->animationNumber = ¤tAnimation; // Actually wire up the events and set up the data structs that the events need to operate: g_signal_connect(lightDisplay, "touch-event", G_CALLBACK(handleTouchEvents), touch_data); g_signal_connect(lightDisplay, "button-press-event", G_CALLBACK(handleTouchEvents), touch_data); g_signal_connect(lightDisplay, "motion-event", G_CALLBACK(handleTouchEvents), touch_data); g_signal_connect(lightDisplay, "button-release-event", G_CALLBACK(handleTouchEvents), touch_data); // Set sane default values for the initial touch location input_y = 0; input_x = 0; // End On screen display //============================= // Shader setup and wirings: // Build the Actor that the shader will dump to directly: shaderOutput = clutter_actor_new(); clutter_actor_set_position(shaderOutput, 0, 0); clutter_actor_set_size(shaderOutput, WIDTH-1, HEIGHT); clutter_actor_set_rotation_angle(shaderOutput, CLUTTER_Z_AXIS, -90); clutter_actor_set_rotation_angle(shaderOutput, CLUTTER_Y_AXIS, 180); clutter_actor_add_child(stage, shaderOutput); // Allocate the memory for the shader output buffer: // Figure out how big our buffer needs to be. *4 because four bytes per pixel (r, g, b, a) in shader land int shaderBufferSize = WIDTH * HEIGHT * 4; shaderBuffer = (guint8 *) malloc(shaderBufferSize); // malloc the buffer!! // Double check that we built the buffer correctly. if (shaderBuffer == NULL) { printf("OOPS! malloc error!\n"); } else { // printf("We malloc'd %i bytes for your shaderBuffer. It points at: %p\n", shaderBufferSize, shaderBuffer); // printf(" The Rowstride on the shaderBuffer is %i\n", rowstride); } // init shader TEXTURES! // Populate the noiseImage: // const char *textureFile = "images/text_noise.png"; // audiopixbuf = gdk_pixbuf_new_from_file (textureFile, NULL); // Init the audioImage that will store the FFT output for attaching to the actor error = NULL; audioImage = clutter_image_new (); audiopixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, WIDTH, HEIGHT ); audioPixels = gdk_pixbuf_get_pixels(audiopixbuf); // Grab it's pixels... audioRowstride = gdk_pixbuf_get_rowstride(audiopixbuf); // figure out the width of the buffer... // Populate the audioImage with no data so we have a fresh start: for (int x = 0; x < WIDTH; x++) { for (int y = 0; y < HEIGHT; y++) { // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built... // and bind it to a pointer to a char... unsigned char *pixel = &audioPixels[y * audioRowstride + x * 3]; // And directly update that memory location with a new color // This AUTOMATICALLY updates the color of the pixbuf! // It's just hitting the memory directly! pixel[0] = getrand(0,255);//((int)(samples[x]*max)) & 0xff; // low bits... pixel[1] = getrand(0,255);//((int)(samples[x]*max)) & 0xff00; // high bits. pixel[2] = getrand(0,255); // some random value could be used for noise... } } // Actually load our color onto the actor clutter_image_set_data (CLUTTER_IMAGE (audioImage), gdk_pixbuf_get_pixels (audiopixbuf), COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_width (audiopixbuf), gdk_pixbuf_get_height (audiopixbuf), gdk_pixbuf_get_rowstride (audiopixbuf), &error); // g_object_unref (audiopixbuf); // we want to reuse this... don't dereference that memory yet... clutter_actor_set_content (shaderOutput, audioImage); //clutter_actor_set_content_gravity (shaderOutput, CLUTTER_CONTENT_GRAVITY_TOP_RIGHT); // audioTexture[0] = 0.25; // srand(time(NULL)); // for (i=0; i<noiseTextureSize; i++) { // noiseTexture[i] = getrandf(); // } // Make sure we don't have a current shader so we don't break the update loop: shaderLoaded = false; currentSpeed = 100; // Once we have all that set up, we still need to START THE ACTUAL ANIMATION!! // To do that, we'll need to use the event chain/callback system we have been using so far. // Get ready to hand this display chunk in to the animation event: AnimationData *data; data = g_slice_new(AnimationData); // reserve memory for it... data->tcl = tcl; // tcl is an pointer to the main TCLControl object. data->animationNumber = ¤tAnimation; data->animationObject = this; // The clutter timeline object takes a "duration" in milliseconds... timeline = clutter_timeline_new(1); g_signal_connect(timeline, "new-frame", G_CALLBACK(handleNewFrame), data); // which will just continue repeating: clutter_timeline_set_repeat_count(timeline, -1); // This actually starts the timeline animation! clutter_timeline_start(timeline); // Generate the list of known shaders: buildShaderList(); // Load the first shader so we do not get a black screen: currentShader = 0; // Set the inital shader to load (usually, first in the directory) updateCurrentShader(); }