Windows Direct3D Intro - Multiple Viewport Render

来源:互联网 发布:淘宝上买psv破解版 编辑:程序博客网 时间:2024/06/16 08:59


http://www.cnblogs.com/ttthink/archive/2009/10/08/1579337.html


Direct3D多视口渲染

多视口渲染主要是改变了视口矩阵,一般我们的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()是将包含多个视口的后缓冲交换出去。所以最后调用。我想也可以直接拷贝后缓冲第一个视口的图像到第二个视口吧。


====================================================================================
上面的似乎有点不对。看下面来自 Codesampler 的代码

From Codesampler:

void render( void )
{
    D3DXMATRIX matView;
    D3DXMATRIX matWorld;
    D3DXMATRIX matRotation;
    D3DXMATRIX matTranslation;

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

    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->BeginScene();
    {
        // 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 );

        g_pd3dDevice->SetMaterial( &g_teapotMtrl );
        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;

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

        // ... and don't bother with the world matrix at all.
        D3DXMatrixIdentity( &matWorld );
        g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

        g_pd3dDevice->SetMaterial( &g_teapotMtrl );
        g_pTeapotMesh->DrawSubset(0);
    }
    g_pd3dDevice->EndScene();

    //
    // We're done! Now, we just call Present()
    //

    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

0 0