///<summary> /// Internal implementation of <see cref="HardwareBuffer.Lock"/>. ///</summary> protected override PixelBox LockImpl(BasicBox lockBox, BufferLocking options) { _lockedBox = lockBox; // Set extents and format var rval = new PixelBox(lockBox, Format); var sizeInBytes = PixelUtil.GetMemorySize(lockBox.Width, lockBox.Height, lockBox.Depth, XnaHelper.Convert(surface.Format)); if (_bufferBytes == null || _bufferBytes.Length != sizeInBytes) { _bufferBytes = new byte[sizeInBytes]; #if !SILVERLIGHT if (surface != null) { surface.GetData(mipLevel, XnaHelper.ToRectangle(lockBox), _bufferBytes, 0, _bufferBytes.Length); } else if (cube != null) { cube.GetData(face, mipLevel, XnaHelper.ToRectangle(lockBox), _bufferBytes, 0, _bufferBytes.Length); } else { volume.GetData(mipLevel, lockBox.Left, lockBox.Top, lockBox.Right, lockBox.Bottom, lockBox.Front, lockBox.Back, _bufferBytes, 0, _bufferBytes.Length); } #endif } rval.Data = BufferBase.Wrap(_bufferBytes); return(rval); }
///<summary> /// Copies a region from normal memory to a region of this pixelbuffer. The source /// image can be in any pixel format supported by Axiom, and in any size. ///</summary> ///<param name="src">PixelBox containing the source pixels and format in memory</param> ///<param name="dstBox">Image.BasicBox describing the destination region in this buffer</param> ///<remarks> /// The source and destination regions dimensions don't have to match, in which /// case scaling is done. This scaling is generally done using a bilinear filter in hardware, /// but it is faster to pass the source image in the right dimensions. /// Only call this function when both buffers are unlocked. ///</remarks> public override void BlitFromMemory(PixelBox src, BasicBox dstBox) { var converted = src; var bufGCHandle = new GCHandle(); var bufSize = 0; // Get src.Data as byte[] bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, Format); var newBuffer = new byte[bufSize]; //bufGCHandle = GCHandle.Alloc( newBuffer, GCHandleType.Pinned ); //XnaHelper.Convert(XFG.SurfaceFormat) would never have returned SurfaceFormat.Unknown anyway... //if (XnaHelper.Convert(src.Format) != XFG.SurfaceFormat.Unknown) { converted = new PixelBox(src.Width, src.Height, src.Depth, Format, BufferBase.Wrap(newBuffer)); PixelConverter.BulkPixelConversion(src, converted); } //else //{ // Memory.Copy(converted.Data, BufferBase.Wrap(newBuffer), bufSize); //} if (surface != null) { surface.SetData(mipLevel, XnaHelper.ToRectangle(dstBox), newBuffer, 0, bufSize); } else if (cube != null) { cube.SetData(face, mipLevel, XnaHelper.ToRectangle(dstBox), newBuffer, 0, bufSize); } else { throw new NotSupportedException("BlitFromMemory on Volume Textures not supported."); } // If we allocated a buffer for the temporary conversion, free it here if (bufGCHandle.IsAllocated) { bufGCHandle.Free(); } if (doMipmapGen) { GenMipmaps(); } }
/// <summary> /// Internal implementation of <see cref="HardwareBuffer.Unlock"/>. /// </summary> protected override void UnlockImpl() { //set the bytes array inside the texture if (surface != null) { surface.SetData(mipLevel, XnaHelper.ToRectangle(_lockedBox), _bufferBytes, 0, _bufferBytes.Length); } else if (cube != null) { cube.SetData(face, mipLevel, XnaHelper.ToRectangle(_lockedBox), _bufferBytes, 0, _bufferBytes.Length); } #if !SILVERLIGHT else { volume.SetData(mipLevel, _lockedBox.Left, _lockedBox.Top, _lockedBox.Right, _lockedBox.Bottom, _lockedBox.Front, _lockedBox.Back, _bufferBytes, 0, _bufferBytes.Length); } #endif }
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 = Driver.XnaDevice; //in 3.1, this was 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 RenderTarget2D surface; var data = new byte[dst.ConsecutiveSize]; var pitch = 0; if (buffer == FrameBuffer.Auto) { buffer = FrameBuffer.Front; } #if SILVERLIGHT var mode = ((XnaRenderSystem)Root.Instance.RenderSystem).DisplayMode; surface = new RenderTarget2D(device, mode.Width, mode.Height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8); #else var mode = device.DisplayMode; surface = new RenderTarget2D(device, mode.Width, mode.Height, false, SurfaceFormat.Rgba64, DepthFormat.Depth24Stencil8); #endif //ResolveTexture2D( device, mode.Width, mode.Height, 0, SurfaceFormat.Rgba32 ); #if !SILVERLIGHT if (buffer == 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(data); } else { var rect = new Rectangle(); rect.Left = dst.Left; rect.Right = dst.Right; rect.Top = dst.Top; rect.Bottom = dst.Bottom; surface.GetData(0, XnaHelper.ToRectangle(rect), data, 0, 255); } } #if !(XBOX || XBOX360 || WINDOWS_PHONE) else { var 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 var point = new Point(); point.X = (int)srcRect.Left; point.Y = (int)srcRect.Top; var control = Control.FromHandle(_windowHandle); point = control.PointToScreen(point); srcRect.Top = (long)point.Y; srcRect.Left = (long)point.X; srcRect.Bottom += (long)point.Y; srcRect.Right += (long)point.X; surface.GetData(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(data); } else { var rect = new Rectangle(); rect.Left = dst.Left; rect.Right = dst.Right; rect.Top = dst.Top; rect.Bottom = dst.Bottom; surface.GetData(0, XnaHelper.ToRectangle(rect), data, 0, 255); } } #endif var format = XnaHelper.Convert(surface.Format); if (format == PixelFormat.Unknown) { throw new Exception("Unsupported format"); } var dataPtr = Memory.PinObject(data); var 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(); }