demos: add missing binaries to .gitignore
[mesa-demos.git] / src / tests / drawstencil.c
blob0c369ed83ec9b5f9dc6a361629bc74555e3d387d
1 /**
2 * Draw stencil region
3 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <math.h>
10 #include <GL/glew.h>
11 #include "glut_wrap.h"
13 static int Win;
14 static int WinWidth = 600, WinHeight = 200;
15 static GLfloat Xrot = 0.0, Yrot = 0.0;
17 #define WIDTH 256
18 #define HEIGHT 150
20 static GLubyte Image[HEIGHT][WIDTH];
23 static void
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).
36 * else
37 * result is zero.
38 * The program parameter contains two values:
39 * parm.x = 255 / (1 << bit)
40 * parm.y = 0.5
42 static const char *program =
43 "!!ARBfp1.0\n"
44 "PARAM parm = program.local[0]; \n"
45 "TEMP t; \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"
49 "# t = (int) t \n"
50 "FRC t.y, t.x; \n"
51 "SUB t.x, t.x, t.y; \n"
52 "# t = 5 * 0.5 \n"
53 "MUL t.x, t.x, parm.y; \n"
54 "# alpha = frac(t) \n"
55 "FRC result.color, t.x; \n"
56 "END \n";
57 GLuint prog;
58 GLint bit;
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);
72 glPushMatrix();
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);
84 glStencilMask(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);
96 glEnd();
99 glPopMatrix();
101 glDisable(GL_FRAGMENT_PROGRAM_ARB);
102 glDisable(GL_ALPHA_TEST);
103 glDisable(GL_STENCIL_TEST);
108 static void
109 Draw(void)
111 GLint x0 = 5, y0= 5, x1 = 10 + WIDTH, y1 = 5;
112 GLubyte tmp[HEIGHT][WIDTH];
113 GLint max, i, j;
115 glClearColor(0.2, 0.2, 0.8, 0.0);
116 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
118 #if 0
119 DrawStencilPixels(x0, y0, WIDTH, HEIGHT, (GLubyte*) Image);
120 #else
121 glWindowPos2i(x0, y0);
122 glDrawPixels(WIDTH, HEIGHT, GL_STENCIL_INDEX,
123 GL_UNSIGNED_BYTE, (GLubyte*) Image);
124 #endif
126 glReadPixels(x0, y0, WIDTH, HEIGHT, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, tmp);
128 max = 0;
129 for (i = 0; i < HEIGHT; i++) {
130 for (j = 0; j < WIDTH; j++) {
131 if (tmp[i][j] > max)
132 max = tmp[i][j];
135 printf("max = %d\n", max);
137 glWindowPos2i(x1, y1);
138 glDrawPixels(WIDTH, HEIGHT, GL_LUMINANCE, GL_UNSIGNED_BYTE, tmp);
140 glutSwapBuffers();
144 static void
145 Reshape(int width, int height)
147 WinWidth = width;
148 WinHeight = height;
149 glViewport(0, 0, width, height);
150 glMatrixMode(GL_PROJECTION);
151 glLoadIdentity();
152 glOrtho(0, width, 0, height, -1, 1);
153 glMatrixMode(GL_MODELVIEW);
154 glLoadIdentity();
158 static void
159 Key(unsigned char key, int x, int y)
161 (void) x;
162 (void) y;
163 switch (key) {
164 case 27:
165 glutDestroyWindow(Win);
166 exit(0);
167 break;
169 glutPostRedisplay();
173 static void
174 SpecialKey(int key, int x, int y)
176 const GLfloat step = 3.0;
177 (void) x;
178 (void) y;
179 switch (key) {
180 case GLUT_KEY_UP:
181 Xrot -= step;
182 break;
183 case GLUT_KEY_DOWN:
184 Xrot += step;
185 break;
186 case GLUT_KEY_LEFT:
187 Yrot -= step;
188 break;
189 case GLUT_KEY_RIGHT:
190 Yrot += step;
191 break;
193 glutPostRedisplay();
197 static void
198 Init(void)
200 int i, j;
201 for (i = 0; i < HEIGHT; i++) {
202 for (j = 0; j < WIDTH; j++) {
203 Image[i][j] = 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]);
216 glewInit();
217 glutReshapeFunc(Reshape);
218 glutKeyboardFunc(Key);
219 glutSpecialFunc(SpecialKey);
220 glutDisplayFunc(Draw);
221 Init();
222 glutMainLoop();
223 return 0;