
/* Compile with:
 * $ gcc -o material material.c $(pkg-config --libs --cflags cogl-1.0) -DCOGL_ENABLE_EXPERIMENTAL_2_0_API
 */

#include <cogl/cogl.h>
#include <glib.h>
#include <stdio.h>
#include <math.h>

static CoglColor black = { 0, 0, 0, 0 };

static const float tex_coords[] = {
    0.0, 0.0, 1.0, 1.0,
    0.0, 0.0, 1.0, 1.0,
};

static CoglHandle
make_multi_texture (const gchar *file0,
                    const gchar *file1)
{
    CoglHandle tex0;
    CoglHandle tex1;
    CoglHandle mat;

    tex0 = cogl_texture_new_from_file (file0,
                                       COGL_TEXTURE_NO_SLICING,
                                       COGL_PIXEL_FORMAT_ANY,
                                       NULL);

    tex1 = cogl_texture_new_from_file (file1,
                                       COGL_TEXTURE_NO_SLICING,
                                       COGL_PIXEL_FORMAT_ANY,
                                       NULL);

    mat = cogl_material_new ();

    cogl_material_set_layer_combine (mat, 0,
                                     "RGBA = REPLACE (TEXTURE)",
                                     NULL);

    cogl_material_set_layer_combine (mat, 1,
                                     "RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A])",
                                     NULL);

    cogl_material_set_layer_combine (mat, 2,
                                     "RGBA = MODULATE (PREVIOUS, PRIMARY)",
                                     NULL);

    cogl_material_set_layer (mat, 0, tex0);
    cogl_material_set_layer (mat, 1, tex1);

    return mat;
}

static void
draw_material (CoglHandle mat,
               gfloat     y1,
               gfloat     y2,
               float      alpha)
{
    CoglColor color;
    cogl_color_init_from_4f (&color, 0., 0., 0., alpha);
    cogl_material_set_layer_combine_constant (mat, 1, &color);

    cogl_set_source (mat);
    cogl_rectangle_with_multitexture_coords (-1, y1, 0, y2,
                                             tex_coords, 8);
}

int
main (int argc, char **argv)
{
    CoglContext *ctx;
    CoglOnscreen *onscreen;
    CoglFramebuffer *fb;
    CoglHandle mat1, mat2;
    GError *error = NULL;
    int time;
    float alpha;

    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);
    /* Eventually there will be an implicit allocate on first use so this
     * will become optional... */
    fb = COGL_FRAMEBUFFER (onscreen);
    if (!cogl_framebuffer_allocate (fb, &error)) {
        fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
        return 1;
    }

    cogl_onscreen_show (onscreen);

    mat1 = make_multi_texture ("Craig.jpg", "crate.jpg");
    mat2 = make_multi_texture ("crate.jpg", "Craig.jpg");

    cogl_push_framebuffer (fb);
    time = 0;
    for (;;) {
        cogl_clear (&black, COGL_BUFFER_BIT_COLOR);

        alpha = sin (time / 10.0) * 0.5 + 0.5;

        draw_material (mat1, 1, 0, alpha);
        draw_material (mat2, 0, -1, alpha);
        cogl_framebuffer_swap_buffers (fb);
        time ++;
    }

    return 0;
}
