public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) { //TODO - lazy create and cache resolving target in RT var target = new d3d9.Texture(dev, tex.IntWidth, tex.IntHeight, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.SystemMemory); var tw = tex.Opaque as TextureWrapper; dev.GetRenderTargetData(tw.Texture.GetSurfaceLevel(0), target.GetSurfaceLevel(0)); var dr = target.LockRectangle(0, LockFlags.ReadOnly); if (dr.Pitch != tex.IntWidth * 4) { throw new InvalidOperationException(); } int[] pixels = new int[tex.IntWidth * tex.IntHeight]; dr.Data.ReadRange(pixels, 0, tex.IntWidth * tex.IntHeight); var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight, pixels); target.UnlockRectangle(0); target.Dispose(); //buffer churn warning return(bb); }
public Bitmap GetScreen() { Bitmap saveBmp; if (useDirectX) { saveBmp = new Bitmap(SlimDX.Direct3D9.Surface.ToStream(dxDisplay.GetSurfaceLevel(0), SlimDX.Direct3D9.ImageFileFormat.Bmp)); } else { System.Drawing.Imaging.BitmapData bmpData = gdiDisplay.LockBits( screenRect, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); //Copy the data from the byte array into BitmapData.Scan0 lock (ziggyWin.zx) { System.Runtime.InteropServices.Marshal.Copy(ziggyWin.zx.ScreenBuffer, 0, bmpData.Scan0, (ScreenWidth) * (ScreenHeight)); } //Unlock the pixels gdiDisplay.UnlockBits(bmpData); Graphics g1 = this.CreateGraphics(); saveBmp = new Bitmap(this.Width, this.Height, g1); Graphics g2 = Graphics.FromImage(saveBmp); System.IntPtr hdc = g2.GetHdc(); System.IntPtr hbmp = gdiDisplay.GetHbitmap(); System.IntPtr memdc = CreateCompatibleDC(hdc); SelectObject(memdc, hbmp); StretchBlt(hdc, 0, 0, this.Width, this.Height, memdc, 0, 0, ScreenWidth, ScreenHeight, 0xCC0020); g2.ReleaseHdc(hdc); DeleteObject(hbmp); DeleteDC(memdc); } return(saveBmp); }
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) { //TODO - lazy create and cache resolving target in RT var target = new d3d9.Texture(dev, tex.IntWidth, tex.IntHeight, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.SystemMemory); var tw = tex.Opaque as TextureWrapper; dev.GetRenderTargetData(tw.Texture.GetSurfaceLevel(0), target.GetSurfaceLevel(0)); var dr = target.LockRectangle(0, LockFlags.ReadOnly); if (dr.Pitch != tex.IntWidth * 4) throw new InvalidOperationException(); int[] pixels = new int[tex.IntWidth * tex.IntHeight]; dr.Data.ReadRange(pixels, 0, tex.IntWidth * tex.IntHeight); var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight, pixels); target.UnlockRectangle(0); target.Dispose(); //buffer churn warning return bb; }
///<summary> /// Copies a region of this pixelbuffer to normal memory. ///</summary> ///<param name="srcBox">BasicBox describing the source region of this buffer</param> ///<param name="dst">PixelBox describing the destination pixels and format in memory</param> ///<remarks> /// The source and destination regions don't have to match, in which /// case scaling is done. /// Only call this function when the buffer is unlocked. ///</remarks> public override void BlitToMemory( BasicBox srcBox, PixelBox dst ) { // Decide on pixel format of temp surface PixelFormat tmpFormat = Format; if ( D3DHelper.ConvertEnum( dst.Format ) == D3D.Format.Unknown ) tmpFormat = dst.Format; if ( surface != null ) { Debug.Assert( srcBox.Depth == 1 && dst.Depth == 1 ); // Create temp texture D3D.Texture tmp = new D3D.Texture( device, dst.Width, dst.Height, 1, // 1 mip level ie topmost, generate no mipmaps 0, D3DHelper.ConvertEnum( tmpFormat ), D3D.Pool.Scratch ); D3D.Surface subSurface = tmp.GetSurfaceLevel( 0 ); // Copy texture to this temp surface System.Drawing.Rectangle destRect, srcRect; srcRect = ToD3DRectangle( srcBox ); destRect = ToD3DRectangleExtent( dst ); D3D.Surface.FromSurface( subSurface, surface, D3D.Filter.None, 0, srcRect, destRect ); // Lock temp surface and copy it to memory int pitch; // Filled in by D3D DX.DataRectangle data = subSurface.LockRectangle( D3D.LockFlags.ReadOnly ); // Copy it PixelBox locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat ); FromD3DLock( locked, data ); PixelConverter.BulkPixelConversion( locked, dst ); subSurface.UnlockRectangle(); // Release temporary surface and texture subSurface.Dispose(); tmp.Dispose(); } else { // Create temp texture D3D.VolumeTexture tmp = new D3D.VolumeTexture( device, dst.Width, dst.Height, dst.Depth, 0, D3D.Usage.None, D3DHelper.ConvertEnum( tmpFormat ), D3D.Pool.Scratch ); D3D.Volume subVolume = tmp.GetVolumeLevel( 0 ); // Volume D3D.Box ddestBox = ToD3DBoxExtent( dst ); D3D.Box dsrcBox = ToD3DBox( srcBox ); D3D.Volume.FromVolume( subVolume, volume, D3D.Filter.None, 0, dsrcBox, ddestBox ); // Lock temp surface and copy it to memory //D3D.LockedBox lbox; // Filled in by D3D DX.DataBox data = subVolume.LockBox( D3D.LockFlags.ReadOnly ); // Copy it PixelBox locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat ); FromD3DLock( locked, data ); PixelConverter.BulkPixelConversion( locked, dst ); subVolume.UnlockBox(); // Release temporary surface and texture subVolume.Dispose(); tmp.Dispose(); } }