static void deceleration_new_frame_cb (ClutterTimeline *timeline, gint frame_num, ChamplainKineticScrollView *scroll) { ChamplainKineticScrollViewPrivate *priv = scroll->priv; if (priv->viewport) { gdouble value, lower, upper; ChamplainAdjustment *hadjust, *vadjust; gint i; gboolean stop = TRUE; champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport), &hadjust, &vadjust); for (i = 0; i < clutter_timeline_get_delta (timeline) / 15; i++) { champlain_adjustment_set_value (hadjust, priv->dx + champlain_adjustment_get_value (hadjust)); champlain_adjustment_set_value (vadjust, priv->dy + champlain_adjustment_get_value (vadjust)); priv->dx = (priv->dx / priv->decel_rate); priv->dy = (priv->dy / priv->decel_rate); } /* Check if we've hit the upper or lower bounds and stop the timeline */ champlain_adjustment_get_values (hadjust, &value, &lower, &upper, NULL); if (((priv->dx > 0) && (value < upper)) || ((priv->dx < 0) && (value > lower))) stop = FALSE; if (stop) { champlain_adjustment_get_values (vadjust, &value, &lower, &upper, NULL); if (((priv->dy > 0) && (value < upper)) || ((priv->dy < 0) && (value > lower))) stop = FALSE; } if (stop) { clutter_timeline_stop (timeline); deceleration_completed_cb (timeline, scroll); } } }
// handleNewFrame is the function that is called ever 120 milliseconds via the timeline! // This is where ALL animation updates will happen. void Animation::handleNewFrame(ClutterTimeline *timeline, gint frame_num, gpointer user_data) { // Rebuild the struct from the pointer we handed in: AnimationData *data; data = (AnimationData *) user_data; TCLControl *tcl = data->tcl; // tcl is STILL a pointer to the main TCLControl object Animation *animation = data->animationObject; // Error object for GDK/Clutter calls that need them error = NULL; shaderAnimation(tcl); // Send the updated color buffer to the strands if (tcl->enabled) { tcl->Update(); } // 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); } // clutter_actor_set_content(lightDisplay, colors); // Bind that delegate to the lightDisplay // Update the shader uniforms: // Populate the audioImage with the FFT data: // executeFFT(audioPixels, audioRowstride); // Actually load our FFT Texture colors onto the actor // clutter_image_set_data (CLUTTER_IMAGE (audioImage), // gdk_pixbuf_get_pixels (audiopixbuf), // gdk_pixbuf_get_has_alpha (audiopixbuf) // ? COGL_PIXEL_FORMAT_RGBA_8888 // : COGL_PIXEL_FORMAT_RGB_888, // gdk_pixbuf_get_width (audiopixbuf), // gdk_pixbuf_get_height (audiopixbuf), // gdk_pixbuf_get_rowstride (audiopixbuf), // &error); // clutter_actor_set_content (shaderOutput, audioImage); // Use the timeline delta to determine how much time to add to the clock: int delta = clutter_timeline_get_delta(timeline); if (animation->currentSpeed > 500 || animation->currentSpeed<-500) { animation->currentSpeed = 100; } animationTime += delta/1000.0 * (animation->currentSpeed/100.0); // printf("Current speed: %i, animation time: %f\n", animation->currentSpeed, animationTime); // Update the random noiseImage: // for (unsigned int i=0; i<noiseTextureSize; i++) { // noiseTexture[i] = getrandf(); // } if (animation->shaderLoaded ) { // Only update the shader when a shader is actually SET clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iGlobalTime", G_TYPE_FLOAT, 1, animationTime); clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iMouse", G_TYPE_FLOAT, 2, input_y*1.0, input_x*1.0); } }