我正在尝试使用纹理在两个不同的应用程序之间共享渲染表面。一切似乎都能正常工作,除了在对共享纹理进行采样时,我才会收到黑色。
1)首先,我创建了一个共享纹理,如下所示:http://msdn.microsoft.com/en-us/library/windows/desktop/ee913554(v=vs.85).aspx。源应用程序成功为目标应用程序提供了共享资源的句柄,打开了资源并愉快地创建了资源视图。
(src Application)
D3D11_TEXTURE2D_DESC SharedTextureDesc = TextureDesc;
SharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
SharedTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
hResult = pD3D11Device->CreateTexture2D(&SharedTextureDesc, NULL, &m_pSharedRenderBuffer);
(dstApplication)
HANDLE hSharedRenderHandle = pDisplayCallback->GetSharedRenderBuffer();
hr = pDevice->OpenSharedResource( hSharedRenderHandle,__uuidof(ID3D11Texture2D), (LPVOID*) &m_pSharedRenderTexture);
pDevice->CreateShaderResourceView(m_pSharedRenderTexture, NULL, &m_RenderTextureView);
// Create the sample state
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory( &sampDesc, sizeof(sampDesc) );
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = -FLT_MAX;
sampDesc.MaxLOD = FLT_MAX;
hr = pDevice->CreateSamplerState( &sampDesc, &m_TexSamplerState );
2)在Source应用程序渲染结束时,我将后缓冲区复制到共享渲染纹理。
(acquireSync)
pDeviceContext->CopyResource(pContext->m_pSharedRenderBuffer, pContext->m_pBackBuffer);
(releaseSync)
3)在目标渲染过程中,在某一点上,我使用原始渲染的内容渲染出一个全屏四边形。
// Set the sampler state in the pixel shader.
pContext->PSSetSamplers(0, 1, &m_TexSamplerState);
pContext->PSSetShaderResources(0, 1, &m_RenderTextureView);
4)VS着色器创建全屏四边形,PS着色器根据纹理值设置颜色
VS(此处描述:http://www.altdevblogaday.com/2011/08/08/interesting-vertex-shader-trick/)
VS_Output Output;
Output.Tex = float2((id << 1) & 2, id & 2);
Output.Pos = float4(Output.Tex * float2(2,-2) + float2(-1,1), 0, 1);
return Output;
PS(用于调试我将屏幕的一部分设置为UV,其余设置为纹理)
float4 DiffuseColor = float4(vsIn.Tex.x, vsIn.Tex.y, 0, 1);
if (vsIn.Tex.x > 0.5 || vsIn.Tex.y < 0.5)
DiffuseColor = g_RenderBuffer.Sample(g_Sampler, vsIn.Tex);
return DiffuseColor;
理论上,这就是我所需要的。然而,事情变得奇怪。
渲染正确进行,全屏幕根据PixelShader的输出进行渲染。
我的紫外线是正确的,因为渲染它们可以提供你所期望的效果。
我尝试从磁盘加载纹理并直接渲染它。这很好用。
我已经尝试将我的共享缓冲区写入磁盘,以确保我收到的内容设置了一些值 - 这也有效。
我尝试比较共享纹理/视图与基于工作磁盘的纹理/视图的描述,它们看起来很相似。我只能看到差异是共享纹理上缺少miplevels,这很好,我不想要mip级别,共享纹理格式匹配源缓冲区渲染表面:DXGI_FORMAT_R8G8B8A8_UNORM_SRGB(加载纹理是BC3_UNORM)
同步似乎很好,或者至少在我几天前第一次尝试这个时,D3D发出警告说资源没有同步,我解决了这个问题。
根据一切,一切正常,根据D3D,纹理是黑色的!
有什么想法?我不是一个图形程序员,所以到目前为止调试这个问题已经非常有趣了!最后一点 - 我无法附加Pix或使用VS2012 gfx调试,因为它在应用启动时崩溃。