Merge commit 'origin/gallium-0.1' into gallium-0.2
[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 * Four squares 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/glut.h>
37
38 static int use20syntax = 1;
39 static int Width = 550;
40 static int Height = 200;
41 static const GLfloat Near = 5.0, Far = 25.0;
42
43
44 static PFNGLSTENCILFUNCSEPARATEPROC stencil_func_separate = NULL;
45 static PFNGLSTENCILFUNCSEPARATEATIPROC stencil_func_separate_ati = NULL;
46 static PFNGLSTENCILOPSEPARATEPROC stencil_op_separate = NULL;
47
48 static void Display( void )
49 {
50 GLint max_stencil;
51 GLint stencil_bits;
52 unsigned i;
53
54
55 glGetIntegerv( GL_STENCIL_BITS, & stencil_bits );
56 max_stencil = (1U << stencil_bits) - 1;
57 printf( "Stencil bits = %u, maximum stencil value = 0x%08x\n",
58 stencil_bits, max_stencil );
59
60 glClearStencil( 1 );
61 glClearColor( 0.2, 0.2, 0.8, 0 );
62 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
63 | GL_STENCIL_BUFFER_BIT );
64
65
66 glPushMatrix();
67
68 /* This is the "reference" square.
69 */
70
71 glDisable(GL_STENCIL_TEST);
72 glTranslatef(-6.0, 0, 0);
73 glBegin(GL_QUADS);
74 glColor3f( 0.5, 0.5, 0.5 );
75 glVertex2f(-1, -1);
76 glVertex2f( 1, -1);
77 glVertex2f( 1, 1);
78 glVertex2f(-1, 1);
79 glEnd();
80
81
82 glEnable(GL_STENCIL_TEST);
83
84 /* Draw the first two squares using incr for the affected face
85 */
86
87 if (use20syntax) {
88 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
89 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
90 }
91 else {
92 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
93 }
94 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR);
95 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR);
96
97 glTranslatef(3.0, 0, 0);
98 glBegin(GL_QUADS);
99 glColor3f( 0.9, 0.9, 0.9 );
100 /* this should be front facing */
101 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
102 glVertex2f(-1, -1);
103 glVertex2f( 1, -1);
104 glVertex2f( 1, 1);
105 glVertex2f(-1, 1);
106 }
107 glEnd();
108
109 glStencilFunc(GL_EQUAL, max_stencil, ~0);
110 glBegin(GL_QUADS);
111 glColor3f( 0.5, 0.5, 0.5 );
112 glVertex2f(-1, -1);
113 glVertex2f( 1, -1);
114 glVertex2f( 1, 1);
115 glVertex2f(-1, 1);
116 glEnd();
117
118 if (use20syntax) {
119 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
120 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
121 }
122 else {
123 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
124 }
125 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
126 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
127
128 glTranslatef(3.0, 0, 0);
129 glBegin(GL_QUADS);
130 glColor3f( 0.9, 0.9, 0.9 );
131
132 /* this should be back facing */
133 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
134 glVertex2f(-1, -1);
135 glVertex2f(-1, 1);
136 glVertex2f( 1, 1);
137 glVertex2f( 1, -1);
138 }
139 glEnd();
140
141 glStencilFunc(GL_EQUAL, max_stencil, ~0);
142 glBegin(GL_QUADS);
143 glColor3f( 0.5, 0.5, 0.5 );
144 glVertex2f(-1, -1);
145 glVertex2f( 1, -1);
146 glVertex2f( 1, 1);
147 glVertex2f(-1, 1);
148 glEnd();
149
150 if (use20syntax) {
151 stencil_func_separate(GL_FRONT, GL_NEVER, 0, ~0);
152 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
153 }
154 else {
155 stencil_func_separate_ati(GL_NEVER, GL_ALWAYS, 0, ~0);
156 }
157 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
158 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
159
160 glTranslatef(3.0, 0, 0);
161 glBegin(GL_QUADS);
162 glColor3f( 0.9, 0.9, 0.9 );
163
164 /* this should be back facing */
165 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
166 /* this should be back facing */
167 glVertex2f(-1, -1);
168 glVertex2f(-1, 1);
169 glVertex2f( 1, 1);
170 glVertex2f( 1, -1);
171 /* this should be front facing */
172 glVertex2f(-1, -1);
173 glVertex2f( 1, -1);
174 glVertex2f( 1, 1);
175 glVertex2f(-1, 1);
176 }
177 glEnd();
178
179 glStencilFunc(GL_EQUAL, max_stencil, ~0);
180 glBegin(GL_QUADS);
181 glColor3f( 0.5, 0.5, 0.5 );
182 glVertex2f(-1, -1);
183 glVertex2f( 1, -1);
184 glVertex2f( 1, 1);
185 glVertex2f(-1, 1);
186 glEnd();
187
188 if (use20syntax) {
189 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
190 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
191 }
192 else {
193 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
194 }
195 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
196 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
197
198 glTranslatef(3.0, 0, 0);
199 glBegin(GL_QUADS);
200 glColor3f( 0.9, 0.9, 0.9 );
201
202 /* this should be back facing */
203 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
204 /* this should be back facing */
205 glVertex2f(-1, -1);
206 glVertex2f(-1, 1);
207 glVertex2f( 1, 1);
208 glVertex2f( 1, -1);
209 /* this should be front facing */
210 glVertex2f(-1, -1);
211 glVertex2f( 1, -1);
212 glVertex2f( 1, 1);
213 glVertex2f(-1, 1);
214 }
215 glEnd();
216
217 glStencilFunc(GL_EQUAL, 1, ~0);
218 glBegin(GL_QUADS);
219 glColor3f( 0.5, 0.5, 0.5 );
220 glVertex2f(-1, -1);
221 glVertex2f( 1, -1);
222 glVertex2f( 1, 1);
223 glVertex2f(-1, 1);
224 glEnd();
225
226 glPopMatrix();
227
228 glutSwapBuffers();
229 }
230
231
232 static void Reshape( int width, int height )
233 {
234 GLfloat ar = (float) width / (float) height;
235 Width = width;
236 Height = height;
237 glViewport( 0, 0, width, height );
238 glMatrixMode( GL_PROJECTION );
239 glLoadIdentity();
240 glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
241 glMatrixMode( GL_MODELVIEW );
242 glLoadIdentity();
243 glTranslatef( 0.0, 0.0, -15.0 );
244 }
245
246
247 static void Key( unsigned char key, int x, int y )
248 {
249 (void) x;
250 (void) y;
251 switch (key) {
252 case 27:
253 exit(0);
254 break;
255 }
256 glutPostRedisplay();
257 }
258
259
260 static void Init( void )
261 {
262 const char * const ver_string = (const char * const)
263 glGetString( GL_VERSION );
264
265 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
266 printf("GL_VERSION = %s\n", ver_string);
267
268 if ( !glutExtensionSupported("GL_ATI_separate_stencil")
269 && (atof( ver_string ) < 2.0) ) {
270 printf("Sorry, this program requires either GL_ATI_separate_stencil or OpenGL 2.0.\n");
271 exit(1);
272 }
273 if (atof( ver_string ) < 2.0) {
274 use20syntax = 0;
275 }
276 stencil_func_separate = glutGetProcAddress( "glStencilFuncSeparate" );
277 stencil_func_separate_ati = glutGetProcAddress( "glStencilFuncSeparateATI" );
278 stencil_op_separate = glutGetProcAddress( "glStencilOpSeparate" );
279
280 printf("\nAll 5 squares should be the same color.\n");
281 }
282
283
284 int main( int argc, char *argv[] )
285 {
286 glutInit( &argc, argv );
287 glutInitWindowPosition( 0, 0 );
288 glutInitWindowSize( Width, Height );
289 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL );
290 glutCreateWindow( "GL_ATI_separate_stencil test" );
291 glutReshapeFunc( Reshape );
292 glutKeyboardFunc( Key );
293 glutDisplayFunc( Display );
294 Init();
295 glutMainLoop();
296 return 0;
297 }