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;
}
static void
clutter_shader_effect_set_actor (ClutterActorMeta *meta,
                                 ClutterActor     *actor)
{
  ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (meta);
  ClutterShaderEffectPrivate *priv = self->priv;
  ClutterActorMetaClass *parent;

  if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
    {
      /* if we don't have support for GLSL shaders then we
       * forcibly disable the ActorMeta
       */
      g_warning ("Unable to use the ShaderEffect: the graphics hardware "
                 "or the current GL driver does not implement support "
                 "for the GLSL shading language.");
      clutter_actor_meta_set_enabled (meta, FALSE);
      return;
    }

  parent = CLUTTER_ACTOR_META_CLASS (clutter_shader_effect_parent_class);
  parent->set_actor (meta, actor);

  /* we keep a back pointer here */
  priv->actor = clutter_actor_meta_get_actor (meta);
  if (priv->actor == NULL)
    return;

  CLUTTER_NOTE (SHADER, "Preparing shader effect of type '%s'",
                G_OBJECT_TYPE_NAME (meta));
}
Exemple #3
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);
}
static void
clutter_shader_effect_finalize (GObject *gobject)
{
  ClutterShaderEffect *effect = CLUTTER_SHADER_EFFECT (gobject);

  clutter_shader_effect_clear (effect, TRUE);

  G_OBJECT_CLASS (clutter_shader_effect_parent_class)->finalize (gobject);
}
static void
clutter_shader_effect_set_property (GObject      *gobject,
                                    guint         prop_id,
                                    const GValue *value,
                                    GParamSpec   *pspec)
{
  ClutterShaderEffectPrivate *priv = CLUTTER_SHADER_EFFECT (gobject)->priv;

  switch (prop_id)
    {
    case PROP_SHADER_TYPE:
      priv->shader_type = g_value_get_enum (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
      break;
    }
}
static void
clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ClutterShaderEffectPrivate *priv = CLUTTER_SHADER_EFFECT (effect)->priv;
  ClutterOffscreenEffectClass *parent;
  CoglHandle material;

  /* we haven't been prepared or we don't have support for
   * GLSL shaders in Clutter
   */
  if (priv->program == COGL_INVALID_HANDLE ||
      priv->shader == COGL_INVALID_HANDLE)
    goto out;

  if (!priv->source_set)
    goto out;

  if (!priv->is_compiled)
    {
      CLUTTER_NOTE (SHADER, "Compiling shader effect");

      cogl_shader_compile (priv->shader);
      if (!cogl_shader_is_compiled (priv->shader))
        {
          gchar *log_buf = cogl_shader_get_info_log (priv->shader);

          g_warning ("Unable to compile the GLSL shader: %s", log_buf);
          g_free (log_buf);

          cogl_handle_unref (priv->shader);
          priv->shader = COGL_INVALID_HANDLE;

          cogl_handle_unref (priv->program);
          priv->shader = COGL_INVALID_HANDLE;

          goto out;
        }

      cogl_program_attach_shader (priv->program, priv->shader);
      cogl_handle_unref (priv->shader);

      cogl_program_link (priv->program);

      priv->is_compiled = TRUE;
    }

  CLUTTER_NOTE (SHADER, "Applying the shader effect of type '%s'",
                G_OBJECT_TYPE_NAME (effect));

  clutter_shader_effect_update_uniforms (CLUTTER_SHADER_EFFECT (effect));

  /* associate the program to the offscreen target material */
  material = clutter_offscreen_effect_get_target (effect);
  cogl_material_set_user_program (material, priv->program);

out:
  /* paint the offscreen buffer */
  parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class);
  parent->paint_target (effect);

}
// 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);
    }

}