11 #include "glut_wrap.h"
14 static int WinWidth
= 600, WinHeight
= 200;
15 static GLfloat Xrot
= 0.0, Yrot
= 0.0;
20 static GLubyte Image
[HEIGHT
][WIDTH
];
24 DrawStencilPixels(GLint x
, GLint y
, GLsizei w
, GLsizei h
,
25 const GLubyte
*stencil
)
27 /* This program is run eight times, once for each stencil bit.
28 * The stencil values to draw are found in an 8-bit alpha texture.
29 * We read the texture/stencil value and test if bit 'b' is set.
30 * If the bit is set, result.A will be non-zero. Finally, use
31 * alpha test and stencil test to update the stencil buffer.
33 * The basic algorithm for checking if a bit is set is:
34 * if (is_odd(value / (1 << bit)))
35 * result is one (or non-zero).
38 * The program parameter contains two values:
39 * parm.x = 255 / (1 << bit)
42 static const char *program
=
44 "PARAM parm = program.local[0]; \n"
46 "TEX t, fragment.texcoord[0], texture[0], RECT; \n"
47 "# t = t * 255 / bit \n"
48 "MUL t.x, t.a, parm.x; \n"
51 "SUB t.x, t.x, t.y; \n"
53 "MUL t.x, t.x, parm.y; \n"
54 "# alpha = frac(t) \n"
55 "FRC result.color, t.x; \n"
60 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
61 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB
, 0, GL_ALPHA
, w
, h
, 0,
62 GL_ALPHA
, GL_UNSIGNED_BYTE
, stencil
);
63 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
64 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
66 glGenProgramsARB(1, &prog
);
67 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, prog
);
68 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB
, GL_PROGRAM_FORMAT_ASCII_ARB
,
69 strlen(program
), (const GLubyte
*) program
);
70 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
73 glTranslatef(x
, y
, 0);
75 glEnable(GL_ALPHA_TEST
);
76 glAlphaFunc(GL_GREATER
, 0.0);
78 glEnable(GL_STENCIL_TEST
);
79 glStencilOp(GL_KEEP
, GL_KEEP
, GL_REPLACE
);
81 for (bit
= 0; bit
< 8; bit
++) {
82 GLuint mask
= 1 << bit
;
83 glStencilFunc(GL_ALWAYS
, 255/*mask*/, mask
);
86 glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB
, 0,
87 // 1.0 / bit, 0.5, 0.0, 0.0);
88 255.0 / mask
, 0.5, 0.0, 0.0);
91 glBegin(GL_TRIANGLE_FAN
);
92 glTexCoord2f(0, 0); glVertex2f(0, 0);
93 glTexCoord2f(w
, 0); glVertex2f(w
, 0);
94 glTexCoord2f(w
, h
); glVertex2f(w
, h
);
95 glTexCoord2f(0, h
); glVertex2f(0, h
);
101 glDisable(GL_FRAGMENT_PROGRAM_ARB
);
102 glDisable(GL_ALPHA_TEST
);
103 glDisable(GL_STENCIL_TEST
);
111 GLint x0
= 5, y0
= 5, x1
= 10 + WIDTH
, y1
= 5;
112 GLubyte tmp
[HEIGHT
][WIDTH
];
115 glClearColor(0.2, 0.2, 0.8, 0.0);
116 glClear(GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
119 DrawStencilPixels(x0
, y0
, WIDTH
, HEIGHT
, (GLubyte
*) Image
);
121 glWindowPos2i(x0
, y0
);
122 glDrawPixels(WIDTH
, HEIGHT
, GL_STENCIL_INDEX
,
123 GL_UNSIGNED_BYTE
, (GLubyte
*) Image
);
126 glReadPixels(x0
, y0
, WIDTH
, HEIGHT
, GL_STENCIL_INDEX
, GL_UNSIGNED_BYTE
, tmp
);
129 for (i
= 0; i
< HEIGHT
; i
++) {
130 for (j
= 0; j
< WIDTH
; j
++) {
135 printf("max = %d\n", max
);
137 glWindowPos2i(x1
, y1
);
138 glDrawPixels(WIDTH
, HEIGHT
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, tmp
);
145 Reshape(int width
, int height
)
149 glViewport(0, 0, width
, height
);
150 glMatrixMode(GL_PROJECTION
);
152 glOrtho(0, width
, 0, height
, -1, 1);
153 glMatrixMode(GL_MODELVIEW
);
159 Key(unsigned char key
, int x
, int y
)
165 glutDestroyWindow(Win
);
174 SpecialKey(int key
, int x
, int y
)
176 const GLfloat step
= 3.0;
201 for (i
= 0; i
< HEIGHT
; i
++) {
202 for (j
= 0; j
< WIDTH
; j
++) {
210 main(int argc
, char *argv
[])
212 glutInit(&argc
, argv
);
213 glutInitWindowSize(WinWidth
, WinHeight
);
214 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_STENCIL
);
215 Win
= glutCreateWindow(argv
[0]);
217 glutReshapeFunc(Reshape
);
218 glutKeyboardFunc(Key
);
219 glutSpecialFunc(SpecialKey
);
220 glutDisplayFunc(Draw
);