diff options
Diffstat (limited to 'progs/demos/dissolve.c')
-rw-r--r-- | progs/demos/dissolve.c | 137 |
1 files changed, 131 insertions, 6 deletions
diff --git a/progs/demos/dissolve.c b/progs/demos/dissolve.c index 0b8df1bb669..8ab5242d91c 100644 --- a/progs/demos/dissolve.c +++ b/progs/demos/dissolve.c @@ -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; } |