2 * Dissolve between two images using randomized/patterned stencil buffer
3 * and varying stencil ref.
17 #define FILE1 "../images/bw.rgb"
18 #define FILE2 "../images/arch.rgb"
22 static int WinWidth
= 400, WinHeight
= 400;
23 static GLboolean Anim
= GL_TRUE
;
25 static int ImgWidth
[2], ImgHeight
[2];
26 static GLenum ImgFormat
[2];
27 static GLubyte
*Image
[2];
28 static GLfloat ScaleX
[2], ScaleY
[2];
30 static GLubyte StencilRef
= 0;
38 StencilRef
= (GLint
) (glutGet(GLUT_ELAPSED_TIME
) / 10);
44 FillRandomPixels(GLubyte
*b
)
47 for (i
= 0; i
< WinWidth
* WinHeight
; i
++) {
54 FillRandomRects(GLubyte
*b
)
58 memset(b
, 0, WinWidth
* WinHeight
);
60 for (i
= 0; i
< 256; i
++) {
61 int x
= rand() % WinWidth
;
62 int y
= rand() % WinHeight
;
69 if (y
+ h
> WinHeight
)
72 for (iy
= 0; iy
< h
; iy
++) {
73 for (ix
= 0; ix
< w
; ix
++) {
74 int p
= (y
+ iy
) * WinWidth
+ x
+ ix
;
87 memset(b
, 0, WinWidth
* WinHeight
);
89 for (iy
= 0; iy
< WinHeight
; iy
++) {
90 for (ix
= 0; ix
< WinWidth
; ix
++) {
91 int p
= iy
* WinWidth
+ ix
;
92 b
[p
] = 2 * ix
+ iy
/ 2;
103 memset(b
, 0, WinWidth
* WinHeight
);
105 for (iy
= 0; iy
< WinHeight
; iy
++) {
106 for (ix
= 0; ix
< WinWidth
; ix
++) {
107 int p
= iy
* WinWidth
+ ix
;
108 b
[p
] = (ix
/ 2) * (ix
/ 2) - (iy
/ 2) * (iy
/ 2);
115 FillWaves(GLubyte
*b
)
119 memset(b
, 0, WinWidth
* WinHeight
);
121 for (iy
= 0; iy
< WinHeight
; iy
++) {
122 for (ix
= 0; ix
< WinWidth
; ix
++) {
123 int p
= iy
* WinWidth
+ ix
;
124 float x
= 8.0 * 3.1415 * ix
/ (float) WinWidth
;
125 b
[p
] = (int) (25.0 * sin(x
) ) - iy
*2;
131 typedef void (*FillFunc
)(GLubyte
*b
);
134 static FillFunc Funcs
[] = {
142 #define NUM_MODES (sizeof(Funcs) / sizeof(Funcs[0]))
147 InitStencilBuffer(void)
149 GLubyte
*b
= malloc(WinWidth
* WinHeight
);
153 glStencilFunc(GL_ALWAYS
, 0, ~0);
154 glPixelZoom(1.0, 1.0);
155 glDrawPixels(WinWidth
, WinHeight
, GL_STENCIL_INDEX
, GL_UNSIGNED_BYTE
, b
);
164 glClear(GL_COLOR_BUFFER_BIT
);
166 glPixelZoom(ScaleX
[0], ScaleY
[0]);
167 glStencilFunc(GL_LESS
, StencilRef
, ~0);
168 glDrawPixels(ImgWidth
[0], ImgHeight
[0], ImgFormat
[0], GL_UNSIGNED_BYTE
, Image
[0]);
170 glPixelZoom(ScaleX
[1], ScaleY
[1]);
171 glStencilFunc(GL_GEQUAL
, StencilRef
, ~0);
172 glDrawPixels(ImgWidth
[1], ImgHeight
[1], ImgFormat
[1], GL_UNSIGNED_BYTE
, Image
[1]);
179 Reshape(int width
, int height
)
183 glViewport(0, 0, width
, height
);
184 glMatrixMode(GL_PROJECTION
);
186 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
187 glMatrixMode(GL_MODELVIEW
);
189 glTranslatef(0.0, 0.0, -15.0);
193 ScaleX
[0] = (float) width
/ ImgWidth
[0];
194 ScaleY
[0] = (float) height
/ ImgHeight
[0];
196 ScaleX
[1] = (float) width
/ ImgWidth
[1];
197 ScaleY
[1] = (float) height
/ ImgHeight
[1];
202 Key(unsigned char key
, int x
, int y
)
225 Mode
= (Mode
+ 1) % NUM_MODES
;
229 glutDestroyWindow(Win
);
241 Image
[0] = LoadRGBImage(FILE1
, &ImgWidth
[0], &ImgHeight
[0], &ImgFormat
[0]);
243 printf("Couldn't read %s\n", FILE1
);
247 Image
[1] = LoadRGBImage(FILE2
, &ImgWidth
[1], &ImgHeight
[1], &ImgFormat
[1]);
249 printf("Couldn't read %s\n", FILE2
);
253 glEnable(GL_STENCIL_TEST
);
254 glStencilOp(GL_KEEP
, GL_KEEP
, GL_KEEP
);
256 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
261 main(int argc
, char *argv
[])
263 glutInitWindowSize(WinWidth
, WinHeight
);
264 glutInit(&argc
, argv
);
265 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
| GLUT_STENCIL
);
266 Win
= glutCreateWindow(argv
[0]);
267 glutReshapeFunc(Reshape
);
268 glutKeyboardFunc(Key
);
269 glutDisplayFunc(Draw
);
275 printf(" a/SPACE toggle animation\n");
276 printf(" +/- single step\n");
277 printf(" i re-init pattern\n");
278 printf(" m change pattern/dissolve mode\n");
279 printf(" ESC exit\n");