dissolve.c revision 32001f49
132001f49Smrg/** 232001f49Smrg * Dissolve between two images using randomized/patterned stencil buffer 332001f49Smrg * and varying stencil ref. 432001f49Smrg * 532001f49Smrg * Brian Paul 632001f49Smrg * 29 Jan 2010 732001f49Smrg */ 832001f49Smrg 932001f49Smrg 1032001f49Smrg#include <stdio.h> 1132001f49Smrg#include <stdlib.h> 1232001f49Smrg#include <string.h> 1332001f49Smrg#include <math.h> 1432001f49Smrg#include "glut_wrap.h" 1532001f49Smrg#include "readtex.h" 1632001f49Smrg 1732001f49Smrg#define FILE1 DEMOS_DATA_DIR "bw.rgb" 1832001f49Smrg#define FILE2 DEMOS_DATA_DIR "arch.rgb" 1932001f49Smrg 2032001f49Smrg 2132001f49Smrgstatic int Win; 2232001f49Smrgstatic int WinWidth = 400, WinHeight = 400; 2332001f49Smrgstatic GLboolean Anim = GL_TRUE; 2432001f49Smrg 2532001f49Smrgstatic int ImgWidth[2], ImgHeight[2]; 2632001f49Smrgstatic GLenum ImgFormat[2]; 2732001f49Smrgstatic GLubyte *Image[2]; 2832001f49Smrgstatic GLfloat ScaleX[2], ScaleY[2]; 2932001f49Smrg 3032001f49Smrgstatic GLubyte StencilRef = 0; 3132001f49Smrg 3232001f49Smrgstatic int Mode = 0; 3332001f49Smrg 3432001f49Smrg 3532001f49Smrgstatic void 3632001f49SmrgIdle(void) 3732001f49Smrg{ 3832001f49Smrg StencilRef = (GLint) (glutGet(GLUT_ELAPSED_TIME) / 10); 3932001f49Smrg glutPostRedisplay(); 4032001f49Smrg} 4132001f49Smrg 4232001f49Smrg 4332001f49Smrgstatic void 4432001f49SmrgFillRandomPixels(GLubyte *b) 4532001f49Smrg{ 4632001f49Smrg int i; 4732001f49Smrg for (i = 0; i < WinWidth * WinHeight; i++) { 4832001f49Smrg b[i] = rand() & 0xff; 4932001f49Smrg } 5032001f49Smrg} 5132001f49Smrg 5232001f49Smrg 5332001f49Smrgstatic void 5432001f49SmrgFillRandomRects(GLubyte *b) 5532001f49Smrg{ 5632001f49Smrg int i; 5732001f49Smrg 5832001f49Smrg memset(b, 0, WinWidth * WinHeight); 5932001f49Smrg 6032001f49Smrg for (i = 0; i < 256; i++) { 6132001f49Smrg int x = rand() % WinWidth; 6232001f49Smrg int y = rand() % WinHeight; 6332001f49Smrg int w = rand() % 60; 6432001f49Smrg int h = rand() % 60; 6532001f49Smrg int ix, iy; 6632001f49Smrg 6732001f49Smrg if (x + w > WinWidth) 6832001f49Smrg w = WinWidth - x; 6932001f49Smrg if (y + h > WinHeight) 7032001f49Smrg h = WinHeight - y; 7132001f49Smrg 7232001f49Smrg for (iy = 0; iy < h; iy++) { 7332001f49Smrg for (ix = 0; ix < w; ix++) { 7432001f49Smrg int p = (y + iy) * WinWidth + x + ix; 7532001f49Smrg b[p] = i; 7632001f49Smrg } 7732001f49Smrg } 7832001f49Smrg } 7932001f49Smrg} 8032001f49Smrg 8132001f49Smrg 8232001f49Smrgstatic void 8332001f49SmrgFillWipe(GLubyte *b) 8432001f49Smrg{ 8532001f49Smrg int iy, ix; 8632001f49Smrg 8732001f49Smrg memset(b, 0, WinWidth * WinHeight); 8832001f49Smrg 8932001f49Smrg for (iy = 0; iy < WinHeight; iy++) { 9032001f49Smrg for (ix = 0; ix < WinWidth; ix++) { 9132001f49Smrg int p = iy * WinWidth + ix; 9232001f49Smrg b[p] = 2 * ix + iy / 2; 9332001f49Smrg } 9432001f49Smrg } 9532001f49Smrg} 9632001f49Smrg 9732001f49Smrg 9832001f49Smrgstatic void 9932001f49SmrgFillMoire(GLubyte *b) 10032001f49Smrg{ 10132001f49Smrg int iy, ix; 10232001f49Smrg 10332001f49Smrg memset(b, 0, WinWidth * WinHeight); 10432001f49Smrg 10532001f49Smrg for (iy = 0; iy < WinHeight; iy++) { 10632001f49Smrg for (ix = 0; ix < WinWidth; ix++) { 10732001f49Smrg int p = iy * WinWidth + ix; 10832001f49Smrg b[p] = (ix / 2) * (ix / 2) - (iy / 2) * (iy / 2); 10932001f49Smrg } 11032001f49Smrg } 11132001f49Smrg} 11232001f49Smrg 11332001f49Smrg 11432001f49Smrgstatic void 11532001f49SmrgFillWaves(GLubyte *b) 11632001f49Smrg{ 11732001f49Smrg int iy, ix; 11832001f49Smrg 11932001f49Smrg memset(b, 0, WinWidth * WinHeight); 12032001f49Smrg 12132001f49Smrg for (iy = 0; iy < WinHeight; iy++) { 12232001f49Smrg for (ix = 0; ix < WinWidth; ix++) { 12332001f49Smrg int p = iy * WinWidth + ix; 12432001f49Smrg float x = 8.0 * 3.1415 * ix / (float) WinWidth; 12532001f49Smrg b[p] = (int) (25.0 * sin(x) ) - iy*2; 12632001f49Smrg } 12732001f49Smrg } 12832001f49Smrg} 12932001f49Smrg 13032001f49Smrg 13132001f49Smrgtypedef void (*FillFunc)(GLubyte *b); 13232001f49Smrg 13332001f49Smrg 13432001f49Smrgstatic FillFunc Funcs[] = { 13532001f49Smrg FillRandomPixels, 13632001f49Smrg FillRandomRects, 13732001f49Smrg FillWipe, 13832001f49Smrg FillMoire, 13932001f49Smrg FillWaves 14032001f49Smrg}; 14132001f49Smrg 14232001f49Smrg#define NUM_MODES (sizeof(Funcs) / sizeof(Funcs[0])) 14332001f49Smrg 14432001f49Smrg 14532001f49Smrg 14632001f49Smrgstatic void 14732001f49SmrgInitStencilBuffer(void) 14832001f49Smrg{ 14932001f49Smrg GLubyte *b = malloc(WinWidth * WinHeight); 15032001f49Smrg 15132001f49Smrg Funcs[Mode](b); 15232001f49Smrg 15332001f49Smrg glStencilFunc(GL_ALWAYS, 0, ~0); 15432001f49Smrg glPixelZoom(1.0, 1.0); 15532001f49Smrg glDrawPixels(WinWidth, WinHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, b); 15632001f49Smrg 15732001f49Smrg free(b); 15832001f49Smrg} 15932001f49Smrg 16032001f49Smrg 16132001f49Smrgstatic void 16232001f49SmrgDraw(void) 16332001f49Smrg{ 16432001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 16532001f49Smrg 16632001f49Smrg glPixelZoom(ScaleX[0], ScaleY[0]); 16732001f49Smrg glStencilFunc(GL_LESS, StencilRef, ~0); 16832001f49Smrg glDrawPixels(ImgWidth[0], ImgHeight[0], ImgFormat[0], GL_UNSIGNED_BYTE, Image[0]); 16932001f49Smrg 17032001f49Smrg glPixelZoom(ScaleX[1], ScaleY[1]); 17132001f49Smrg glStencilFunc(GL_GEQUAL, StencilRef, ~0); 17232001f49Smrg glDrawPixels(ImgWidth[1], ImgHeight[1], ImgFormat[1], GL_UNSIGNED_BYTE, Image[1]); 17332001f49Smrg 17432001f49Smrg glutSwapBuffers(); 17532001f49Smrg} 17632001f49Smrg 17732001f49Smrg 17832001f49Smrgstatic void 17932001f49SmrgReshape(int width, int height) 18032001f49Smrg{ 18132001f49Smrg WinWidth = width; 18232001f49Smrg WinHeight = height; 18332001f49Smrg glViewport(0, 0, width, height); 18432001f49Smrg glMatrixMode(GL_PROJECTION); 18532001f49Smrg glLoadIdentity(); 18632001f49Smrg glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); 18732001f49Smrg glMatrixMode(GL_MODELVIEW); 18832001f49Smrg glLoadIdentity(); 18932001f49Smrg glTranslatef(0.0, 0.0, -15.0); 19032001f49Smrg 19132001f49Smrg InitStencilBuffer(); 19232001f49Smrg 19332001f49Smrg ScaleX[0] = (float) width / ImgWidth[0]; 19432001f49Smrg ScaleY[0] = (float) height / ImgHeight[0]; 19532001f49Smrg 19632001f49Smrg ScaleX[1] = (float) width / ImgWidth[1]; 19732001f49Smrg ScaleY[1] = (float) height / ImgHeight[1]; 19832001f49Smrg} 19932001f49Smrg 20032001f49Smrg 20132001f49Smrgstatic void 20232001f49SmrgKey(unsigned char key, int x, int y) 20332001f49Smrg{ 20432001f49Smrg (void) x; 20532001f49Smrg (void) y; 20632001f49Smrg switch (key) { 20732001f49Smrg case 'a': 20832001f49Smrg case ' ': 20932001f49Smrg Anim = !Anim; 21032001f49Smrg if (Anim) 21132001f49Smrg glutIdleFunc(Idle); 21232001f49Smrg else 21332001f49Smrg glutIdleFunc(NULL); 21432001f49Smrg break; 21532001f49Smrg case 'i': 21632001f49Smrg InitStencilBuffer(); 21732001f49Smrg break; 21832001f49Smrg case '-': 21932001f49Smrg StencilRef--; 22032001f49Smrg break; 22132001f49Smrg case '+': 22232001f49Smrg StencilRef++; 22332001f49Smrg break; 22432001f49Smrg case 'm': 22532001f49Smrg Mode = (Mode + 1) % NUM_MODES; 22632001f49Smrg InitStencilBuffer(); 22732001f49Smrg break; 22832001f49Smrg case 27: 22932001f49Smrg glutDestroyWindow(Win); 23032001f49Smrg exit(0); 23132001f49Smrg break; 23232001f49Smrg } 23332001f49Smrg glutPostRedisplay(); 23432001f49Smrg} 23532001f49Smrg 23632001f49Smrg 23732001f49Smrg 23832001f49Smrgstatic void 23932001f49SmrgInit(void) 24032001f49Smrg{ 24132001f49Smrg Image[0] = LoadRGBImage(FILE1, &ImgWidth[0], &ImgHeight[0], &ImgFormat[0]); 24232001f49Smrg if (!Image[0]) { 24332001f49Smrg printf("Couldn't read %s\n", FILE1); 24432001f49Smrg exit(0); 24532001f49Smrg } 24632001f49Smrg 24732001f49Smrg Image[1] = LoadRGBImage(FILE2, &ImgWidth[1], &ImgHeight[1], &ImgFormat[1]); 24832001f49Smrg if (!Image[1]) { 24932001f49Smrg printf("Couldn't read %s\n", FILE2); 25032001f49Smrg exit(0); 25132001f49Smrg } 25232001f49Smrg 25332001f49Smrg glEnable(GL_STENCIL_TEST); 25432001f49Smrg glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 25532001f49Smrg 25632001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 25732001f49Smrg} 25832001f49Smrg 25932001f49Smrg 26032001f49Smrgint 26132001f49Smrgmain(int argc, char *argv[]) 26232001f49Smrg{ 26332001f49Smrg glutInitWindowSize(WinWidth, WinHeight); 26432001f49Smrg glutInit(&argc, argv); 26532001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); 26632001f49Smrg Win = glutCreateWindow(argv[0]); 26732001f49Smrg glutReshapeFunc(Reshape); 26832001f49Smrg glutKeyboardFunc(Key); 26932001f49Smrg glutDisplayFunc(Draw); 27032001f49Smrg if (Anim) 27132001f49Smrg glutIdleFunc(Idle); 27232001f49Smrg Init(); 27332001f49Smrg 27432001f49Smrg printf("Keys:\n"); 27532001f49Smrg printf(" a/SPACE toggle animation\n"); 27632001f49Smrg printf(" +/- single step\n"); 27732001f49Smrg printf(" i re-init pattern\n"); 27832001f49Smrg printf(" m change pattern/dissolve mode\n"); 27932001f49Smrg printf(" ESC exit\n"); 28032001f49Smrg 28132001f49Smrg glutMainLoop(); 28232001f49Smrg return 0; 28332001f49Smrg} 284