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
119 if (use20syntax) {
120 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
121 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
122 }
123 else {
124 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
125 }
126 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
127 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
128
129 glTranslatef(3.0, 0, 0);
130 glBegin(GL_QUADS);
131 glColor3f( 0.9, 0.9, 0.9 );
132
133 /* this should be back facing */
134 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
135 glVertex2f(-1, -1);
136 glVertex2f(-1, 1);
137 glVertex2f( 1, 1);
138 glVertex2f( 1, -1);
139 }
140 glEnd();
141
142 glStencilFunc(GL_EQUAL, max_stencil, ~0);
143 glBegin(GL_QUADS);
144 glColor3f( 0.5, 0.5, 0.5 );
145 glVertex2f(-1, -1);
146 glVertex2f( 1, -1);
147 glVertex2f( 1, 1);
148 glVertex2f(-1, 1);
149 glEnd();
150
151 if (use20syntax) {
152 stencil_func_separate(GL_FRONT, GL_NEVER, 0, ~0);
153 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
154 }
155 else {
156 stencil_func_separate_ati(GL_NEVER, GL_ALWAYS, 0, ~0);
157 }
158 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
159 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
160
161 glTranslatef(3.0, 0, 0);
162 glBegin(GL_QUADS);
163 glColor3f( 0.9, 0.9, 0.9 );
164
165 /* this should be back facing */
166 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
167 /* this should be back facing */
168 glVertex2f(-1, -1);
169 glVertex2f(-1, 1);
170 glVertex2f( 1, 1);
171 glVertex2f( 1, -1);
172 /* this should be front facing */
173 glVertex2f(-1, -1);
174 glVertex2f( 1, -1);
175 glVertex2f( 1, 1);
176 glVertex2f(-1, 1);
177 }
178 glEnd();
179
180 glStencilFunc(GL_EQUAL, max_stencil, ~0);
181 glBegin(GL_QUADS);
182 glColor3f( 0.5, 0.5, 0.5 );
183 glVertex2f(-1, -1);
184 glVertex2f( 1, -1);
185 glVertex2f( 1, 1);
186 glVertex2f(-1, 1);
187 glEnd();
188
189 if (use20syntax) {
190 stencil_func_separate(GL_FRONT, GL_ALWAYS, 0, ~0);
191 stencil_func_separate(GL_BACK, GL_ALWAYS, 0, ~0);
192 }
193 else {
194 stencil_func_separate_ati(GL_ALWAYS, GL_ALWAYS, 0, ~0);
195 }
196 stencil_op_separate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR);
197 stencil_op_separate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR);
198
199 glTranslatef(3.0, 0, 0);
200 glBegin(GL_QUADS);
201 glColor3f( 0.9, 0.9, 0.9 );
202
203 /* this should be back facing */
204 for ( i = 0 ; i < (max_stencil + 5) ; i++ ) {
205 /* this should be back facing */
206 glVertex2f(-1, -1);
207 glVertex2f(-1, 1);
208 glVertex2f( 1, 1);
209 glVertex2f( 1, -1);
210 /* this should be front facing */
211 glVertex2f(-1, -1);
212 glVertex2f( 1, -1);
213 glVertex2f( 1, 1);
214 glVertex2f(-1, 1);
215 }
216 glEnd();
217
218 glStencilFunc(GL_EQUAL, 1, ~0);
219 glBegin(GL_QUADS);
220 glColor3f( 0.5, 0.5, 0.5 );
221 glVertex2f(-1, -1);
222 glVertex2f( 1, -1);
223 glVertex2f( 1, 1);
224 glVertex2f(-1, 1);
225 glEnd();
226
227 glPopMatrix();
228
229 glutSwapBuffers();
230 }
231
232
233 static void Reshape( int width, int height )
234 {
235 GLfloat ar = (float) width / (float) height;
236 Width = width;
237 Height = height;
238 glViewport( 0, 0, width, height );
239 glMatrixMode( GL_PROJECTION );
240 glLoadIdentity();
241 glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
242 glMatrixMode( GL_MODELVIEW );
243 glLoadIdentity();
244 glTranslatef( 0.0, 0.0, -15.0 );
245 }
246
247
248 static void Key( unsigned char key, int x, int y )
249 {
250 (void) x;
251 (void) y;
252 switch (key) {
253 case 27:
254 exit(0);
255 break;
256 }
257 glutPostRedisplay();
258 }
259
260
261 static void Init( void )
262 {
263 const char * const ver_string = (const char * const)
264 glGetString( GL_VERSION );
265
266 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
267 printf("GL_VERSION = %s\n", ver_string);
268
269 if ( !glutExtensionSupported("GL_ATI_separate_stencil")
270 && (atof( ver_string ) < 2.0) ) {
271 printf("Sorry, this program requires either GL_ATI_separate_stencil or OpenGL 2.0.\n");
272 exit(1);
273 }
274 if (atof( ver_string ) < 2.0) {
275 use20syntax = 0;
276 }
277 stencil_func_separate = glutGetProcAddress( "glStencilFuncSeparate" );
278 stencil_func_separate_ati = glutGetProcAddress( "glStencilFuncSeparateATI" );
279 stencil_op_separate = glutGetProcAddress( "glStencilOpSeparate" );
280
281 printf("\nAll 5 squares should be the same color.\n");
282 glEnable( GL_BLEND );
283 }
284
285
286 int main( int argc, char *argv[] )
287 {
288 glutInit( &argc, argv );
289 glutInitWindowPosition( 0, 0 );
290 glutInitWindowSize( Width, Height );
291 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL );
292 glutCreateWindow( "GL_ATI_separate_stencil test" );
293 glutReshapeFunc( Reshape );
294 glutKeyboardFunc( Key );
295 glutDisplayFunc( Display );
296 Init();
297 glutMainLoop();
298 return 0;
299 }