progs/demos: add other modes/patterns to dissolve demo
authorBrian Paul <brianp@vmware.com>
Fri, 19 Mar 2010 17:34:43 +0000 (11:34 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 24 Mar 2010 22:29:17 +0000 (16:29 -0600)
progs/demos/dissolve.c

index 0b8df1bb66916edbd4c73d7c9598178cac579c4c..8ab5242d91ce6488d874e6af597c6ae23b20de34 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Dissolve between two images using randomized stencil buffer
+ * Dissolve between two images using randomized/patterned stencil buffer
  * and varying stencil ref.
  *
  * Brian Paul
@@ -9,6 +9,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <math.h>
 #include <GL/glut.h>
 #include "readtex.h"
@@ -28,6 +29,8 @@ static GLfloat ScaleX[2], ScaleY[2];
 
 static GLubyte StencilRef = 0;
 
+static int Mode = 0;
+
 
 static void
 Idle(void)
@@ -38,13 +41,114 @@ Idle(void)
 
 
 static void
-RandomizeStencilBuffer(void)
+FillRandomPixels(GLubyte *b)
 {
-   GLubyte *b = malloc(WinWidth * WinHeight);
    int i;
    for (i = 0; i < WinWidth * WinHeight; i++) {
       b[i] = rand() & 0xff;
    }
+}
+
+
+static void
+FillRandomRects(GLubyte *b)
+{
+   int i;
+
+   memset(b, 0, WinWidth * WinHeight);
+
+   for (i = 0; i < 256; i++) {
+      int x = rand() % WinWidth;
+      int y = rand() % WinHeight;
+      int w = rand() % 60;
+      int h = rand() % 60;
+      int ix, iy;
+
+      if (x + w > WinWidth)
+         w = WinWidth - x;
+      if (y + h > WinHeight)
+         h = WinHeight - y;
+
+      for (iy = 0; iy < h; iy++) {
+         for (ix = 0; ix < w; ix++) {
+            int p = (y + iy) * WinWidth + x + ix;
+            b[p] = i;
+         }
+      }
+   }
+}
+
+
+static void
+FillWipe(GLubyte *b)
+{
+   int iy, ix;
+
+   memset(b, 0, WinWidth * WinHeight);
+
+   for (iy = 0; iy < WinHeight; iy++) {
+      for (ix = 0; ix < WinWidth; ix++) {
+         int p = iy * WinWidth + ix;
+         b[p] = 2 * ix + iy / 2;
+      }
+   }
+}
+
+
+static void
+FillMoire(GLubyte *b)
+{
+   int iy, ix;
+
+   memset(b, 0, WinWidth * WinHeight);
+
+   for (iy = 0; iy < WinHeight; iy++) {
+      for (ix = 0; ix < WinWidth; ix++) {
+         int p = iy * WinWidth + ix;
+         b[p] = (ix / 2) * (ix / 2) - (iy / 2) * (iy / 2);
+      }
+   }
+}
+
+
+static void
+FillWaves(GLubyte *b)
+{
+   int iy, ix;
+
+   memset(b, 0, WinWidth * WinHeight);
+
+   for (iy = 0; iy < WinHeight; iy++) {
+      for (ix = 0; ix < WinWidth; ix++) {
+         int p = iy * WinWidth + ix;
+         float x = 8.0 * 3.1415 * ix / (float) WinWidth;
+         b[p] = (int) (25.0 * sin(x) ) - iy*2;
+      }
+   }
+}
+
+
+typedef void (*FillFunc)(GLubyte *b);
+
+
+static FillFunc Funcs[] = {
+   FillRandomPixels,
+   FillRandomRects,
+   FillWipe,
+   FillMoire,
+   FillWaves
+};
+
+#define NUM_MODES (sizeof(Funcs) / sizeof(Funcs[0]))
+
+
+
+static void
+InitStencilBuffer(void)
+{
+   GLubyte *b = malloc(WinWidth * WinHeight);
+
+   Funcs[Mode](b);
 
    glStencilFunc(GL_ALWAYS, 0, ~0);
    glPixelZoom(1.0, 1.0);
@@ -54,7 +158,6 @@ RandomizeStencilBuffer(void)
 }
 
 
-
 static void
 Draw(void)
 {
@@ -85,7 +188,7 @@ Reshape(int width, int height)
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -15.0);
 
-   RandomizeStencilBuffer();
+   InitStencilBuffer();
 
    ScaleX[0] = (float) width / ImgWidth[0];
    ScaleY[0] = (float) height / ImgHeight[0];
@@ -102,12 +205,26 @@ Key(unsigned char key, int x, int y)
    (void) y;
    switch (key) {
    case 'a':
+   case ' ':
       Anim = !Anim;
       if (Anim)
          glutIdleFunc(Idle);
       else
          glutIdleFunc(NULL);
       break;
+   case 'i':
+      InitStencilBuffer();
+      break;
+   case '-':
+      StencilRef--;
+      break;
+   case '+':
+      StencilRef++;
+      break;
+   case 'm':
+      Mode = (Mode + 1) % NUM_MODES;
+      InitStencilBuffer();
+      break;
    case 27:
       glutDestroyWindow(Win);
       exit(0);
@@ -143,8 +260,8 @@ Init(void)
 int
 main(int argc, char *argv[])
 {
-   glutInit(&argc, argv);
    glutInitWindowSize(WinWidth, WinHeight);
+   glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
    Win = glutCreateWindow(argv[0]);
    glutReshapeFunc(Reshape);
@@ -153,6 +270,14 @@ main(int argc, char *argv[])
    if (Anim)
       glutIdleFunc(Idle);
    Init();
+
+   printf("Keys:\n");
+   printf("  a/SPACE  toggle animation\n");
+   printf("  +/-      single step\n");
+   printf("  i        re-init pattern\n");
+   printf("  m        change pattern/dissolve mode\n");
+   printf("  ESC      exit\n");
+
    glutMainLoop();
    return 0;
 }