Beispiel #1
0
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;
}
Beispiel #2
0
int main(int argc, char ** argv) {
    m = import_object("teapot.3dt");
    if(argc < 2) {
        return render_test();
    } else return read_file(argv[1]);
}