Skip to main content
GameDev.net gamedev.net
🔒 Locked

Stencil Buffer not drawing?

Started by combatc2 Jul 13, 2006 at 8:33 PM 1 replies 1k views
Original Post
combatc2
combatc2
I am trying to draw a reflection of a teapot in my program. The teapot shows, as does the mirror I'm trying to reflect it in. The program exits with no errors, but yet the teapot still doesn't reflect Here's my RenderMirror() function which has all the stencil buffer operations in it .. if there's any errors in it I would greatly appreciate it if someone would help me find 'em .. thanks!


void RenderMirror() {
	Device->SetRenderState(D3DRS_STENCILENABLE, true);
	Device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
	Device->SetRenderState(D3DRS_STENCILREF, 0x1);
	Device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
	Device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
	Device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
	Device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
	Device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
	
	// Disable writes to the depth and back buffers
	Device->SetRenderState(D3DRS_ZWRITEENABLE, false);
	Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
	Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
	
	// Draw the mirror to the stencil buffer
	Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
	Device->SetIndices(IB);
	Device->SetFVF(FVF_VERTEX);
	Device->SetMaterial(&mirrorMtrl);
	Device->SetTexture(0, mirrorTex);
	
	D3DXMATRIX I;
	D3DXMatrixIdentity(&I);
	Device->SetTransform(D3DTS_WORLD, &I);
	Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 6, 2);

	// Re-enable depth writes
	Device->SetRenderState(D3DRS_ZWRITEENABLE, true);

	Device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
	Device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);

	// Position the reflection
	D3DXMATRIX W, T, R;
	D3DXPLANE plane(0.0f, 0.0f, 1.0f, 0.0f); // XY plane
	D3DXMatrixReflect(&R, &plane);

	D3DXMatrixTranslation(&T, TeapotPosition.x, TeapotPosition.y, TeapotPosition.z);

	W = T*R;

	Device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);

	// Now in order to make the teapot look like it's in the mirror:
	// We must blend the teapot's reflection into the mirror texture
	Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
	Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);

	// Finally, we're ready to draw the reflected teapot
	Device->SetTransform(D3DTS_WORLD, &W);
	Device->SetMaterial(&teapotMtrl);
	Device->SetTexture(0, 0);
	Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
	Teapot->DrawSubset(0);

	// Disable blending and restore the usual cull mode
	Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
	Device->SetRenderState(D3DRS_STENCILENABLE, false);
	Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}

.. Oh, and my coordinates for the mirror are (if it matters):

v[4] = Vertex(11.0f, 6.0f, 2.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
	v[5] = Vertex(11.0f, 0.0f, 2.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
	v[6] = Vertex(6.0f, 0.0f, 2.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
	v[7] = Vertex(6.0f, 6.0f, 2.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);

Thanks again, Carl
S1CA
S1CA
The stencil setup looks ok to me. A couple of questions:

- Which depth/stencil format are you using? and does your hardware definitely support it? (i.e. you might be getting 0 bits of usable stencil that are always set to 0).

- Do you ever Clear() the stencil buffer? It's worth doing at least once when your app starts so you know for certain what values are in there.


To rule out the drawing, I'd first test that the mirror, and reflected teapot are rendering in the correct places by removing all the stencil and alpha blend stuff.
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site
combatc2
combatc2
For the depth buffer I have the format as: d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

If that fails, it tries again to make a 16-bit depth buffer instead (D3DFMT_D16).

I couldn't find a separate declaration for the stencil buffer that's to be used in my code.

I clear the stencil buffer as well as the back buffer(right?) and that's when I setup the geometry and such with RenderScene(), and then I call RenderMirror() for the reflection.
                Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0xff000000, 1.0f, 0L);		Device->BeginScene();		RenderScene();                RenderMirror();                                Device->EndScene();


My geometry and my teapot are all floating in the right place in the "world", just the teapot won't reflect. I tried removing blending to see if maybe it was "hiding" the teapot, but I had the same effect so I think it's not being drawn at all.

Thanks again,
Carl

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.