Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / tstencil2.cpp
blobd0c783a8f9c0476595e979486e149ed9c0cbeb40
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyright (C) 2009 VMware, Inc. All Rights Reserved.
4 //
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
12 // conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
16 // Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL VMWARE BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
26 //
27 // END_COPYRIGHT
30 // Test two-sided stencil extensions
31 // Brian Paul
32 // 19 Feb 2009
35 // This test could be better:
36 // 1. Generate random state vectors, render and compare to expected values
37 // 2. Exercise separate front/back reference values and masks for the
38 // EXT and GL2 variations.
42 #include <cassert>
43 #include <cstring>
44 #include "tstencil2.h"
47 namespace GLEAN {
49 // ATI
50 static PFNGLSTENCILOPSEPARATEATIPROC glStencilOpSeparateATI_func;
51 static PFNGLSTENCILFUNCSEPARATEATIPROC glStencilFuncSeparateATI_func;
53 // EXT
54 static PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFaceEXT_func;
56 // GL2
57 static PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate_func;
58 static PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate_func;
59 static PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate_func;
62 // two-sided methods:
63 #define ATI 1
64 #define EXT 2
65 #define GL2 3
68 Stencil2Result::Stencil2Result()
70 pass = false;
74 void
75 Stencil2Test::get_ext_functions(void)
77 // ATI
78 glStencilOpSeparateATI_func = (PFNGLSTENCILOPSEPARATEATIPROC)
79 GLUtils::getProcAddress("glStencilOpSeparateATI");
80 glStencilFuncSeparateATI_func = (PFNGLSTENCILFUNCSEPARATEATIPROC)
81 GLUtils::getProcAddress("glStencilFuncSeparateATI");
83 // EXT
84 glActiveStencilFaceEXT_func = (PFNGLACTIVESTENCILFACEEXTPROC)
85 GLUtils::getProcAddress("glActiveStencilFaceEXT");
87 // GL2
88 glStencilOpSeparate_func = (PFNGLSTENCILOPSEPARATEPROC)
89 GLUtils::getProcAddress("glStencilOpSeparate");
91 glStencilFuncSeparate_func = (PFNGLSTENCILFUNCSEPARATEPROC)
92 GLUtils::getProcAddress("glStencilFuncSeparate");
94 glStencilMaskSeparate_func= (PFNGLSTENCILMASKSEPARATEPROC)
95 GLUtils::getProcAddress("glStencilMaskSeparate");
99 bool
100 Stencil2Test::have_ATI_separate_stencil(void) const
102 return GLUtils::haveExtension("GL_ATI_separate_stencil");
105 bool
106 Stencil2Test::have_EXT_stencil_two_side(void) const
108 return GLUtils::haveExtension("GL_EXT_stencil_two_side");
111 bool
112 Stencil2Test::have_GL2_stencil_two_side(void) const
114 const char *version = (const char *) glGetString(GL_VERSION);
115 if (strncmp(version, "2.", 2) == 0 ||
116 strncmp(version, "3.0", 3) == 0) {
117 return true;
119 return false;
122 bool
123 Stencil2Test::have_stencil_wrap(void) const
125 const char *version = (const char *) glGetString(GL_VERSION);
126 if (strncmp(version, "2.", 2) == 0 ||
127 strncmp(version, "3.0", 3) == 0) {
128 return true;
130 else if (GLUtils::haveExtension("GL_EXT_stencil_wrap")) {
131 return true;
133 return false;
137 // Draw four quads:
138 // Bottom row uses GL_CCW
139 // Top row uses GL_CW
140 // Left column is front-facing
141 // Right column is back-facing
142 // Check the values in the stencil buffer to see if they match
143 // the expected values.
144 bool
145 Stencil2Test::render_test(GLuint expectedFront, GLuint expectedBack)
147 GLint x0 = 0;
148 GLint x1 = windowSize / 2;
149 GLint x2 = windowSize;
150 GLint y0 = 0;
151 GLint y1 = windowSize / 2;
152 GLint y2 = windowSize;
154 glFrontFace(GL_CCW); // this the GL default
156 // lower left quad = front-facing
157 glBegin(GL_TRIANGLE_FAN);
158 glVertex2f(x0, y0);
159 glVertex2f(x1, y0);
160 glVertex2f(x1, y1);
161 glVertex2f(x0, y1);
162 glEnd();
164 // lower right quad = back-facing
165 glBegin(GL_TRIANGLE_FAN);
166 glVertex2f(x1, y0);
167 glVertex2f(x1, y1);
168 glVertex2f(x2, y1);
169 glVertex2f(x2, y0);
170 glEnd();
172 glFrontFace(GL_CW);
174 // upper left quad = front-facing
175 glBegin(GL_TRIANGLE_FAN);
176 glVertex2f(x0, y1);
177 glVertex2f(x0, y2);
178 glVertex2f(x1, y2);
179 glVertex2f(x1, y1);
180 glEnd();
182 // upper right quad = back-facing
183 glBegin(GL_TRIANGLE_FAN);
184 glVertex2f(x1, y1);
185 glVertex2f(x2, y1);
186 glVertex2f(x2, y2);
187 glVertex2f(x1, y2);
188 glEnd();
190 GLint midXleft = (x0 + x1) / 2;
191 GLint midXright = (x1 + x2) / 2;
192 GLint midYlower = (y0 + y1) / 2;
193 GLint midYupper = (y1 + y2) / 2;
194 GLuint lowerLeftVal, lowerRightVal;
195 GLuint upperLeftVal, upperRightVal;
197 glReadPixels(midXleft, midYlower, 1, 1,
198 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerLeftVal);
199 glReadPixels(midXright, midYlower, 1, 1,
200 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerRightVal);
202 glReadPixels(midXleft, midYupper, 1, 1,
203 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperLeftVal);
204 glReadPixels(midXright, midYupper, 1, 1,
205 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperRightVal);
207 if (lowerLeftVal != upperLeftVal) {
208 env->log << "FAIL:\n";
209 env->log << "\tLower-left value (" << lowerLeftVal
210 << ") doesn't match upper-left value ("
211 << upperLeftVal
212 << ").\n";
213 env->log << "\tLooks like a front/back-face orientation bug.\n";
214 return false;
217 if (lowerRightVal != upperRightVal) {
218 env->log << "FAIL:\n";
219 env->log << "\tLower-right value (" << lowerRightVal
220 << ") doesn't match upper-right value ("
221 << upperRightVal
222 << ").\n";
223 env->log << "\tLooks like a front/back-face orientation bug.\n";
224 return false;
228 if (lowerLeftVal != expectedFront) {
229 env->log << "FAIL:\n";
230 env->log << "\tExpected front-face stencil value is "
231 << expectedFront
232 << " but found " << lowerLeftVal << "\n";
233 return false;
235 else if (lowerRightVal != expectedBack) {
236 env->log << "FAIL:\n";
237 env->log << "\tExpected back-face stencil value is " << expectedBack
238 << " but found " << lowerRightVal << "\n";
239 return false;
241 else {
242 return true;
247 bool
248 Stencil2Test::compare_state(int method, GLenum found, GLenum expected,
249 const char *msg)
251 if (found != expected) {
252 env->log << "FAIL:\n";
253 env->log << "\tQuery of " << msg << " state failed for ";
254 switch (method) {
255 case ATI:
256 env->log << "GL_ATI_separate_stencil";
257 break;
258 case EXT:
259 env->log << "GL_EXT_stencil_two_side";
260 break;
261 case GL2:
262 env->log << "GL 2.x two-sided stencil";
263 break;
264 default:
265 assert(0);
267 env->log << "\n";
268 char s[1000];
269 sprintf(s, "\tFound 0x%x, expected 0x%x\n", found, expected);
270 env->log << s;
271 return false;
273 return true;
277 // Set stencil state, plus read it back and check that it's correct.
278 // Note: we only test with one reference value and one mask value
279 // even though EXT and GL2 support separate front/back refs/masks
280 bool
281 Stencil2Test::set_stencil_state(int method,
282 GLenum frontStencilFail,
283 GLenum backStencilFail,
284 GLenum frontZFail,
285 GLenum backZFail,
286 GLenum frontZPass,
287 GLenum backZPass,
288 GLenum frontFunc,
289 GLenum backFunc,
290 GLint ref,
291 GLuint mask)
293 GLint get_frontStencilFail;
294 GLint get_backStencilFail;
295 GLint get_frontZFail;
296 GLint get_backZFail;
297 GLint get_frontZPass;
298 GLint get_backZPass;
299 GLint get_frontFunc;
300 GLint get_backFunc;
301 GLint get_ref;
302 GLint get_mask;
303 GLint twoEnabled;
305 switch (method) {
306 case ATI:
307 // set state
308 glStencilOpSeparateATI_func(GL_FRONT,
309 frontStencilFail,
310 frontZFail,
311 frontZPass);
313 glStencilOpSeparateATI_func(GL_BACK,
314 backStencilFail,
315 backZFail,
316 backZPass);
318 glStencilFuncSeparateATI_func(frontFunc, backFunc, ref, mask);
320 // get state
321 glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
322 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
323 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
324 glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
325 glGetIntegerv(GL_STENCIL_REF, &get_ref);
326 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_mask);
328 glGetIntegerv(GL_STENCIL_BACK_FUNC_ATI, &get_backFunc);
329 glGetIntegerv(GL_STENCIL_BACK_FAIL_ATI, &get_backStencilFail);
330 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI, &get_backZFail);
331 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI, &get_backZPass);
332 twoEnabled = GL_TRUE;
333 break;
335 case EXT:
336 // set state
337 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
339 glActiveStencilFaceEXT_func(GL_FRONT);
340 glStencilOp(frontStencilFail, frontZFail, frontZPass);
341 glStencilFunc(frontFunc, ref, mask);
343 glActiveStencilFaceEXT_func(GL_BACK);
344 glStencilOp(backStencilFail, backZFail, backZPass);
345 glStencilFunc(backFunc, ref, mask);
347 // get state
348 glActiveStencilFaceEXT_func(GL_FRONT);
349 glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
350 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
351 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
352 glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
353 glGetIntegerv(GL_STENCIL_REF, &get_ref);
354 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_mask);
355 glActiveStencilFaceEXT_func(GL_BACK);
356 glGetIntegerv(GL_STENCIL_FAIL, &get_backStencilFail);
357 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_backZFail);
358 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_backZPass);
359 glGetIntegerv(GL_STENCIL_FUNC, &get_backFunc);
360 glGetIntegerv(GL_STENCIL_REF, &get_ref);
361 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_mask);
362 glGetIntegerv(GL_STENCIL_TEST_TWO_SIDE_EXT, &twoEnabled);
363 break;
365 case GL2:
366 // set state
367 glStencilOpSeparate_func(GL_FRONT,
368 frontStencilFail,
369 frontZFail,
370 frontZPass);
371 glStencilOpSeparate_func(GL_BACK,
372 backStencilFail,
373 backZFail,
374 backZPass);
375 glStencilFuncSeparate_func(GL_FRONT, frontFunc, ref, mask);
376 glStencilFuncSeparate_func(GL_BACK, backFunc, ref, mask);
378 // get state
379 glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
380 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
381 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
382 glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
383 glGetIntegerv(GL_STENCIL_REF, &get_ref);
384 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_mask);
386 glGetIntegerv(GL_STENCIL_BACK_FUNC, &get_backFunc);
387 glGetIntegerv(GL_STENCIL_BACK_FAIL, &get_backStencilFail);
388 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &get_backZFail);
389 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &get_backZPass);
390 twoEnabled = GL_TRUE;
391 break;
393 default:
394 assert(0);
397 // mask off bits we don't care about
398 get_mask &= stencilMax;
399 mask &= stencilMax;
401 GLenum err = glGetError();
402 if (err != GL_NO_ERROR) {
403 env->log << "FAIL:\n";
404 env->log << "\tGL error " << err << " detected.\n";
405 return false;
408 // see if state-get matches state-set
410 if (!compare_state(method, get_frontStencilFail, frontStencilFail,
411 "front stencil fail"))
412 return false;
414 if (!compare_state(method, get_backStencilFail, backStencilFail,
415 "back stencil fail"))
416 return false;
418 if (!compare_state(method, get_frontZFail, frontZFail,
419 "front Z fail"))
420 return false;
422 if (!compare_state(method, get_backZFail, backZFail,
423 "back Z fail"))
424 return false;
426 if (!compare_state(method, get_frontZPass, frontZPass,
427 "front Z pass"))
428 return false;
430 if (!compare_state(method, get_backZPass, backZPass,
431 "back Z pass"))
432 return false;
434 if (!compare_state(method, get_frontFunc, frontFunc,
435 "front stencil func"))
436 return false;
438 if (!compare_state(method, get_backFunc, backFunc,
439 "back stencil func"))
440 return false;
442 if (!compare_state(method, get_ref, ref, "stencil ref"))
443 return false;
445 if (!compare_state(method, get_mask, mask, "stencil mask"))
446 return false;
448 if (!compare_state(method, twoEnabled, GL_TRUE, "two-side enable"))
449 return false;
451 return true;
455 void
456 Stencil2Test::reset_stencil_state(int method)
458 switch (method) {
459 case ATI:
460 break;
461 case EXT:
462 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
463 glActiveStencilFaceEXT_func(GL_FRONT);
464 break;
465 case GL2:
466 break;
467 default:
468 assert(0);
473 bool
474 Stencil2Test::test_stencil(int method)
476 bool pass;
478 glEnable(GL_STENCIL_TEST);
480 //============================================================
481 // No depth testing
482 glDisable(GL_DEPTH_TEST);
484 glClear(GL_COLOR_BUFFER_BIT |
485 GL_STENCIL_BUFFER_BIT |
486 GL_DEPTH_BUFFER_BIT);
489 // set stencil buffer vals to 5
490 pass = set_stencil_state(method,
491 GL_KEEP, GL_KEEP, // stencil fail
492 GL_KEEP, GL_KEEP, // z fail
493 GL_REPLACE, GL_REPLACE, // z pass
494 GL_ALWAYS, GL_ALWAYS, // stencil func
495 5, ~0); // ref, mask
496 if (pass)
497 pass = render_test(5, 5);
498 reset_stencil_state(method);
499 if (!pass)
500 return false;
502 // incr front val to 6, decr back val to 4
503 pass = set_stencil_state(method,
504 GL_KEEP, GL_KEEP, // stencil fail
505 GL_KEEP, GL_KEEP, // z fail
506 GL_INCR, GL_DECR, // z pass
507 GL_ALWAYS, GL_ALWAYS, // stencil func
508 5, ~0); // ref, mask
509 if (pass)
510 pass = render_test(6, 4);
511 reset_stencil_state(method);
512 if (!pass)
513 return false;
515 // if front==6, keep
516 // if back<6, replace with zero
517 // final: front=6, back=0
518 pass = set_stencil_state(method,
519 GL_KEEP, GL_ZERO, // stencil fail
520 GL_KEEP, GL_KEEP, // z fail
521 GL_KEEP, GL_KEEP, // z pass
522 GL_EQUAL, GL_LESS, // stencil func
523 6, ~0); // ref, mask
524 if (pass)
525 pass = render_test(6, 0);
526 reset_stencil_state(method);
527 if (!pass)
528 return false;
530 // if front!=10, keep, else decr
531 // if back<10, keep, else incr
532 // final: front=6, back=1
533 pass = set_stencil_state(method,
534 GL_DECR, GL_INCR, // stencil fail
535 GL_KEEP, GL_KEEP, // z fail
536 GL_KEEP, GL_KEEP, // z pass
537 GL_NOTEQUAL, GL_LESS, // stencil func
538 10, ~0); // ref, mask
539 if (pass)
540 pass = render_test(6, 1);
541 reset_stencil_state(method);
542 if (!pass)
543 return false;
546 //============================================================
547 // Now begin tests with depth test
548 glEnable(GL_DEPTH_TEST);
549 glDepthFunc(GL_LESS);
551 glClear(GL_COLOR_BUFFER_BIT |
552 GL_STENCIL_BUFFER_BIT |
553 GL_DEPTH_BUFFER_BIT);
555 // set stencil buffer vals to 7, set Z values
556 pass = set_stencil_state(method,
557 GL_KEEP, GL_KEEP, // stencil fail
558 GL_KEEP, GL_KEEP, // z fail
559 GL_REPLACE, GL_REPLACE, // z pass
560 GL_ALWAYS, GL_ALWAYS, // stencil func
561 7, ~0); // ref, mask
562 if (pass)
563 pass = render_test(7, 7);
564 reset_stencil_state(method);
565 if (!pass)
566 return false;
569 // GL_LESS test should fail everywhere
570 // decr front to 5, incr back to 2
571 pass = set_stencil_state(method,
572 GL_KEEP, GL_KEEP, // stencil fail
573 GL_DECR, GL_INCR, // z fail
574 GL_KEEP, GL_KEEP, // z pass
575 GL_ALWAYS, GL_ALWAYS, // stencil func
576 99, ~0); // ref, mask
577 if (pass)
578 pass = render_test(6, 8);
579 reset_stencil_state(method);
580 if (!pass)
581 return false;
584 // set depth test = GL_EQUAL
585 // Z test should pass everywhere
586 // set front to 3
587 // decr back to 7
588 glDepthFunc(GL_EQUAL);
589 pass = set_stencil_state(method,
590 GL_KEEP, GL_KEEP, // stencil fail
591 GL_KEEP, GL_KEEP, // z fail
592 GL_REPLACE, GL_DECR, // z pass
593 GL_ALWAYS, GL_ALWAYS, // stencil func
594 3, ~0); // ref, mask
595 if (pass)
596 pass = render_test(3, 7);
597 reset_stencil_state(method);
598 if (!pass)
599 return false;
602 // incr front to 4 (by z pass), decr back to 6 (by stencil fail)
603 pass = set_stencil_state(method,
604 GL_DECR, GL_INCR, // stencil fail
605 GL_KEEP, GL_KEEP, // z fail
606 GL_INCR, GL_DECR, // z pass
607 GL_EQUAL, GL_NOTEQUAL, // stencil func
608 3, ~0); // ref, mask
609 if (pass)
610 pass = render_test(4, 6);
611 reset_stencil_state(method);
612 if (!pass)
613 return false;
616 //============================================================
617 // Disable depth test
618 glDisable(GL_DEPTH_TEST);
620 // test stencil value mask
621 // only test bit 1 in stencil values
622 // if !(front&0x2 == 15&0x2), decr to 3 (should happen)
623 // if !(back&0x2 == 15&0x2), incr to 7 (should not happen)
624 pass = set_stencil_state(method,
625 GL_DECR, GL_INCR, // stencil fail
626 GL_KEEP, GL_KEEP, // z fail
627 GL_KEEP, GL_KEEP, // z pass
628 GL_EQUAL, GL_EQUAL, // stencil func
629 15, 0x2); // ref, mask
630 if (pass)
631 pass = render_test(3, 6);
632 reset_stencil_state(method);
633 if (!pass)
634 return false;
637 //============================================================
638 // Test common two-sided stencil modes for shadow volume rendering
639 // Requires stencil +/- wrap feature.
641 if (!have_stencil_wrap())
642 return true;
644 glClear(GL_COLOR_BUFFER_BIT |
645 GL_STENCIL_BUFFER_BIT |
646 GL_DEPTH_BUFFER_BIT);
648 glEnable(GL_DEPTH_TEST);
649 glDepthFunc(GL_LESS);
651 // "traditional / Z-pass" method:
652 // front face: incr on zpass
653 // back face: decr on zpass
654 // both front and back Z-test should pass here
655 pass = set_stencil_state(method,
656 GL_KEEP, GL_KEEP, // stencil fail
657 GL_KEEP, GL_KEEP, // z fail
658 GL_INCR_WRAP_EXT, GL_DECR_WRAP_EXT, // z pass
659 GL_ALWAYS, GL_ALWAYS, // stencil func
660 0, ~0); // ref, mask
661 if (pass)
662 pass = render_test(1, stencilMax);
663 reset_stencil_state(method);
664 if (!pass)
665 return false;
668 // "Z-fail" method:
669 // front face: decr on zfail
670 // back face: incr on zfail
671 // both front and back Z-test should fail here
672 pass = set_stencil_state(method,
673 GL_KEEP, GL_KEEP, // stencil fail
674 GL_DECR_WRAP_EXT, GL_INCR_WRAP_EXT, // z fail
675 GL_KEEP, GL_KEEP, // z pass
676 GL_ALWAYS, GL_ALWAYS, // stencil func
677 0, ~0); // ref, mask
678 if (pass)
679 pass = render_test(0, 0);
680 reset_stencil_state(method);
681 if (!pass)
682 return false;
685 return true;
689 void
690 Stencil2Test::runOne(Stencil2Result &r, Window &w)
692 (void) w; // silence warning
693 r.pass = true;
695 get_ext_functions();
697 // how many stencil bits (we assume at least 8 above)
698 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
699 stencilMax = (1 << stencilBits) - 1;
700 assert(stencilBits >= 8);
702 glViewport(0, 0, windowSize, windowSize);
703 glMatrixMode(GL_PROJECTION);
704 glLoadIdentity();
705 glOrtho(0, windowSize, 0, windowSize, -1, 1);
706 glMatrixMode(GL_MODELVIEW);
707 glLoadIdentity();
709 if (have_ATI_separate_stencil()) {
710 r.pass &= test_stencil(ATI);
713 if (have_EXT_stencil_two_side()) {
714 r.pass &= test_stencil(EXT);
717 if (have_GL2_stencil_two_side()) {
718 r.pass &= test_stencil(GL2);
723 void
724 Stencil2Test::logOne(Stencil2Result &r)
726 logPassFail(r);
727 logConcise(r);
731 void
732 Stencil2Test::compareOne(Stencil2Result &oldR,
733 Stencil2Result &stencil2R)
735 comparePassFail(oldR, stencil2R);
739 void
740 Stencil2Result::putresults(ostream &s) const
742 if (pass) {
743 s << "PASS\n";
745 else {
746 s << "FAIL\n";
751 bool
752 Stencil2Result::getresults(istream &s)
754 char result[1000];
755 s >> result;
757 if (strcmp(result, "FAIL") == 0) {
758 pass = false;
760 else {
761 pass = true;
763 return s.good();
767 bool
768 Stencil2Test::isApplicable() const
770 return (have_ATI_separate_stencil() ||
771 have_EXT_stencil_two_side() ||
772 have_EXT_stencil_two_side());
777 // The test object itself:
778 Stencil2Test stencil2Test("stencil2",
779 "window, rgb, s, z", // we need stencil and Z
780 "", // no extension filter, but see isApplicable()
781 "Test two-sided stencil features\n");
785 } // namespace GLEAN