public override void BlitFromMemory( PixelBox src, BasicBox dstBox )
{
// TODO: This currently does way too many copies. We copy
// from src to a converted buffer (if needed), then from
// converted to a byte array, then into the temporary surface,
// and finally from the temporary surface to the real surface.
PixelBox converted = src;
GCHandle bufGCHandle = new GCHandle();
int bufSize = 0;
// convert to pixelbuffer's native format if necessary
if ( D3DHelper.ConvertEnum( src.Format ) == D3D.Format.Unknown )
{
bufSize = PixelUtil.GetMemorySize( src.Width, src.Height, src.Depth, Format );
byte[] newBuffer = new byte[ bufSize ];
bufGCHandle = GCHandle.Alloc( newBuffer, GCHandleType.Pinned );
converted = new PixelBox( src.Width, src.Height, src.Depth, Format, bufGCHandle.AddrOfPinnedObject() );
PixelConverter.BulkPixelConversion( src, converted );
}
//int formatBytes = PixelUtil.GetNumElemBytes(converted.Format);
using ( D3D.Surface tmpSurface = D3D.Surface.CreateOffscreenPlain( device, converted.Width, converted.Height, D3DHelper.ConvertEnum( converted.Format ), D3D.Pool.Scratch ) )
{
int pitch;
// Ideally I would be using the Array mechanism here, but that doesn't seem to work
DX.DataRectangle buf = tmpSurface.LockRectangle( D3D.LockFlags.NoSystemLock );
{
buf.Data.Position = 0; // Ensure starting Position
bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format );
byte[] ugh = new byte[ bufSize ];
Marshal.Copy( converted.Data, ugh, 0, bufSize );
buf.Data.Write( ugh, 0, bufSize );
}
tmpSurface.UnlockRectangle();
if ( surface != null )
{
// I'm trying to write to surface using the data in converted
System.Drawing.Rectangle srcRect = ToD3DRectangleExtent( converted );
System.Drawing.Rectangle destRect = ToD3DRectangle( dstBox );
D3D.Surface.FromSurface( surface, tmpSurface, D3D.Filter.None, 0, srcRect, destRect );
}
else
{
throw new NotSupportedException( "BlitFromMemory on Volume Textures not supported." );
//D3D.Box srcBox = ToD3DBoxExtent( converted );
//D3D.Box destBox = ToD3DBox( dstBox );
//D3D.VolumeLoader.FromStream(volume, destBox, converted.Data, converted.RowPitch * converted.SlicePitch * formatBytes, srcBox, Filter.None, 0);
//D3D.VolumeLoader.FromStream( volume, destBox, buf, srcBox, D3D.Filter.None, 0 );
}
}
// If we allocated a buffer for the temporary conversion, free it here
// If I used bufPtr to store my temporary data while I converted
// it, I need to free it here. This invalidates converted.
// My data has already been copied to tmpSurface and then to the
// real surface.
if ( bufGCHandle.IsAllocated )
bufGCHandle.Free();
if ( doMipmapGen )
GenMipmaps();
}