I've been looking at Frank D Luna's method of reflecting an object in a (planar) mirror.
I understand the code, and it works fine.
However, I tried to reflect another object (now reflecting two objects), and the second object when behnd the first object is been reflected in the mirror as if it's actually in-front of it. I know this is because the technique disables depth writes when drawing the reflected object (so the mirror doesn't obscure it).
So my question is, how can I adapt this technique to successfully reflect multiple objects?
The code that does the reflection of one object is below:
HR(gd3dDevice->SetRenderState(D3DRS_STENCILENABLE, true));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILREF, 0x1));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE));
// disable writes to the depth and back buffers
HR(gd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false));
HR(gd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true));
HR(gd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO));
HR(gd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE));
// Draw mirror to stencil only.
drawMirror();
// Re-enable depth writes
HR(gd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, true ));
// Only draw reflected teapot to the pixels where the mirror
// was drawn to.
HR(gd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL));
HR(gd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP));
// Build Reflection transformation.
D3DXMATRIX R;
D3DXPLANE plane(0.0f, 0.0f, 1.0f, 0.0f); // xy plane
D3DXMatrixReflect(&R, &plane);
// Save the original world matrices.
D3DXMATRIX oldTeapotWorld = mTeapotWorld;
// Add reflection transform.
mTeapotWorld = mTeapotWorld * R;
// Reflect light vector also.
D3DXVECTOR3 oldLightVecW = mLightVecW;
D3DXVec3TransformNormal(&mLightVecW, &mLightVecW, &R);
HR(mFX->SetValue(mhLightVecW, &mLightVecW, sizeof(D3DXVECTOR3)));
// Disable depth buffer and render the reflected teapot.
HR(gd3dDevice->SetRenderState(D3DRS_ZENABLE, false));
HR(gd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false));
// Finally, draw the reflected teapot
HR(gd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW));
drawTeapot();
mTeapotWorld = oldTeapotWorld;
mLightVecW = oldLightVecW;
// Restore render states.
HR(gd3dDevice->SetRenderState(D3DRS_ZENABLE, true));
HR(gd3dDevice->SetRenderState( D3DRS_STENCILENABLE, false));
HR(gd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW));
Thankyou for your time and patience.