我試圖使用Direct3D11來執行一些圖像扭曲非常快,根據this previous question,但似乎無法讓所有的東西一起工作。DirectX - 渲染四個WicBitmapRenderTarget(SharpDX)
當我嘗試將DXGI表面讀入Direct2D位圖時,出現故障。
var renderSurface = renderTexture.QueryInterface<SharpDX.DXGI.Surface>();
var props = new BitmapProperties
{
PixelFormat = new SharpDX.Direct2D1.PixelFormat(
Format.B8G8R8A8_UNorm,
AlphaMode.Premultiplied
)
};
// This throws "No such interface supported"
var direct2DBitmap =
new SharpDX.Direct2D1.Bitmap(_bitmapRenderTarget, renderSurface, props);
我也試圖讀取直接使用Map
法在表面,但在此之前我甚至嘗試用數據做任何事情,失敗:
var renderSurface = renderTexture.QueryInterface<SharpDX.DXGI.Surface>();
// This throws "The parameter is incorrect."
renderSurface.Map(MapFlags.Read);
更完整的代碼如下。此外,如果這裏有什麼與這項工作無關的話......我全都是耳朵。我不是一個真正的3D人,只是想解決一個沒有簡單的Direct2D解決方案的特定問題。
public void AddImage(BitmapSource bitmapSource, SharpDX.Vector2[] abcd)
{
Device device;
Texture2D renderTexture = null;
device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport);
renderTexture = new Texture2D(device, new Texture2DDescription
{
Width = _size.Width,
Height = _size.Height,
Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
MipLevels = 1,
ArraySize = 1,
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
Usage = ResourceUsage.Default,
});
var renderView = new RenderTargetView(device, renderTexture);
//
// Load the input bitmap as a texture
//
var texture = CreateTexture2DFromBitmap(device, bitmapSource);
var textureView = new ShaderResourceView(device, texture);
var sampler = new SamplerState(device, new SamplerStateDescription()
{
Filter = Filter.MinMagMipLinear,
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Never,
MaximumAnisotropy = 16,
MipLodBias = 0,
MinimumLod = 0,
MaximumLod = 16,
});
//
// Setup the scene
// These shaders are from the MiniCubeTexture sample for SharpDX
//
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "VS", "vs_4_0");
var vertexShader = new VertexShader(device, vertexShaderByteCode);
var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "PS", "ps_4_0");
var pixelShader = new PixelShader(device, pixelShaderByteCode);
var layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] {
new InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 0, 0),
new InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 16, 0),
});
var vertices = SharpDX.Direct3D11.Buffer.Create(device, BindFlags.VertexBuffer, new[] {
// 3D coordinates UV Texture coordinates
abcd[0].X, abcd[0].Y, 0.0f, 1.0f, 0.0f, 1.0f, // Front
abcd[1].X, abcd[1].Y, 0.0f, 1.0f, 0.0f, 0.0f,
abcd[2].X, abcd[2].Y, 0.0f, 1.0f, 1.0f, 0.0f,
abcd[3].X, abcd[3].Y, 0.0f, 1.0f, 0.0f, 1.0f,
});
var contantBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
var context = device.ImmediateContext;
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() + Utilities.SizeOf<Vector2>(), 0));
context.VertexShader.SetConstantBuffer(0, contantBuffer);
context.VertexShader.Set(vertexShader);
context.Rasterizer.SetViewports(new Viewport(0, 0, _size.Width, _size.Height, 0.0f, 1.0f));
context.PixelShader.Set(pixelShader);
context.PixelShader.SetSampler(0, sampler);
context.PixelShader.SetShaderResource(0, textureView);
context.OutputMerger.SetTargets(renderView);
//
// Render 3D
//
context.ClearRenderTargetView(renderView, Colors.Transparent);
var worldViewProj = Matrix.Identity;// Matrix.Translation (_size.Width, _size.Height/2, 0) * Matrix.Scaling (_size.Width/2, _size.Height/2, 1);
context.UpdateSubresource(ref worldViewProj, contantBuffer);
context.Draw(4, 0);
//
// Composite
//
//Create a render target
var renderSurface = renderTexture.QueryInterface<SharpDX.DXGI.Surface>();
var props = new BitmapProperties
{
PixelFormat = new SharpDX.Direct2D1.PixelFormat(Format.B8G8R8A8_UNorm,AlphaMode.Premultiplied)
};
var direct2DBitmap = new SharpDX.Direct2D1.Bitmap(_bitmapRenderTarget, renderSurface, props);
_wicRenderTarget.BeginDraw();
_wicRenderTarget.DrawBitmap(direct2DBitmap, 1.0f, SharpDX.Direct2D1.BitmapInterpolationMode.Linear);
_wicRenderTarget.EndDraw();
direct2DBitmap.Dispose();
}
private static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, SharpDX.WIC.BitmapSource bitmapSource)
{
// Allocate DataStream to receive the WIC image pixels
int stride = bitmapSource.Size.Width * 4;
using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
{
// Copy the content of the WIC to the buffer
bitmapSource.CopyPixels(stride, buffer);
return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription()
{
Width = bitmapSource.Size.Width,
Height = bitmapSource.Size.Height,
ArraySize = 1,
BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
Usage = SharpDX.Direct3D11.ResourceUsage.Immutable,
CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
MipLevels = 1,
OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
}, new SharpDX.DataRectangle(buffer.DataPointer, stride));
}
}
謝謝。它看起來像我調用的構造函數是一個調用CreateSharedBitmap的構造函數,所以其他事情必須進行。 – roufamatic 2012-07-24 19:43:15
請參閱我上面編輯的答案。 :) – Ani 2012-07-24 19:59:53
阿格。與DX一起工作所需的大量咒語讓我驚歎不已。 – roufamatic 2012-07-24 20:17:58