0

我是DirectX10的新手。现在我正在开发一个 Direct10 应用程序。它混合了两个根据用户输入手动填充的纹理。当前的实现是

  1. 使用 D3D10_USAGE_STAGING 创建两个空纹理。
  2. 创建两个资源着色器视图以绑定到像素着色器,因为着色器需要它。
  3. 通过调用 CopyResource 将纹理复制到 GPU 内存。

现在的问题是我只能看到第一个纹理,但看不到第二个。在我看来,绑定不适用于第二个纹理。

我不知道它有什么问题。这里的任何人都可以告诉我吗?

谢谢,马歇尔

COverlayTexture 类负责创建纹理、创建资源视图、使用来自另一个应用程序的映射位图填充纹理并将资源视图绑定到像素着色器。

HRESULT COverlayTexture::Initialize(VOID)
{
D3D10_TEXTURE2D_DESC texDesStaging;
texDesStaging.Width = m_width;
texDesStaging.Height = m_height;
texDesStaging.Usage = D3D10_USAGE_STAGING;
texDesStaging.BindFlags = 0;
texDesStaging.ArraySize = 1;
texDesStaging.MipLevels = 1;
texDesStaging.SampleDesc.Count = 1;
texDesStaging.SampleDesc.Quality = 0;
texDesStaging.MiscFlags = 0;
texDesStaging.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texDesStaging.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;  
HR( m_Device->CreateTexture2D( &texDesStaging, NULL, &m_pStagingResource ) );

D3D10_TEXTURE2D_DESC texDesShader;
texDesShader.Width = m_width;
texDesShader.Height = m_height;
texDesShader.BindFlags = D3D10_BIND_SHADER_RESOURCE;
texDesShader.ArraySize = 1;
texDesShader.MipLevels = 1;
texDesShader.SampleDesc.Count = 1;
texDesShader.SampleDesc.Quality = 0;
texDesShader.MiscFlags = 0;    
texDesShader.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texDesShader.Usage = D3D10_USAGE_DEFAULT;    
texDesShader.CPUAccessFlags = 0;
HR( m_Device->CreateTexture2D( &texDesShader, NULL, &m_pShaderResource ) );

D3D10_SHADER_RESOURCE_VIEW_DESC viewDesc;
ZeroMemory( &viewDesc, sizeof( viewDesc ) );
viewDesc.Format = texDesShader.Format;
viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
viewDesc.Texture2D.MipLevels = texDesShader.MipLevels;
HR( m_Device->CreateShaderResourceView( m_pShaderResource, &viewDesc, &m_pShaderResourceView ) );
}

HRESULT COverlayTexture::Render(VOID)
{
m_Device->PSSetShaderResources(0, 1, m_pShaderResourceView);

D3D10_MAPPED_TEXTURE2D lockedRect;
m_pStagingResource->Map( 0, D3D10_MAP_WRITE, 0, &lockedRect );

// Fill in the texture with the bitmap mapped from shared memory view

m_pStagingResource->Unmap(0);

m_Device->CopyResource(m_pShaderResource, m_pStagingResource); 
} 

我使用 COverlayTexture 类的两个实例,每个实例分别将自己的位图填充到其纹理中,并使用序列 COverlayTexture[1] 然后 COverlayTexture[0] 进行渲染。

COverlayTexture* pOverlayTexture[2];

for( int i = 1; i < 0; i++)
{
     pOverlayTexture[i]->Render()
}

FX 文件中的混合状态设置定义如下:

BlendState AlphaBlend
{
AlphaToCoverageEnable = FALSE;
BlendEnable[0] = TRUE;
      SrcBlend = SRC_ALPHA;
      DestBlend = INV_SRC_ALPHA;
      BlendOp = ADD;
      BlendOpAlpha = ADD;
      SrcBlendAlpha = ONE;
DestBlendAlpha = ZERO;
RenderTargetWriteMask[0] = 0x0f;
};

FX 文件中的像素着色器定义如下:

Texture2D txDiffuse;
float4 PS(PS_INPUT input) : SV_Target
{
float4 ret = txDiffuse.Sample(samLinear, input.Tex);
return ret;
}

再次感谢。

为保罗编辑:

非常感谢,保罗。问题是对象的哪个实例应该绑定到 alpha 纹理或漫反射纹理。作为测试,我将 COverlayTexture[0] 绑定到 alpha 并将 COverlayTexture[1] 绑定到漫反射纹理。

Texture2D txDiffuse[2];
float4 PS(PS_INPUT input) : SV_Target
{
float4 ret = txDiffuse[1].Sample(samLinear, input.Tex);
float alpha = txDiffuse[0].Sample(samLinear, input.Tex).x;

return float4(ret.xyz, alpha);
} 

我为这两个资源视图调用了 PSSetShaderResources。

g_pShaderResourceViews[0] = overlay[0].m_pShaderResourceView;
g_pShaderResourceViews[1] = overlay[1].m_pShaderResourceView;
m_Device->PSSetShaderResources(0, 2, g_pShaderResourceViews);

结果是我什么都看不到。我还尝试了通道 x,y,z,w。

4

1 回答 1

0

再贴一些代码。

我不确定你的意思是如何混合这两种纹理。如果您想在像素着色器中混合它们,您需要对它们进行采样,然后将它们(或您需要的任何操作)添加在一起。

你如何将纹理添加在一起?通过设置 ID3D11BlendState 或在像素着色器中?

编辑:

你不需要在每个类中使用两个纹理:如果你想写入你的纹理,你的使用应该是 D3D10_USAGE_DYNAMIC。执行此操作时,您还可以将此纹理作为着色器资源,因此您无需执行此m_Device->CopyResource(m_pShaderResource, m_pStagingResource);步骤。

由于您使用的是 alpha 混合,因此您必须控制像素着色器中的 alpha 值输出(像素着色器返回的 float4 的 w 分量)。

将两个纹理绑定到您的像素着色器并使用一个纹理值作为 alpha 分量:

Texture2D txDiffuse;
Texture2D txAlpha;
float4 PS(PS_INPUT input) : SV_Target
{
    float4 ret = txDiffuse.Sample(samLinear, input.Tex);
    float alpha=txAlpha.Sample(samLinear,input.Tex).x; // Choose the proper channel
    return float4(ret.xyz,alpha); // Alpha is the 4th component
}
于 2011-07-22T15:02:00.820 回答