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." );
}
var device = D3DDevice;
D3D.Surface surface, tmpSurface = null;
DX.DataRectangle stream;
int pitch;
D3D.SurfaceDescription desc;
DX.DataBox lockedBox;
if ( buffer == RenderTarget.FrameBuffer.Auto )
{
buffer = RenderTarget.FrameBuffer.Front;
}
if ( buffer == RenderTarget.FrameBuffer.Front )
{
D3D.DisplayMode mode = device.GetDisplayMode( 0 );
desc = new D3D.SurfaceDescription();
desc.Width = mode.Width;
desc.Height = mode.Height;
desc.Format = D3D.Format.A8R8G8B8;
// create a temp surface which will hold the screen image
surface = D3D.Surface.CreateOffscreenPlain( device, mode.Width, mode.Height, D3D.Format.A8R8G8B8,
D3D.Pool.SystemMemory );
// get the entire front buffer. This is SLOW!!
device.GetFrontBufferData( 0, surface );
if ( IsFullScreen )
{
if ( ( dst.Left == 0 ) && ( dst.Right == Width ) && ( dst.Top == 0 ) && ( dst.Bottom == Height ) )
{
stream = surface.LockRectangle( D3D.LockFlags.ReadOnly | D3D.LockFlags.NoSystemLock );
}
else
{
Rectangle rect = new Rectangle();
rect.Left = dst.Left;
rect.Right = dst.Right;
rect.Top = dst.Top;
rect.Bottom = dst.Bottom;
stream = surface.LockRectangle( D3DHelper.ToRectangle( rect ), D3D.LockFlags.ReadOnly | D3D.LockFlags.NoSystemLock );
}
}
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
SWF.Control control = (SWF.Control)hWnd;
System.Drawing.Point point = new System.Drawing.Point();
point.X = (int)srcRect.Left;
point.Y = (int)srcRect.Top;
point = control.PointToScreen( point );
srcRect.Top = point.Y;
srcRect.Left = point.X;
srcRect.Bottom += point.Y;
srcRect.Right += point.X;
desc.Width = (int)( srcRect.Right - srcRect.Left );
desc.Height = (int)( srcRect.Bottom - srcRect.Top );
stream = surface.LockRectangle( D3DHelper.ToRectangle( srcRect ),
D3D.LockFlags.ReadOnly | D3D.LockFlags.NoSystemLock );
}
}
else
{
surface = device.GetBackBuffer( 0, 0 );
desc = surface.Description;
tmpSurface = D3D.Surface.CreateOffscreenPlain( device, desc.Width, desc.Height, desc.Format, D3D.Pool.SystemMemory );
if ( desc.MultisampleType == D3D.MultisampleType.None )
{
device.GetRenderTargetData( surface, tmpSurface );
}
else
{
D3D.Surface stretchSurface;
Rectangle rect = new Rectangle();
stretchSurface = D3D.Surface.CreateRenderTarget( device, desc.Width, desc.Height, desc.Format,
D3D.MultisampleType.None, 0, false );
device.StretchRectangle( tmpSurface, D3DHelper.ToRectangle( rect ), stretchSurface, D3DHelper.ToRectangle( rect ),
D3D.TextureFilter.None );
device.GetRenderTargetData( stretchSurface, tmpSurface );
stretchSurface.Dispose();
}
if ( ( dst.Left == 0 ) && ( dst.Right == Width ) && ( dst.Top == 0 ) && ( dst.Bottom == Height ) )
{
stream = tmpSurface.LockRectangle( D3D.LockFlags.ReadOnly | D3D.LockFlags.NoSystemLock );
}
else
{
Rectangle rect = new Rectangle();
rect.Left = dst.Left;
rect.Right = dst.Right;
rect.Top = dst.Top;
rect.Bottom = dst.Bottom;
stream = tmpSurface.LockRectangle( D3DHelper.ToRectangle( rect ),
D3D.LockFlags.ReadOnly | D3D.LockFlags.NoSystemLock );
}
}
PixelFormat format = D3DHelper.ConvertEnum( desc.Format );
if ( format == PixelFormat.Unknown )
{
if ( tmpSurface != null )
{
tmpSurface.Dispose();
}
throw new Exception( "Unsupported format" );
}
PixelBox src = new PixelBox( dst.Width, dst.Height, 1, format, stream.Data.DataPointer );
src.RowPitch = stream.Pitch / PixelUtil.GetNumElemBytes( format );
src.SlicePitch = desc.Height * src.RowPitch;
PixelConverter.BulkPixelConversion( src, dst );
if ( tmpSurface != null )
{
tmpSurface.Dispose();
}
}