public override void CopyContentsToMemory( PixelBox dst, FrameBuffer buffer )
{
if ( ( dst.Left < 0 ) || ( dst.Right > Width ) ||
( dst.Top < 0 ) || ( dst.Bottom > Height ) ||
( dst.Front != 0 ) || ( dst.Back != 1 ) )
{
throw new Exception( "Invalid box." );
}
XFG.GraphicsDevice device = Driver.XnaDevice;
//in 3.1, this was XFG.ResolveTexture2D, an actual RenderTarget provides the exact same
//functionality, especially seeing as RenderTarget2D is a texture now.
//the difference is surface is actually set on the device -DoubleA
XFG.RenderTarget2D surface;
byte[] data = new byte[ dst.ConsecutiveSize ];
int pitch = 0;
if ( buffer == RenderTarget.FrameBuffer.Auto )
{
buffer = RenderTarget.FrameBuffer.Front;
}
XFG.DisplayMode mode = device.DisplayMode;
surface = new XFG.RenderTarget2D(device, mode.Width, mode.Height, false, XFG.SurfaceFormat.Rgba64, XFG.DepthFormat.Depth24Stencil8); //XFG.ResolveTexture2D( device, mode.Width, mode.Height, 0, XFG.SurfaceFormat.Rgba32 );
if ( buffer == RenderTarget.FrameBuffer.Front )
{
// get the entire front buffer. This is SLOW!!
device.SetRenderTarget(surface);
if ( IsFullScreen )
{
if ( ( dst.Left == 0 ) && ( dst.Right == Width ) && ( dst.Top == 0 ) && ( dst.Bottom == Height ) )
{
surface.GetData<byte>( data );
}
else
{
Rectangle rect = new Rectangle();
rect.Left = dst.Left;
rect.Right = dst.Right;
rect.Top = dst.Top;
rect.Bottom = dst.Bottom;
surface.GetData<byte>( 0, XnaHelper.ToRectangle( rect ), data, 0, 255 );
}
}
#if !( XBOX || XBOX360 )
else
{
Rectangle srcRect = new Rectangle();
srcRect.Left = dst.Left;
srcRect.Right = dst.Right;
srcRect.Top = dst.Top;
srcRect.Bottom = dst.Bottom;
// Adjust Rectangle for Window Menu and Chrome
System.Drawing.Point point = new System.Drawing.Point();
point.X = (int)srcRect.Left;
point.Y = (int)srcRect.Top;
SWF.Control control = SWF.Control.FromHandle( _windowHandle );
point = control.PointToScreen( point );
srcRect.Top = point.Y;
srcRect.Left = point.X;
srcRect.Bottom += point.Y;
srcRect.Right += point.X;
surface.GetData<byte>( 0, XnaHelper.ToRectangle( srcRect ), data, 0, 255 );
}
#endif
}
else
{
device.SetRenderTarget( surface );
if ( ( dst.Left == 0 ) && ( dst.Right == Width ) && ( dst.Top == 0 ) && ( dst.Bottom == Height ) )
{
surface.GetData<byte>( data );
}
else
{
Rectangle rect = new Rectangle();
rect.Left = dst.Left;
rect.Right = dst.Right;
rect.Top = dst.Top;
rect.Bottom = dst.Bottom;
surface.GetData<byte>( 0, XnaHelper.ToRectangle( rect ), data, 0, 255 );
}
}
PixelFormat format = XnaHelper.Convert( surface.Format );
if ( format == PixelFormat.Unknown )
{
throw new Exception( "Unsupported format" );
}
IntPtr dataPtr = Memory.PinObject( data );
PixelBox src = new PixelBox( dst.Width, dst.Height, 1, format, dataPtr );
src.RowPitch = pitch / PixelUtil.GetNumElemBytes( format );
src.SlicePitch = surface.Height * src.RowPitch;
PixelConverter.BulkPixelConversion( src, dst );
Memory.UnpinObject( data );
surface.Dispose();
}