[MDX 2.0 Feb06SDK] Unable to read backbuffer

Started by
4 comments, last by axon 18 years ago
Hi folks, This is an age-old problem I've read many threads here and abroad... but no joy. I'm using the Feb06SDK MDX. It seems MS has moved (removed?) all mechanisms for reading (locking) device buffers (back-buffer or any render-targets). I want to access the data of a rendered scene in CPU. To do so I would have thought I could simply create a Surface with Pool.SystemMemory and Clone() the backbuffer. i.e.
Surface surf = device.CreateOffscreenPlainSurface(640, 480, Format.G16R16F, Pool.SystemMemory);
surf = device.GetBackBuffer(0,0);
GraphicsBuffer gb = surf.Lock(new System.Drawing.Rectangle(0,0,640, 480), LockFlags.ReadOnly);
float[] pixFlt = new float[640 * 480 * 2];
Marshal.Copy(gb.DataBuffer, pixFlt, 0, gb.SizeInBytes / 4);
surf.Unlock();
There used to be SurfaceLoader.FromSurface(surf, BackBuffer, Filter.Point, 0) but this no longer exists. I'd be over-the-moon if anyone has a workaround or a way of reading a pixel from either the back-buffer or a texture that has Usage.RenderTarget. Thanks in advance for exercising your neurons on this. Greg
Advertisement
having similiar issues. I was trying to write to the surface not read but again same issue =/
- The collective intelligence of the human race is a constant; the population is growing at an exponential rate. The conclusion is left as an exercise for the student.
I've found what looks like a key function: GetRenderTargetData()

I've tried to use it like this:
device.GetRenderTargetData(texRT.GetSurfaceLevel(0), surf);GraphicsBuffer gb = surf.Lock(null, LockFlags.None);Marshal.Copy(gb.DataBuffer, pixFlt, 0, gb.SizeInBytes / 4);surf.Unlock();

But gb.SizeInBytes is always zero.

I've also found a couple of old thread which are related but some say it's possible, some say it's impossible (hard to believe), and none say how to do it!
Here's the links to a couple of those threads:
Locking RenderTarget Texture
Locking rendertarget texture for Tron-like glow (this one ends with them using a shader to do what they wanted to without solving this problem)

To me this seems like a common problem.. I just can't crack it. Anyone had more luck than me?
The SurfaceLoader class does not exist anymore in MDX2.0 as you might have noticed. It's been suggested that developers revert back to MDX1.1 for the time being as MDX2.0 will only be out of Beta when XNA is released which will include Managed DirectX 2.0.

I hope this helps.
Take care.
even if there is no SurfLoader class in MDX2, is there support in the DXAPI somewhere else which can move texture data to CPU accessible memory?

What about MDX1?

I've created a test application using MDX1 and am having the same trouble... even with the help of SurfaceLoader (see below):
// InitialisationTexture texRT = new Texture(e.Device, desc.Width, desc.Height, 1,                             Usage.RenderTarget, Format.G16R16F, Pool.Default);Surface surf = e.Device.CreateOffscreenPlainSurface(desc.Width, desc.Height,                                                    Format.G16R16F, Pool.SystemMemory);float[] pixFlt = new float[desc.Width * desc.Height * 2];// OnRenderSurfaceLoader.FromSurface(surf, texRT.GetSurfaceLevel(0), Filter.None, 0);GraphicsStream gs = surf.LockRectangle(LockFlags.ReadOnly);Marshal.Copy(gs.InternalData, pixFlt, 0, Math.Min((int)gs.Length / 4, pixFlt.Length));surf.UnlockRectangle();


Now Marshal.Copy() throws a memory access violation exception.

(based on code at MSDN Forum)

[Edited by - axon on March 29, 2006 1:41:47 AM]
Good News!

The code I've already posted is eesentially correct!

What made me think the code didn't work was the fact that I was copying 16-bit floats (Format.G16R16F) into 32-bit floats (float[]).

So the code works fine in both MDX1 and MDX2 (despite the absence of SurfLoader).

This topic is closed to new replies.

Advertisement