Merge branch '7.8'
[mesa.git] / progs / tests / stencil_twoside.c
1 /*
2 * (C) Copyright IBM Corporation 2004
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file stencil_twoside.c
27 *
28 * Simple test of GL_ATI_separate_stencil (or the OGL 2.0 equivalent) functionality.
29 * Five squares (or six if stencil wrap is available) are drawn
30 * with different stencil modes, but all should be rendered with the same
31 * final color.
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <GL/glew.h>
37 #include <GL/glut.h>
38
39 static int use20syntax = 1;
40 static int Width = 650;
41 static int Height = 200;
42 static const GLfloat Near = 5.0, Far = 25.0;
43
44
45 static PFNGLSTENCILFUNCSEPARATEPROC stencil_func_separate = NULL;
46 static PFNGLSTENCILFUNCSEPARATEATIPROC stencil_func_separate_ati = NULL;
47 static PFNGLSTENCILOPSEPARATEPROC stencil_op_separate = NULL;
48
49 static void Display( void )
50 {
51 GLint max_stencil;
52 GLint stencil_bits;
53 unsigned i;
54
55
56 glGetIntegerv( GL_STENCIL_BITS, & stencil_bits );
57 max_stencil = (1U << stencil_bits) - 1;
58 printf( "Stencil bits = %u, maximum stencil value = 0x%08x\n",
59 stencil_bits, max_stencil );
60
61 glClearStencil( 1 );
62 glClearColor( 0.2, 0.2, 0.8, 0 );
63 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
64 | GL_STENCIL_BUFFER_BIT );
65
66
67 glPushMatrix();
68
69 /* This is the "reference" square.
70 */
71
72 glDisable(GL_STENCIL_TEST);
73 glTranslatef(-7.0, 0, 0);
74 glBegin(GL_QUADS);
75 glColor3f( 0.5, 0.5, 0.5 );
76 glVertex2f(-1, -1);
77 glVertex2f( 1, -1);
78 glVertex2f( 1, 1);
79 glVertex2f(-1, 1);
80 glEnd();
81
82
83 glEnable(GL_STENCIL_TEST);
84
85 /* Draw the first two squares using incr for the affected face
86 */
87
88 /*************************************************************************
89 * 2nd square
90 */
91 if (use20syntax) {
92 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
93 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
94 }
95 else {
96 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
97 }
98 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
99 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
100
101 glTranslatef(3.0, 0, 0);
102 glBegin(GL_QUADS);
103 glColor3f( 0.9, 0.9, 0.9 );
104 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
105 /* this should be front facing */
106 glVertex2f(-1, -1);
107 glVertex2f( 1, -1);
108 glVertex2f( 1, 1);
109 glVertex2f(-1, 1);
110 }
111 glEnd();
112
113 /* stencil vals should be equal to max_stencil */
114 glStencilFunc(GL_EQUAL, max_stencil, ~0);
115 glBegin(GL_QUADS);
116 glColor3f( 0.5, 0.5, 0.5 );
117 glVertex2f(-1, -1);
118 glVertex2f( 1, -1);
119 glVertex2f( 1, 1);
120 glVertex2f(-1, 1);
121 glEnd();
122
123 /*************************************************************************
124 * 3rd square
125 */
126 if (use20syntax) {
127 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
128 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
129 }
130 else {
131 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
132 }
133 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
134 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
135
136 glTranslatef(3.0, 0, 0);
137 glBegin(GL_QUADS);
138 glColor3f( 0.9, 0.9, 0.9 );
139 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
140 /* this should be back facing */
141 glVertex2f(-1, -1);
142 glVertex2f(-1, 1);
143 glVertex2f( 1, 1);
144 glVertex2f( 1, -1);
145 }
146 glEnd();
147
148 /* stencil vals should be equal to max_stencil */
149 glStencilFunc(GL_EQUAL, max_stencil, ~0);
150 glBegin(GL_QUADS);
151 glColor3f( 0.5, 0.5, 0.5 );
152 glVertex2f(-1, -1);
153 glVertex2f( 1, -1);
154 glVertex2f( 1, 1);
155 glVertex2f(-1, 1);
156 glEnd();
157
158 /*************************************************************************
159 * 4th square
160 */
161 if (use20syntax) {
162 stencil_func_separate(GL_FRONT, GL_NEVER, 0, ~0);
163 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
164 }
165 else {
166 stencil_func_separate_ati(GL_NEVER, GL_ALWAYS, 0, ~0);
167 }
168 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
169 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
170
171 glTranslatef(3.0, 0, 0);
172 glBegin(GL_QUADS);
173 glColor3f( 0.9, 0.9, 0.9 );
174 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
175 /* this should be back facing */
176 glVertex2f(-1, -1);
177 glVertex2f(-1, 1);
178 glVertex2f( 1, 1);
179 glVertex2f( 1, -1);
180 /* this should be front facing */
181 glVertex2f(-1, -1);
182 glVertex2f( 1, -1);
183 glVertex2f( 1, 1);
184 glVertex2f(-1, 1);
185 }
186 glEnd();
187
188 /* stencil vals should be equal to max_stencil */
189 glStencilFunc(GL_EQUAL, max_stencil, ~0);
190 glBegin(GL_QUADS);
191 glColor3f( 0.5, 0.5, 0.5 );
192 glVertex2f(-1, -1);
193 glVertex2f( 1, -1);
194 glVertex2f( 1, 1);
195 glVertex2f(-1, 1);
196 glEnd();
197
198 /*************************************************************************
199 * 5th square
200 */
201 if (use20syntax) {
202 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
203 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
204 }
205 else {
206 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
207 }
208 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
209 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
210
211 glTranslatef(3.0, 0, 0);
212 glBegin(GL_QUADS);
213 glColor3f( 0.9, 0.9, 0.9 );
214 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
215 /* this should be back facing */
216 glVertex2f(-1, -1);
217 glVertex2f(-1, 1);
218 glVertex2f( 1, 1);
219 glVertex2f( 1, -1);
220 /* this should be front facing */
221 glVertex2f(-1, -1);
222 glVertex2f( 1, -1);
223 glVertex2f( 1, 1);
224 glVertex2f(-1, 1);
225 }
226 glEnd();
227
228 glStencilFunc(GL_EQUAL, 1, ~0);
229 glBegin(GL_QUADS);
230 glColor3f( 0.5, 0.5, 0.5 );
231 glVertex2f(-1, -1);
232 glVertex2f( 1, -1);
233 glVertex2f( 1, 1);
234 glVertex2f(-1, 1);
235 glEnd();
236
237 /*************************************************************************
238 * 6th square
239 */
240 if (glutExtensionSupported("GL_EXT_stencil_wrap")) {
241 if (use20syntax) {
242 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
243 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
244 }
245 else {
246 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
247 }
248 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
249 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
250
251 glTranslatef(3.0, 0, 0);
252 glBegin(GL_QUADS);
253 glColor3f( 0.9, 0.9, 0.9 );
254 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
255 /* this should be back facing */
256 glVertex2f(-1, -1);
257 glVertex2f(-1, 1);
258 glVertex2f( 1, 1);
259 glVertex2f( 1, -1);
260 /* this should be front facing */
261 glVertex2f(-1, -1);
262 glVertex2f( 1, -1);
263 glVertex2f( 1, 1);
264 glVertex2f(-1, 1);
265 }
266 glEnd();
267
268 glStencilFunc(GL_EQUAL, 260 - 255, ~0);
269 glBegin(GL_QUADS);
270 glColor3f( 0.5, 0.5, 0.5 );
271 glVertex2f(-1, -1);
272 glVertex2f( 1, -1);
273 glVertex2f( 1, 1);
274 glVertex2f(-1, 1);
275 glEnd();
276 }
277
278 glPopMatrix();
279
280 glutSwapBuffers();
281 }
282
283
284 static void Reshape( int width, int height )
285 {
286 GLfloat ar = (float) width / (float) height;
287 Width = width;
288 Height = height;
289 glViewport( 0, 0, width, height );
290 glMatrixMode( GL_PROJECTION );
291 glLoadIdentity();
292 glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
293 glMatrixMode( GL_MODELVIEW );
294 glLoadIdentity();
295 glTranslatef( 0.0, 0.0, -15.0 );
296 }
297
298
299 static void Key( unsigned char key, int x, int y )
300 {
301 (void) x;
302 (void) y;
303 switch (key) {
304 case 27:
305 exit(0);
306 break;
307 }
308 glutPostRedisplay();
309 }
310
311
312 static void Init( void )
313 {
314 const char * const ver_string = (const char * const)
315 glGetString( GL_VERSION );
316
317 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
318 printf("GL_VERSION = %s\n", ver_string);
319
320 if ( !glutExtensionSupported("GL_ATI_separate_stencil")
321 && (atof( ver_string ) < 2.0) ) {
322 printf("Sorry, this program requires either GL_ATI_separate_stencil or OpenGL 2.0.\n");
323 exit(1);
324 }
325 if (atof( ver_string ) < 2.0) {
326 use20syntax = 0;
327 }
328 stencil_func_separate = (PFNGLSTENCILFUNCSEPARATEPROC) glutGetProcAddress( "glStencilFuncSeparate" );
329 stencil_func_separate_ati = (PFNGLSTENCILFUNCSEPARATEATIPROC) glutGetProcAddress( "glStencilFuncSeparateATI" );
330 stencil_op_separate = (PFNGLSTENCILOPSEPARATEPROC) glutGetProcAddress( "glStencilOpSeparate" );
331
332 printf("\nAll 5 (or 6) squares should be the same color.\n");
333 }
334
335
336 int main( int argc, char *argv[] )
337 {
338 glutInit( &argc, argv );
339 glutInitWindowPosition( 0, 0 );
340 glutInitWindowSize( Width, Height );
341 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL );
342 glutCreateWindow( "GL_ATI_separate_stencil test" );
343 glewInit();
344 glutReshapeFunc( Reshape );
345 glutKeyboardFunc( Key );
346 glutDisplayFunc( Display );
347 Init();
348 glutMainLoop();
349 return 0;
350 }