您的位置:首页 > 其它

平面剪切(clip mirror )-----做一个镜面效果

2005-03-22 17:09 811 查看
使用平面剪切功能,我们可以屏蔽一些我们不想看到的东西,它就像一块挡光板,挡住了我们的视线.这样我们就可以创建一个镜子。
一、首先我们必需先构造一个平面。在3D中,我们有两种方法来构造一个平面
1、通过平面上的一个点和这个平面的法线,我们就可以确定一个平面。
D3DXVECTOR3 vPosition, vNormal;
D3DXPLANE plane;
D3DXPlaneFromPointNormal( &plane, vPosition, vNormal );
2、通过平面上的任意三点,也可以确定一个平面
D3DXVECTOR3 v1, v2, v3;
D3DXPLANE plane;
D3DXPlaneFromPoints( &plane, &v1, &v2, &v3 );
二、在确定平面之后,我们就要得到相对于这个平面的世界变换,并改变当前世界变换。当然我们得保存现有的世界变换,好在使用完平面之后恢复世界变换。
D3DXMATRIX matSaveWorld , matReflectMirror;
pd3dDevice->GetTransfrom( D3DTS_WORLD, &matSaveWorld );
D3DXMatrixReflect( &matReflectMirror, &plane );
pd3dDevice->SetTransfrom( D3DTS_WORLD, &matReflectMirror );
三、设置D3DRS_CULLMODE 为反面模式 D3DCULL_CW,
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
四、设置平面剪切方法
pd3dDevice->SetClipPlane( 0, &plane ); // 当要从多面剪切时,设置多个。
                  // 然后在后面的渲染状态里面加以设置
pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0 /*| D3DCLIPPLANE1*/ );
// 在上面的函数里面,当要设置多个剪切平面时,可以给第二个参数传多个
// D3DCLIPPLANE0 | D3DCLIPPLANE1| D3DCLIPPLANE2| D3DCLIPPLANE3
五、画出要看到的东西(即是把其渲染到剪切中)
RenderScene();
六、把刚刚渲染的输出
pd3dDevice->SetTransform( D3DTS_WORLD, &matSaveWorld );
pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x00); // 清除平面剪切
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ) ;
pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

// 在这里渲染出刚刚经过平面剪切后的内容
RenderClip();
pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

D3D中的代码示例
RenderMirror()
{
D3DXMATRIXA16 matWorldSaved;
D3DXMATRIXA16 matReflectInMirror;
D3DXPLANE plane;
// Save the world matrix so it can be restored
m_pd3dDevice->GetTransform( D3DTS_WORLD, &matWorldSaved );
// Get the four corners of the mirror. (This should be dynamic rather than
// hardcoded.)
D3DXVECTOR3 a(-1.5f, 1.5f, 3.0f );
D3DXVECTOR3 b( 1.5f, 1.5f, 3.0f );
D3DXVECTOR3 c( -1.5f,-1.5f, 3.0f );
D3DXVECTOR3 d( 1.5f,-1.5f, 3.0f );
// Construct the reflection matrix
D3DXPlaneFromPoints( &plane, &a, &b, &c );
D3DXMatrixReflect( &matReflectInMirror, &plane );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matReflectInMirror );
// Reverse the cull mode (since normals will be reflected)
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
// Set the custom clip planes (so geometry is clipped by mirror edges).
// This is the heart of this sample. The mirror has 4 edges, so there are
// 4 clip planes, each defined by two mirror vertices and the eye point.
m_pd3dDevice->SetClipPlane( 0, *D3DXPlaneFromPoints( &plane, &b, &a, &m_vEyePt ) );
m_pd3dDevice->SetClipPlane( 1, *D3DXPlaneFromPoints( &plane, &d, &b, &m_vEyePt ) );
m_pd3dDevice->SetClipPlane( 2, *D3DXPlaneFromPoints( &plane, &c, &d, &m_vEyePt ) );
m_pd3dDevice->SetClipPlane( 3, *D3DXPlaneFromPoints( &plane, &a, &c, &m_vEyePt ) );
m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE,
D3DCLIPPLANE0 | D3DCLIPPLANE1 | D3DCLIPPLANE2 | D3DCLIPPLANE3 );
// Render the scene
RenderScene();
// Restore the modified render states
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorldSaved );
m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x00 );
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
// Finally, render the mirror itself (as an alpha-blended quad)
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
m_pd3dDevice->SetStreamSource( 0, m_pMirrorVB, 0, sizeof(MIRRORVERTEX) );
m_pd3dDevice->SetFVF( MIRRORVERTEX::FVF );
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: