思路:根据镜子的平面和茶壶的位置,计算出茶壶的映像,这时映像有的是在镜子的范围内,有的是在镜子以外的范围上显示。为了只在镜子的范围内显示茶壶,所以在深度缓存中把镜子范围内标记为0x1。然后在值设置为0x1的位置上绘制茶壶。
//1.启用模板缓存,并对相关的绘制状态进行设置
g_d3dDevice->SetRenderState(D3DRS_STENCILENABLE, true); //启用模板缓存
g_d3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); //设置模板测试总会成功
g_d3dDevice->SetRenderState(D3DRS_STENCILREF, 0x1); //修改模板参考值,默认为
g_d3dDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); //模板掩码
g_d3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
g_d3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); //如果深度测试失败不对模板缓存中的值进行更新
g_d3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); //如果模板测试失败不对模板缓存中的值进行更新
g_d3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);//如果深度测试和模板测试均通过了则用模板参考值(x1)代替模板缓存中的对应值
//2绘制镜面,只绘制到模板缓存中
g_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); //阻止深度缓存进行写操作
g_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
g_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
//在模板缓存中绘制镜子
g_d3dDevice->SetStreamSource(0, VB, 0, sizeof(Vertex));
g_d3dDevice->SetFVF(VertexFVF);
g_d3dDevice->SetMaterial(&MirrorMtrl);
g_d3dDevice->SetTexture(0, TexMirror);
D3DXMATRIX I;
D3DXMatrixIdentity(&I);
g_d3dDevice->SetTransform(D3DTS_WORLD, &I);
g_d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2);
g_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
//3.画茶壶镜像
g_d3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
g_d3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
//4.计算场景中为了物体的映像进行定位的映像变换矩阵
//镜像的位置
D3DXMATRIX W, T, R;
D3DXPLANE plane(0.0f, 0.0f, 1.0f, 0.0f); //xy平面
D3DXMatrixReflect(&R, &plane);
D3DXMatrixTranslation(&T, TeapotPosition.x, TeapotPosition.y, TeapotPosition.z);
W = T * R;
//5.绘制茶壶的镜像(使显示的映像逼真)
//清楚深度缓存,融合反射的茶壶到镜子中
g_d3dDevice->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
g_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
g_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
//最终绘制反射茶壶到镜子中
g_d3dDevice->SetTransform(D3DTS_WORLD, &W);
g_d3dDevice->SetMaterial(&TeapotMtrl);
g_d3dDevice->SetTexture(0, 0);
g_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
TeaPot->DrawSubset(0);
//回复Render设置
g_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
g_d3dDevice->SetRenderState(D3DRS_STENCILENABLE, false);
g_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
浙公网安备 33010602011771号