http://www.cnblogs.com/ttthink/archive/2009/10/08/1579337.html
多视口渲染主要是改变了视口矩阵,一般我们的Shader程序没有直接处理这个视口矩阵,注意多视口渲染的顺序
void Render()
{
Clear()
GetViewport()保存原视口
BeginScene();
SetViewport(1);
DrawObject();
EndScene();
BeginScene();
SetViewport(2);
DrawObject();
EndScene();
SetViewport(&oldviewport);
Present( NULL, NULL, NULL, NULL );
}
上面任何一个步骤出错都会带来以外的结果。
1.除最后一个视口外全屏幕闪烁,这也是为什么要还原原视口的原因,如果我们不还原,那么下一次Clear()的是上次渲染的最后一个视口,因此我们的图像除了最后一个视口区域外全部闪烁。
2。全屏幕闪烁。(1.是否调用Clear(Target|Zbuffer),2.是否最后调用Present())
Present()是将我们的后备缓冲交换至前缓冲。而SetViewPort相当于在后备缓冲的某个指定区域绘图,因此我们的Present()是将包含多个视口的后缓冲交换出去。所以最后调用。我想也可以直接拷贝后缓冲第一个视口的图像到第二个视口吧。
void Render()
{
Clear()
GetViewport()保存原视口
BeginScene();
SetViewport(1);
DrawObject();
EndScene();
BeginScene();
SetViewport(2);
DrawObject();
EndScene();
SetViewport(&oldviewport);
Present( NULL, NULL, NULL, NULL );
}
上面任何一个步骤出错都会带来以外的结果。
1.除最后一个视口外全屏幕闪烁,这也是为什么要还原原视口的原因,如果我们不还原,那么下一次Clear()的是上次渲染的最后一个视口,因此我们的图像除了最后一个视口区域外全部闪烁。
2。全屏幕闪烁。(1.是否调用Clear(Target|Zbuffer),2.是否最后调用Present())
Present()是将我们的后备缓冲交换至前缓冲。而SetViewPort相当于在后备缓冲的某个指定区域绘图,因此我们的Present()是将包含多个视口的后缓冲交换出去。所以最后调用。我想也可以直接拷贝后缓冲第一个视口的图像到第二个视口吧。
====================================================================================
上面的似乎有点不对。看下面来自 Codesampler 的代码
From Codesampler:
void render( void )
{
D3DXMATRIX matView;
D3DXMATRIX matWorld;
D3DXMATRIX matRotation;
D3DXMATRIX matTranslation;
{
D3DXMATRIX matView;
D3DXMATRIX matWorld;
D3DXMATRIX matRotation;
D3DXMATRIX matTranslation;
//
// Render to the left viewport
//
// Render to the left viewport
//
D3DVIEWPORT9 leftViewPort;
leftViewPort.X = 0;
leftViewPort.Y = 0;
leftViewPort.Width = g_dwBackBufferWidth / 2;
leftViewPort.Height = g_dwBackBufferHeight;
leftViewPort.MinZ = 0.0f;
leftViewPort.MaxZ = 1.0f;
leftViewPort.Y = 0;
leftViewPort.Width = g_dwBackBufferWidth / 2;
leftViewPort.Height = g_dwBackBufferHeight;
leftViewPort.MinZ = 0.0f;
leftViewPort.MaxZ = 1.0f;
g_pd3dDevice->SetViewport( &leftViewPort );
// Now we can clear just view-port's portion of the buffer to red...
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_COLORVALUE( 1.0f, 0.0f, 0.0f, 1.0f ), 1.0f, 0 );
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_COLORVALUE( 1.0f, 0.0f, 0.0f, 1.0f ), 1.0f, 0 );
g_pd3dDevice->BeginScene();
{
// For the left view-port, leave the view at the origin...
D3DXMatrixIdentity( &matView );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
{
// For the left view-port, leave the view at the origin...
D3DXMatrixIdentity( &matView );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
// ... and use the world matrix to spin and translate the teapot
// out where we can see it...
D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, 5.0f );
matWorld = matRotation * matTranslation;
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// out where we can see it...
D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, 5.0f );
matWorld = matRotation * matTranslation;
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->SetMaterial( &g_teapotMtrl );
g_pTeapotMesh->DrawSubset(0);
}
g_pd3dDevice->EndScene();
//
// Render to the right viewport
//
g_pTeapotMesh->DrawSubset(0);
}
g_pd3dDevice->EndScene();
//
// Render to the right viewport
//
D3DVIEWPORT9 rightViewPort;
rightViewPort.X = g_dwBackBufferWidth / 2;
rightViewPort.Y = 0;
rightViewPort.Width = g_dwBackBufferWidth / 2;
rightViewPort.Height = g_dwBackBufferHeight;
rightViewPort.MinZ = 0.0f;
rightViewPort.MaxZ = 1.0f;
rightViewPort.Y = 0;
rightViewPort.Width = g_dwBackBufferWidth / 2;
rightViewPort.Height = g_dwBackBufferHeight;
rightViewPort.MinZ = 0.0f;
rightViewPort.MaxZ = 1.0f;
g_pd3dDevice->SetViewport( &rightViewPort );
// Now we can clear just view-port's portion of the buffer to green...
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_COLORVALUE( 0.0f, 1.0f, 0.0f, 1.0f ), 1.0f, 0 );
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_COLORVALUE( 0.0f, 1.0f, 0.0f, 1.0f ), 1.0f, 0 );
g_pd3dDevice->BeginScene();
{
// For the right view-port, translate and rotate the view around
// the teapot so we can see it...
D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, 5.0f );
matView = matRotation * matTranslation;
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
{
// For the right view-port, translate and rotate the view around
// the teapot so we can see it...
D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, 5.0f );
matView = matRotation * matTranslation;
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
// ... and don't bother with the world matrix at all.
D3DXMatrixIdentity( &matWorld );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
D3DXMatrixIdentity( &matWorld );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->SetMaterial( &g_teapotMtrl );
g_pTeapotMesh->DrawSubset(0);
}
g_pd3dDevice->EndScene();
g_pTeapotMesh->DrawSubset(0);
}
g_pd3dDevice->EndScene();
//
// We're done! Now, we just call Present()
//
// We're done! Now, we just call Present()
//
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
}