您的位置:首页 > 其它

利用模板缓存绘制镜面效果

2011-03-11 00:42 309 查看
思路:根据镜子的平面和茶壶的位置,计算出茶壶的映像,这时映像有的是在镜子的范围内,有的是在镜子以外的范围上显示。为了只在镜子的范围内显示茶壶,所以在深度缓存中把镜子范围内标记为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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: