/*
 * Spinning cube
 *
 * This is a demonstration of animation and using OpenGL gropnodes.
 * Note that this ONLY works with the sdlgl driver, and this theme
 * also requires the PNM, JPEG, and PNG image loaders.
 *
 * It draws on the background, so you can run it without any apps to
 * see the effect. There should be a water background with a scrolling
 * interlace effect on it, then a spinning cube in the middle with
 * the "pG" logo on each face.
 *
 */

/* Texture properties */
prop tInterlace, tWater, tPanel;

object default name = "Spinning Cube Demo (OpenGL)";

object background {

  /* Load textures */
  tInterlace = LoadBitmap("data/fgl_interlace.pgm");
  tWater = LoadBitmap("data/fgl_water.jpeg");
  tPanel = LoadBitmap("data/fgl_panel.png");

  /* Fillstyle */
  bgfill = fillstyle {
    var s, ts, cube_z, t, u;
    
    t = ticks;  /* Get the current time for the animations */
    u = 1<<16;  /* Unit for specifying normals */
    
    /*** Background */

    /* Water background */
    Bitmap(x,y,w,h,tWater);

    /* Use s as a temporary variable to compute the offset of the interlacing.
     * Scale it to slow it down, then keep it under 8 (height of our texture)
     * to avoid the whole texture disappearing later when things overflow.
     */
    s = t>>5;
    s = s&7;
    SetLgop(PG_LGOP_MULTIPLY);
    Bitmap(x,y-s,w,h+s+s,tInterlace);
    
    /*** OpenGL Setup */

    s  = (w/4)<<16;    /* Size of the cube */
    ts = 1<<16;        /* Size in texture coordinates */
    cube_z = s;        /* Height it floats at */
        
    GL.pushmatrix();
    GL.enable(GL_DEPTH_TEST);
    GL.depthfunc(GL_LESS);
    GL.bindtexture(tPanel);
    GL.enable(GL_TEXTURE_2D);
    GL.disable(GL_BLEND);
    GL.enable(GL_LIGHT1);
    GL.enable(GL_LIGHTING);
    GL.lightfv(GL_LIGHT1, GL_AMBIENT,1,0, 0x0A000,0x0A000,0x0A000);
    GL.lightfv(GL_LIGHT1, GL_DIFFUSE,1,0, 0x10000,0x10000,0x12000);

    /*** Transformations */

    GL.translatef((x<<16)+(w<<15),(y<<16)+(h<<15),cube_z);   /* Float above the divnode */

    /* Set up the light relative to the cube's center.
     * Hover it in front of the cube for nice shading effects.
     */
    GL.lightfv(GL_LIGHT1, GL_POSITION,1,0, 0,0,w<<15);

    GL.rotatef(45,0,0,0, 1<<16,0,0);            /* Small vertical tilt */
    GL.rotatef(t>>4,t<<12,0,0, 0,1<<16,0);      /* Spin */
    GL.translatef(0-(s>>1),0-(s>>1),0-(s>>1));  /* Center on the origin */

    /*** Cube */
    
    GL.begin(GL_QUADS);
    
    /* Right */
    GL.normal3f(u,0,0);
    GL.texcoord2f(0,0);     GL.vertex3f(s,0,0);
    GL.texcoord2f(ts,0);    GL.vertex3f(s,s,0);
    GL.texcoord2f(ts,ts);   GL.vertex3f(s,s,s);
    GL.texcoord2f(0,ts);    GL.vertex3f(s,0,s);
    
    /* Left */
    GL.normal3f(-u,0,0);
    GL.texcoord2f(0,0);     GL.vertex3f(0,0,0);
    GL.texcoord2f(ts,0);    GL.vertex3f(0,s,0);
    GL.texcoord2f(ts,ts);   GL.vertex3f(0,s,s);
    GL.texcoord2f(0,ts);    GL.vertex3f(0,0,s);
    
    /* Bottom */
    GL.normal3f(0,u,0);
    GL.texcoord2f(0,0);     GL.vertex3f(0,s,0);
    GL.texcoord2f(ts,0);    GL.vertex3f(s,s,0);
    GL.texcoord2f(ts,ts);   GL.vertex3f(s,s,s);
    GL.texcoord2f(0,ts);    GL.vertex3f(0,s,s);
    
    /* Top */
    GL.normal3f(0,-u,0);
    GL.texcoord2f(0,0);     GL.vertex3f(0,0,0);
    GL.texcoord2f(ts,0);    GL.vertex3f(s,0,0);
    GL.texcoord2f(ts,ts);   GL.vertex3f(s,0,s);
    GL.texcoord2f(0,ts);    GL.vertex3f(0,0,s);
    
    /* Front */
    GL.normal3f(0,0,-u);
    GL.texcoord2f(0,0);     GL.vertex3f(0,0,0);
    GL.texcoord2f(ts,0);    GL.vertex3f(s,0,0);
    GL.texcoord2f(ts,ts);   GL.vertex3f(s,s,0);
    GL.texcoord2f(0,ts);    GL.vertex3f(0,s,0);
    
    /* Back */
    GL.normal3f(0,0,u);
    GL.texcoord2f(0,0);     GL.vertex3f(0,0,s);
    GL.texcoord2f(ts,0);    GL.vertex3f(s,0,s);
    GL.texcoord2f(ts,ts);   GL.vertex3f(s,s,s);
    GL.texcoord2f(0,ts);    GL.vertex3f(0,s,s);
    
    GL.end();

    /*** Cleanup */
    
    GL.disable(GL_TEXTURE_2D);
    GL.disable(GL_DEPTH_TEST);
    GL.disable(GL_LIGHTING);
    GL.popmatrix();
  };
}

/* The End */
