Example #1
0
static void
shader_paint (ClutterEffect           *effect,
              ClutterEffectPaintFlags  flags)
{
  ClutterShaderEffect *shader = CLUTTER_SHADER_EFFECT (effect);
  float tex_width;
  ClutterActor *actor =
    clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));

  if (g_test_verbose ())
    g_debug ("shader_paint");

  clutter_shader_effect_set_shader_source (shader,
    "uniform sampler2D tex;\n"
    "uniform float step;\n"
    "void main (void)\n"
    "{\n"
    "  gl_FragColor = texture2D(tex, vec2 (gl_TexCoord[0].s + step,\n"
    "                                      gl_TexCoord[0].t));\n"
    "}\n");

  tex_width = clutter_actor_get_width (actor);

  clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0);
  clutter_shader_effect_set_uniform (shader, "step", G_TYPE_FLOAT, 1,
                                     SHIFT_STEP / tex_width);

  CLUTTER_EFFECT_CLASS (shift_effect_parent_class)->paint (effect, flags);
}
void Animation::loadShader(const char *fragment_path) {

    std::string fragShaderStr = readFile(fragment_path);
    const gchar *fragShaderSrc = fragShaderStr.c_str();

    // Pop off the old shader:
    unloadShader();

    printf("Loading shader: '%s' \n", fragment_path);

    // Setup the GLSL Fragment shaders that we'll use to generate colors
    // Build a GLSL Fragment shader to affect the color output (to the screen at least for now)
    shaderEffect = clutter_shader_effect_new(CLUTTER_FRAGMENT_SHADER);
    clutter_shader_effect_set_shader_source(CLUTTER_SHADER_EFFECT(shaderEffect), fragShaderSrc);

    // Start fuckups:
//    ClutterEffect *effect = clutter_blur_effect_new (); // works
//    ClutterEffect *effect = clutter_sensatron_effect_new ();
//    clutter_sensatron_effect_set_shader_source(CLUTTER_SENSATRON_EFFECT(effect), fragShaderSrc);
    // Now, let's try attaching a texture to this bitch!!
//    CoglTexture *texture = cogl_texture_new_from_file(textureFile,
//                                                      COGL_TEXTURE_NONE,
//                                                      COGL_PIXEL_FORMAT_ANY,
//                                                      &error);
    // Try attaching the texture to the effect (on the 1th layer?):
//    cogl_pipeline_set_layer_texture (priv->pipeline, 1, texture);
//    CoglPipeline *target;
//    target = COGL_PIPELINE (clutter_offscreen_effect_get_target ((ClutterOffscreenEffect)shaderEffect));
    // End fuckups


    // Bind uniforms to the shader so we can hand variables into them
    animationTime = 0.0;
    currentSpeed = 100;

    clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iGlobalTime", G_TYPE_FLOAT, 1, animationTime);
    clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iResolution", G_TYPE_FLOAT, 2, HEIGHT*osd_scale, WIDTH*osd_scale);
    clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iMouse", G_TYPE_FLOAT, 2, input_x*osd_scale, input_y*osd_scale);
//    clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iChannel0", CLUTTER_TYPE_SHADER_FLOAT, 1, audioTexture);
//    clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iChannel1", CLUTTER_TYPE_SHADER_FLOAT, 1, noiseTexture);


    // Set the effect live on the on screen display actor...
    clutter_actor_add_effect(shaderOutput, shaderEffect);

//    clutter_actor_add_effect(shaderOutput, effect);
    shaderLoaded = true;
}
// 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);
    }

}