渲染纹理在DirectX 11中是透明的

时间:2015-10-16 13:00:13

标签: wpf directx-11 sharpdx d3dimage

我正在从IP摄像机渲染H264视频帧,通过DirectX 11和WPD中的SharpDx通过D3DImage控制解码为BGRA32像素格式。

经过大量研究并查看各种样本和示例后,我设法得到它最终得到它render H264 frames with DirectX 11

我目前的设置包括设置顶点着色器和像素着色器,如下所示:

var device = this.Device;
var context = device.ImmediateContext;

// Compile Vertex and Pixel shaders
vertexShaderByteCode = ShaderBytecode.CompileFromFile("TriangleShader.fx", "VSMain", "vs_5_0", ShaderFlags.Debug, EffectFlags.None);
vertexShader = new VertexShader(device, vertexShaderByteCode);
pixelShaderByteCode = ShaderBytecode.CompileFromFile("TriangleShader.fx", "PSMain", "ps_5_0", ShaderFlags.Debug, EffectFlags.None);
pixelShader = new PixelShader(device, pixelShaderByteCode);

// Layout from VertexShader input signature
// An input layout is the layout of the data containing the location and properties of a vertex. It would be a format of data that you can modify and set according
layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] {
          new InputElement("SV_Position", 0, Format.R32G32B32A32_Float, 0, 0),
          new InputElement("COLOR", 0, Format.R32G32_Float, 16, 0),
          new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0),
        });

// Write vertex data to a datastream
var stream = new DataStream(Utilities.SizeOf<Vertex>() * 6, true, true);

int iWidth = (int)this.ActualWidth;
int iHeight = (int)this.ActualHeight;

float top = iWidth / 2;
float bottom = iHeight / 2;

stream.WriteRange(new[]
                             {
   new Vertex(
               new Vector4(-top, bottom, 0.5f, 0.0f), // position top-center
               new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color top-center (r,g,b,alpha)
               new Vector2(0f,0f)),
    new Vertex(
               new Vector4(top, bottom, 0.5f, 0.0f), // position top-right
               new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color top-right (r,g,b,alpha)
               new Vector2(iWidth,iHeight)),
    new Vertex(
               new Vector4(-top, -bottom, 0.5f, 0.0f), // position bottom-left
               new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color bottom-left (r,g,b,alpha)
               new Vector2(iWidth,iHeight)),
    new Vertex( 
                new Vector4(-top, -bottom, 0.5f, 0.0f), // position bottom-right
                new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color bottom-left (r,g,b,alpha)
                new Vector2(iWidth,0f)),
        new Vertex(
                new Vector4(top, -bottom, 0.5f, 0.0f), // position bottom-right
                new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color bottom-right (r,g,b,alpha)
                new Vector2(iWidth,iHeight)),
        new Vertex(
                new Vector4(top, bottom, 0.5f, 0.0f), // position top-right
                new Color4(0.0f, 0.0f, 0.0f, 0.0f), // color top-right (r,g,b,alpha)
                new Vector2(0f, iHeight)),
        });

        stream.Position = 0;

        // Instantiate Vertex buiffer from vertex data
        // 
        vertices = new SharpDX.Direct3D11.Buffer(device, stream, new BufferDescription()
        {
            BindFlags = BindFlags.VertexBuffer,
            CpuAccessFlags = CpuAccessFlags.None,
            OptionFlags = ResourceOptionFlags.None,
            SizeInBytes = Utilities.SizeOf<Vertex>() * 6,
            Usage = ResourceUsage.Default,
            StructureByteStride = 0
        });
        stream.Dispose();

        // Prepare All the stages
        context.InputAssembler.InputLayout = (layout);
        context.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleStrip);
        context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vertex>(), 0));
        context.VertexShader.Set(vertexShader);
        context.PixelShader.Set(pixelShader);
        context.OutputMerger.SetTargets(m_RenderTargetView);

当我收到一个新帧时,我通过映射资源更新RenderTexture,如下所示:

device.ImmediateContext.ClearRenderTargetView(this.m_RenderTargetView, Color4.Black);

        Texture2DDescription colordesc = new Texture2DDescription
        {
            BindFlags = BindFlags.ShaderResource,
            Format = m_PixelFormat,
            Width = iWidth,
            Height = iHeight,
            MipLevels = 1,
            SampleDescription = new SampleDescription(1, 0),
            Usage = ResourceUsage.Dynamic,
            OptionFlags = ResourceOptionFlags.None,
            CpuAccessFlags = CpuAccessFlags.Write,
            ArraySize = 1
        };

        Texture2D newFrameTexture = new Texture2D(this.Device, colordesc);

        DataStream dtStream = null;
        DataBox dBox = Device.ImmediateContext.MapSubresource(newFrameTexture, 0, MapMode.WriteDiscard, 0, out dtStream);
        if (dtStream != null)
        {
            int iRowPitch = dBox.RowPitch;

            for (int iHeightIndex = 0; iHeightIndex < iHeight; iHeightIndex++)
            {
                //Copy the image bytes to Texture
                // we write row strides multiplies by bytes per pixel
                // as our case is bgra32 which is 4 bytes 
                dtStream.Position = iHeightIndex * iRowPitch;
                Marshal.Copy(decodedData, iHeightIndex * iWidth * 4, new IntPtr(dtStream.DataPointer.ToInt64() + iHeightIndex * iRowPitch), iWidth * 4);
            }
        }

        Device.ImmediateContext.UnmapSubresource(newFrameTexture, 0);

        Texture2D srcTexture = m_RenderTargetView.ResourceAs<Texture2D>();
        Device.ImmediateContext.CopySubresourceRegion(newFrameTexture, 0, null, this.RenderTarget, 0);

        Device.ImmediateContext.Draw(6, 0);
        Device.ImmediateContext.Flush();
        this.D3DSurface.InvalidateD3DImage();

        Disposer.SafeDispose(ref newFrameTexture);

我的效果/ HLSL文件:

Texture2D ShaderTexture : register(t0);
SamplerState Sampler : register(s0);

cbuffer PerObject: register(b0)
{
    float4x4 WorldViewProj;
};
struct VertexShaderInput
{
    float4 Position : SV_Position;
    float4 Color : COLOR;
    float2 TextureUV : TEXCOORD0;
};
struct VertexShaderOutput
{
    float4 Position : SV_Position;
    float4 Color : COLOR;
    float2 TextureUV : TEXCOORD0;
};

VertexShaderOutput VSMain(VertexShaderInput input)
{
    VertexShaderOutput output = (VertexShaderOutput)0;

output.Position = mul(input.Position, WorldViewProj);
output.Color = mul(input.Color, WorldViewProj);
output.TextureUV = input.TextureUV;

return output;
}

float4 PSMain(VertexShaderOutput input) : SV_Target
{
    return ShaderTexture.Sample(Sampler, input.TextureUV).rgb;
}

正确渲染图像,但如果父颜色的背景颜色不是黑色,则它们似乎是不透明的。

现在我似乎无法弄清楚这里到底发生了什么,这使我的纹理变得透明。

当父网格控件的背景为考拉图片时,我也尝试渲染,如下所示: enter image description here

非常感谢任何有关此事的帮助。

0 个答案:

没有答案