progs/tests: also test stencil INCR_WRAP mode if supported
[mesa.git] / progs / tests / zcomp.c
1 /**
2 * Test Z compositing with glDrawPixels(GL_DEPTH_COMPONENT) and stencil test.
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <math.h>
8 #include <GL/glew.h>
9 #include <GL/glut.h>
10
11
12 static int Win;
13 static GLfloat Xrot = 0, Yrot = 0, Zpos = 6;
14 static GLboolean Anim = GL_FALSE;
15
16 static int Width = 400, Height = 200;
17 static GLfloat *Zimg;
18 static GLubyte *Cimg;
19 static GLboolean showZ = 0;
20
21
22 static void
23 Idle(void)
24 {
25 Xrot += 3.0;
26 Yrot += 4.0;
27 glutPostRedisplay();
28 }
29
30
31 /**
32 * Draw first object, save color+Z images
33 */
34 static void
35 DrawFirst(void)
36 {
37 static const GLfloat red[4] = { 1.0, 0.0, 0.0, 0.0 };
38
39 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
40
41 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
42
43 glPushMatrix();
44 glTranslatef(-1, 0, 0);
45 glRotatef(45 + Xrot, 1, 0, 0);
46
47 glutSolidTorus(0.75, 2.0, 10, 20);
48
49 glPopMatrix();
50
51 glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, Zimg);
52 glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Cimg);
53 }
54
55
56 /**
57 * Draw second object.
58 */
59 static void
60 DrawSecond(void)
61 {
62 static const GLfloat blue[4] = { 0.0, 0.0, 1.0, 0.0 };
63
64 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
65
66 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
67
68 glPushMatrix();
69 glTranslatef(+1, 0, 0);
70 glRotatef(-45 + Xrot, 1, 0, 0);
71
72 glutSolidTorus(0.75, 2.0, 10, 20);
73
74 glPopMatrix();
75 }
76
77
78 /**
79 * Composite first/saved image over second rendering.
80 */
81 static void
82 Composite(void)
83 {
84 glWindowPos2i(0, 0);
85
86 /* Draw Z values, set stencil where Z test passes */
87 glEnable(GL_STENCIL_TEST);
88 glStencilFunc(GL_ALWAYS, 1, ~0);
89 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
90 glColorMask(0,0,0,0);
91 glDrawPixels(Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, Zimg);
92 glColorMask(1,1,1,1);
93
94 /* Draw color where stencil==1 */
95 glStencilFunc(GL_EQUAL, 1, ~0);
96 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
97 glDisable(GL_DEPTH_TEST);
98 glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Cimg);
99 glEnable(GL_DEPTH_TEST);
100
101 glDisable(GL_STENCIL_TEST);
102 }
103
104
105 static void
106 Draw(void)
107 {
108 DrawFirst();
109 DrawSecond();
110 Composite();
111 glutSwapBuffers();
112 }
113
114
115 static void
116 Reshape(int width, int height)
117 {
118 GLfloat ar = (float) width / height;
119 glViewport(0, 0, width, height);
120 glMatrixMode(GL_PROJECTION);
121 glLoadIdentity();
122 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 30.0);
123 glMatrixMode(GL_MODELVIEW);
124 glLoadIdentity();
125 glTranslatef(0.0, 0.0, -15.0);
126
127 Width = width;
128 Height = height;
129
130 if (Zimg)
131 free(Zimg);
132 if (Cimg)
133 free(Cimg);
134 Zimg = (float *) malloc(width * height * 4);
135 Cimg = (GLubyte *) malloc(width * height * 4);
136 }
137
138
139 static void
140 Key(unsigned char key, int x, int y)
141 {
142 const GLfloat step = 1.0;
143 (void) x;
144 (void) y;
145 switch (key) {
146 case 'a':
147 Anim = !Anim;
148 if (Anim)
149 glutIdleFunc(Idle);
150 else
151 glutIdleFunc(NULL);
152 break;
153 case 'd':
154 showZ = !showZ;
155 break;
156 case 'z':
157 Zpos -= step;
158 break;
159 case 'Z':
160 Zpos += step;
161 break;
162 case 27:
163 glutDestroyWindow(Win);
164 exit(0);
165 break;
166 }
167 glutPostRedisplay();
168 }
169
170
171 static void
172 SpecialKey(int key, int x, int y)
173 {
174 const GLfloat step = 3.0;
175 (void) x;
176 (void) y;
177 switch (key) {
178 case GLUT_KEY_UP:
179 Xrot -= step;
180 break;
181 case GLUT_KEY_DOWN:
182 Xrot += step;
183 break;
184 case GLUT_KEY_LEFT:
185 Yrot -= step;
186 break;
187 case GLUT_KEY_RIGHT:
188 Yrot += step;
189 break;
190 }
191 glutPostRedisplay();
192 }
193
194
195 static void
196 Init(void)
197 {
198 /* setup lighting, etc */
199 glEnable(GL_DEPTH_TEST);
200 glEnable(GL_LIGHTING);
201 glEnable(GL_LIGHT0);
202 }
203
204
205 int
206 main(int argc, char *argv[])
207 {
208 glutInit(&argc, argv);
209 glutInitWindowPosition(0, 0);
210 glutInitWindowSize(Width, Height);
211 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
212 Win = glutCreateWindow(argv[0]);
213 glewInit();
214 glutReshapeFunc(Reshape);
215 glutKeyboardFunc(Key);
216 glutSpecialFunc(SpecialKey);
217 glutDisplayFunc(Draw);
218 if (Anim)
219 glutIdleFunc(Idle);
220 Init();
221 glutMainLoop();
222 return 0;
223 }