我如何:将曲面转换为纹理或使用某些多重采样参数创建纹理或使用alpha图层渲染曲面

时间:2011-03-23 22:48:09

标签: c++ directx direct3d alphablending surface

我正在创建两个渲染目标,两者都必须共享后缓冲区的深度缓冲区,因此我将它们设置为具有相同的多采样参数非常重要,但是pDevice-> CreateTexture(..)不提供任何参数用于设置多采样类型。所以我使用pDevice-> CreateRenderTarget(...)创建了两个渲染目标曲面,给出了与深度缓冲区相同的值,现在深度缓冲区与我的渲染目标一起工作,但是我无法在屏幕上正确渲染它们因为alpha混合不适用于 - > StretchRect(或者我被告知,当我尝试时它不起作用)。

所以这个问题的标题基本上都是我的问题,我该怎么做:         - 将表面转换为纹理或         - 使用某些多重采样参数创建纹理或         - 使用alpha图层正确渲染表面

2 个答案:

答案 0 :(得分:1)

StretchRect的文档具体说明了如何执行此操作:

  

使用StretchRect下采样a   多重样本Rendertarget

     

您可以使用StretchRect进行复制   一个rendertarget到另一个。如果   source rendertarget是多重采样的,   这会导致下采样   source rendertarget。比如你   可以:

     
      
  • 创建多重采样的rendertarget。
  •   
  • 创建第二个rendertarget   大小相同,不是多重采样。
  •   
  • 复制(使用StretchRect   多样本rendertarget到第二个   渲染目标。
  •   
     

注意使用   涉及使用的额外表面   StretchRect下采样a   将产生多重采样Rendertarget   在一次表演中。

答案 1 :(得分:1)

对旧问题的新回应,但我遇到了这个并认为我会提供一个答案,以防其他人碰到这个问题。这是我的包装器及其功能的精简版本的解决方案。

我有一个游戏,其中渲染器有几个图层,其中一个是几何图层。渲染时,它遍历所有图层,调用其Draw函数。每个图层都有自己的RenderTarget包装器实例。当图层绘制时,它“激活”其渲染目标,将缓冲区清除为alpha,绘制场景,然后“停用”其渲染目标。在所有图层都绘制到渲染目标后,所有这些渲染目标都会合并到后台缓冲区上以生成最终图像。

GeometryLayer ::绘制
*激活此图层使用的渲染目标
*设置所需的渲染状态
*清除缓冲区
*绘制几何体
*取消激活此图层使用的渲染目标

void GeometryLayer::Draw( const math::mat4& viewProjection )
{
    m_pRenderTarget->Activate();

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

    pDevice->Clear(0,0,D3DCLEAR_TARGET,m_clearColor,1.0,0);
    pDevice->BeginScene();
    pDevice->Clear(0,0,D3DCLEAR_ZBUFFER,0,1.0,0);

    for(auto it = m->visibleGeometry.begin(); it != m->visibleGeometry.end(); ++it)
        it->second->Draw(viewProjection);

    pDevice->EndScene();

    m_pRenderTarget->Deactivate();
}

我的RenderTarget包装器包含一个IDirect3DTexture9 *(m_pTexture),它与D3DXCreateTexture一起用于生成要绘制的纹理。它还包含一个由纹理给出的IDirect3DSurface9 *(m_pSurface)。它还包含另一个IDirect3DSurface9 *(m_pMSAASurface)。

在我的RenderTarget初始化中,有一个选项可以启用多重采样。如果关闭此选项,则m_pMSAASurface将初始化为nullptr。如果启用此选项,则使用IDirect3DDevice9 :: CreateRenderTarget函数为您创建m_pMSAASurface,将当前的多重采样设置指定为第4和第5个参数。

的RenderTarget ::初始化
*创建纹理
*从纹理中获取一个曲面(添加到曲面的引用计数)
*如果是MSAA,则创建启用msaa的表面

void    RenderTarget::Init(const int width,const int height,const bool enableMSAA)
{
    m_bEnableMSAA = enableMSAA;
    D3DXCreateTexture(pDevice,
        width,
        height,
        1,
        D3DUSAGE_RENDERTARGET,
        D3DFMT_A8R8G8B8,
        D3DPOOL_DEFAULT,
        &m_pTexture;
    );
    m_pTexture->GetSurfaceLevel(0,&m_pSurface);

    if(enableMSAA)
    {
        Renderer::GetInstance()->GetDevice()->CreateRenderTarget(
            width,
            height,
            D3DFMT_A8R8G8B8,
            d3dpp.MultiSampleType,
            d3dpp.MultiSampleQuality,
            false,
            &m_pMSAAsurface,
            NULL
        );
    }
}

如果此MSAA设置关闭,RenderTarget :: Activate会将m_pSurface设置为渲染目标。如果启用此MSAA设置,则RenderTarget :: Activate将m_pMSAASurface设置为渲染目标并启用多重采样渲染状态。

的RenderTarget ::激活
*存储当前渲染目标(添加到该曲面的引用计数)
*如果不是MSAA,则将surface设置为新的渲染目标
*如果MSAA将msaa surface设置为新的渲染目标,则启用msaa渲染状态

void    RenderTarget::Activate()
{
    pDevice->GetRenderTarget(0,&m_pOldSurface);

    if(!m_bEnableMSAA)
    {
        pDevice->SetRenderTarget(0,m_pSurface);
    }
    else
    {
        pDevice->SetRenderTarget(0,m_pMSAAsurface);
        pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,true);
    }
}

如果关闭此MSAA设置,RenderTarget :: Deactivate只会恢复原始渲染目标。如果启用此MSAA设置,RenderTarget :: Deactivate也会恢复原始渲染目标,但也会将m_pMSAASurface复制到m_pSurface上。

的RenderTarget ::停用
*如果是MSAA,则禁用MSAA渲染状态
*恢复上一个渲染目标
*删除前一个渲染目标的引用计数

void    RenderTarget::Deactivate()
{
    if(m_bEnableMSAA)
    {
        pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,false);
        pDevice->StretchRect(m_pMSAAsurface,NULL,m_pSurface,NULL,D3DTEXF_NONE);
    }
    pDevice->SetRenderTarget(0,m_pOldSurface);

    m_pOldSurface->Release();
    m->pOldSurface = nullptr;
}

当渲染器稍后向几何图层询问其RenderTarget纹理以便将其与其他图层组合时,该纹理将从其上的m_pMSAASurface复制图像。假设你正在使用一种促进alpha通道的格式,这个纹理可以与其他纹理混合,就像我正在使用多个图层的渲染目标一样。