1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
void RenderMirror()
{
// Turn depth buffer off, and stencil buffer on
g_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
g_pd3dDevice->SetRenderState( D3DRS_STENCILREF, 0x1 );
g_pd3dDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff );
g_pd3dDevice->SetRenderState( D3DRS_STENCILWRITEMASK,0xffffffff );
g_pd3dDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
g_pd3dDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
g_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE );
// Make sure no pixels are written to the z-buffer or frame buffer
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
// Draw the reflecting surface into the stencil buffer
g_pd3dDevice->SetTexture( 0, NULL);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matMirrorMatrix );
g_pd3dDevice->SetVertexShader( D3DFVF_MIRRORVERTEX );
g_pd3dDevice->SetStreamSource( 0, m_pMirrorVB, sizeof(MIRRORVERTEX) );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
// Save the view matrix
D3DXMATRIX matViewSaved;
g_pd3dDevice->GetTransform( D3DTS_VIEW, &matViewSaved );
// Reflect camera in X-Z plane mirror
D3DXMATRIX matView2, matReflect;
D3DXPLANE plane;
D3DXPlaneFromPointNormal( &plane, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0) );
D3DXMatrixReflect( &matReflect, &plane );
D3DXMatrixMultiply( &matView2, &matReflect, &matViewSaved );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView2 );
// Set a clip plane, so that only objects above the water are reflected
g_pd3dDevice->SetClipPlane( 0, plane );
g_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x01 );
// Setup render states to a blended render scene against mask in stencil
// buffer. An important step here is to reverse the cull-order of the
// polygons, since the view matrix is being relected.
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL );
g_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
// Clear the zbuffer (leave frame- and stencil-buffer intact)
g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER, 0L, 1.0f, 0L );
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
if (arbres_mesh[3].visible) Afficher_Mesh( arbres_mesh[3] );
// Restore render states
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
g_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
g_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x00 );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matViewSaved );
} |