我正在从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;
}
正确渲染图像,但如果父颜色的背景颜色不是黑色,则它们似乎是不透明的。
现在我似乎无法弄清楚这里到底发生了什么,这使我的纹理变得透明。
非常感谢任何有关此事的帮助。