龙书第八章理解

//《第一部分》

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);


开启模板测试,模板测试是费时间的操作,没有必要的时候不要开启,开启后记得要关闭。

设置测试选项。


//end


//《第二部分》
// 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->SetFVF(Vertex::FVF);
Device->SetMaterial(&MirrorMtrl);
Device->SetTexture(0, MirrorTex);
D3DXMATRIX I;
D3DXMatrixIdentity(&I);
Device->SetTransform(D3DTS_WORLD, &I);

Device->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2);


该部分是禁止深度可写,阻止后台缓存更新,在模板缓存中标记镜面大小。表面上是往模板缓存上绘制镜面,实际是在模板缓存中标记哪个区域是下一步操作中指定的可视镜面区域。因为在该部绘制了镜面,那么在D3D内部实际是进行中模板测试。因为第一部分的设置项,绘制完和测试完后,模板缓存得到的是一块1的像素块。为啥在这一步模板测试通过了,绘制的壶没有出现在镜面上。原因就是下面的代码控制了,根据融合,当前绘制的像素是属于源像素,已绘制的像素(后台缓存中保留的像素)属于目的像素,在下面的设置就是忽略了源像素的绘制,直接保留了目的像素。实际上可以把前面先绘制的镜面去掉,同时在这里去掉融合操作,在该处统一绘制,减少了一次镜面绘制,提升效率。

Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
    Device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ZERO);
    Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

//


//《第三部分》

// re-enable depth writes
//恢复深度缓存可写,不恢复的话 下一次绘制的时候遮挡效果无法表现
Device->SetRenderState( D3DRS_ZWRITEENABLE, true );


// only draw reflected teapot to the pixels where the mirror
// was drawn to.
Device->SetRenderState(D3DRS_STENCILFUNC,  D3DCMP_EQUAL);

    Device->SetRenderState(D3DRS_STENCILPASS,  D3DSTENCILOP_KEEP);


模板测试,判断指定符合区域的才把茶壶绘到镜面

//end



//《第四部分》

// position 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;


// clear depth buffer and blend the reflected teapot with the mirror
Device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
Device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_DESTCOLOR);
    Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);


// Finally, 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);

// Restore render states.
Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
Device->SetRenderState( D3DRS_STENCILENABLE, false);

Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

//end

这里不明白为啥要特别处理背影消除,正常的情况下不是应该在镜子中绘制物品的背面吗,而物品的背面应该是没有光线,从而导致有暗影



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值