0

I have a DirectX rendering that works perfectly when I render to the screen:

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);

(input layout and vertex buffers are omitted here because, as I said, the rendering works as expected to the screen).

When I change it slightly to use a different render target rather than the screen:

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);

and finally save the texture by duly copying it to a staging resource and mapping the latter:

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;
}

the resulting bitmap will be completely empty. There are no errors either in compilation or during the run, just the emptiness.

It might also be worth noting that I don't need repeatedly rendered frames, just a single bitmap created, so there are no performance issues involved. I'd be happy to do away with the screen rendering completely and render to a final bitmap that I can use later.

Gábor
  • 9,466
  • 3
  • 65
  • 79
  • What are you using to implement this? Is this VB.NET using legacy Managed DirectX 1.1? What OS are you using? – Chuck Walbourn Jul 15 '14 at 06:35
  • I've been caught out with offscreen rendering when I failed to set a new viewport after switching render targets - depending on the relative sizes of the targets, you may not get what you expected. – Roger Rowland Jul 15 '14 at 07:24
  • As it can be seen from the tags :-), it's Windows API Code Pack on Windows (I'm on W7, actually). The language is C#. – Gábor Jul 15 '14 at 08:39

0 Answers0