我有一个 DirectX 渲染,当我渲染到屏幕上时效果很好:
var DxDevice = D3D.D3DDevice.CreateDeviceAndSwapChain(host.Handle);
...
var DxFinalRenderTexture = DxDevice.SwapChain.GetBuffer<D3D.Texture2D>(0);
var DxFinalRenderTarget = DxDevice.CreateRenderTargetView(DxFinalRenderTexture);
DxDevice.OM.RenderTargets = new D3D.OutputMergerRenderTargets(new D3D.RenderTargetView[] { DxFinalRenderTarget }, null);
DxTechnique.GetPassByIndex(0).Apply();
DxDevice.Draw(4, 0);
DxDevice.SwapChain.Present(0, GX.PresentOptions.None);
(这里省略了输入布局和顶点缓冲区,因为正如我所说,渲染按预期在屏幕上工作)。
当我稍微改变它以使用不同的渲染目标而不是屏幕时:
var description = new D3D.Texture2DDescription() {
Width = 1024,
Height = 1024,
ArraySize = 1,
BindingOptions = D3D.BindingOptions.RenderTarget | D3D.BindingOptions.ShaderResource,
CpuAccessOptions = D3D.CpuAccessOptions.None,
Format = DX.Graphics.Format.B8G8R8A8UNorm,
MipLevels = 1,
MiscellaneousResourceOptions = D3D.MiscellaneousResourceOptions.None,
SampleDescription = new DX.Graphics.SampleDescription(1, 0),
Usage = D3D.Usage.Default
};
var DxFinalRenderTexture = DxDevice.CreateTexture2D(description);
var description2 = new D3D.RenderTargetViewDescription() {
Format = description.Format,
ViewDimension = D3D.RenderTargetViewDimension.Texture2D,
Texture2D = new D3D.Texture2DRenderTargetView() { MipSlice = 0 }
};
var DxFinalRenderTarget = DxDevice.CreateRenderTargetView(DxFinalRenderTexture, description2);
最后通过适当地将纹理复制到暂存资源并映射后者来保存纹理:
private WriteableBitmap GetTexture(D3D.Texture2D texture) {
var description = new D3D.Texture2DDescription() {
Width = 1024,
Height = 1024,
ArraySize = 1,
BindingOptions = D3D.BindingOptions.None,
CpuAccessOptions = D3D.CpuAccessOptions.Read,
Format = DX.Graphics.Format.B8G8R8A8UNorm,
MipLevels = 1,
MiscellaneousResourceOptions = D3D.MiscellaneousResourceOptions.None,
SampleDescription = new DX.Graphics.SampleDescription(1, 0),
Usage = D3D.Usage.Staging
};
var texture2 = DxDevice.CreateTexture2D(description);
DxDevice.CopyResource(texture2, texture);
var texmap = texture2.Map(0, D3D.Map.Read, D3D.MapOptions.None);
var bitmap = new WriteableBitmap(1024, 1024, 96, 96, PixelFormats.Pbgra32, null);
bitmap.Lock();
bitmap.WritePixels(new Int32Rect(0, 0, 1024, 1024), texmap.Data, 1024 * 1024 * 4, 1024 * 4);
bitmap.Unlock();
texture2.Unmap(0);
return bitmap;
}
生成的位图将完全为空。编译和运行过程中都没有错误,只有空虚。
还可能值得注意的是,我不需要重复渲染帧,只需要创建一个位图,因此不涉及性能问题。我很乐意完全取消屏幕渲染并渲染到我以后可以使用的最终位图。