bool Stencil2Test::test_stencil(int method) { bool pass; glEnable(GL_STENCIL_TEST); //============================================================ // No depth testing glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set stencil buffer vals to 5 pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_REPLACE, GL_REPLACE, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 5, ~0); // ref, mask if (pass) pass = render_test(5, 5); reset_stencil_state(method); if (!pass) return false; // incr front val to 6, decr back val to 4 pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_INCR, GL_DECR, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 5, ~0); // ref, mask if (pass) pass = render_test(6, 4); reset_stencil_state(method); if (!pass) return false; // if front==6, keep // if back<6, replace with zero // final: front=6, back=0 pass = set_stencil_state(method, GL_KEEP, GL_ZERO, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_KEEP, GL_KEEP, // z pass GL_EQUAL, GL_LESS, // stencil func 6, ~0); // ref, mask if (pass) pass = render_test(6, 0); reset_stencil_state(method); if (!pass) return false; // if front!=10, keep, else decr // if back<10, keep, else incr // final: front=6, back=1 pass = set_stencil_state(method, GL_DECR, GL_INCR, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_KEEP, GL_KEEP, // z pass GL_NOTEQUAL, GL_LESS, // stencil func 10, ~0); // ref, mask if (pass) pass = render_test(6, 1); reset_stencil_state(method); if (!pass) return false; if (method != ATI) { // if front!=10, keep, else decr // if back<10, keep, else incr // final: front=6, back=1 pass = set_stencil_state(method, GL_DECR, GL_INCR, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_REPLACE, GL_REPLACE, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 0xf6, 0xf1, // ref 0xff, 0xff, // mask 0x60, 0x10); // writeMask if (pass) pass = render_test(0x66, 0x11); reset_stencil_state(method); if (!pass) return false; } // reset write mask for clear set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_REPLACE, GL_REPLACE, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 0, 0, ~0, ~0, ~0, ~0); //============================================================ // Now begin tests with depth test glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set stencil buffer vals to 7, set Z values pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_REPLACE, GL_REPLACE, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 7, ~0); // ref, mask if (pass) pass = render_test(7, 7); reset_stencil_state(method); if (!pass) return false; // GL_LESS test should fail everywhere // decr front to 5, incr back to 2 pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_DECR, GL_INCR, // z fail GL_KEEP, GL_KEEP, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 99, ~0); // ref, mask if (pass) pass = render_test(6, 8); reset_stencil_state(method); if (!pass) return false; // set depth test = GL_EQUAL // Z test should pass everywhere // set front to 3 // decr back to 7 glDepthFunc(GL_EQUAL); pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_REPLACE, GL_DECR, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 3, ~0); // ref, mask if (pass) pass = render_test(3, 7); reset_stencil_state(method); if (!pass) return false; // incr front to 4 (by z pass), decr back to 6 (by stencil fail) pass = set_stencil_state(method, GL_DECR, GL_INCR, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_INCR, GL_DECR, // z pass GL_EQUAL, GL_NOTEQUAL, // stencil func 3, ~0); // ref, mask if (pass) pass = render_test(4, 6); reset_stencil_state(method); if (!pass) return false; //============================================================ // Disable depth test glDisable(GL_DEPTH_TEST); // test stencil value mask // only test bit 1 in stencil values // if !(front&0x2 == 15&0x2), decr to 3 (should happen) // if !(back&0x2 == 15&0x2), incr to 7 (should not happen) pass = set_stencil_state(method, GL_DECR, GL_INCR, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_KEEP, GL_KEEP, // z pass GL_EQUAL, GL_EQUAL, // stencil func 15, 0x2); // ref, mask if (pass) pass = render_test(3, 6); reset_stencil_state(method); if (!pass) return false; //============================================================ // Test common two-sided stencil modes for shadow volume rendering // Requires stencil +/- wrap feature. if (!have_stencil_wrap()) return true; glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); // "traditional / Z-pass" method: // front face: incr on zpass // back face: decr on zpass // both front and back Z-test should pass here pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_KEEP, GL_KEEP, // z fail GL_INCR_WRAP_EXT, GL_DECR_WRAP_EXT, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 0, ~0); // ref, mask if (pass) pass = render_test(1, stencilMax); reset_stencil_state(method); if (!pass) return false; // "Z-fail" method: // front face: decr on zfail // back face: incr on zfail // both front and back Z-test should fail here pass = set_stencil_state(method, GL_KEEP, GL_KEEP, // stencil fail GL_DECR_WRAP_EXT, GL_INCR_WRAP_EXT, // z fail GL_KEEP, GL_KEEP, // z pass GL_ALWAYS, GL_ALWAYS, // stencil func 0, ~0); // ref, mask if (pass) pass = render_test(0, 0); reset_stencil_state(method); if (!pass) return false; return true; }
int main(int argc, char ** argv) { m = import_object("teapot.3dt"); if(argc < 2) { return render_test(); } else return read_file(argv[1]); }