/// <summary> /// Capture a region of the screen using Direct3D /// </summary> /// <param name="handle">The handle of a window</param> /// <param name="region">The region to capture (in screen coordinates)</param> /// <returns>A bitmap containing the captured region, this should be disposed of appropriately when finished with it</returns> public static Bitmap CaptureRegionDirect3D(IntPtr handle, Rectangle region) { IntPtr hWnd = handle; Bitmap bitmap = null; // We are only supporting the primary display adapter for Direct3D mode SlimDX.Direct3D9.AdapterInformation adapterInfo = _direct3D9.Adapters.DefaultAdapter; SlimDX.Direct3D9.Device device; #region Get Direct3D Device // Retrieve the existing Direct3D device if we already created one for the given handle if (_direct3DDeviceCache.ContainsKey(hWnd)) { device = _direct3DDeviceCache[hWnd]; } // We need to create a new device else { // Setup the device creation parameters SlimDX.Direct3D9.PresentParameters parameters = new SlimDX.Direct3D9.PresentParameters(); parameters.BackBufferFormat = adapterInfo.CurrentDisplayMode.Format; Rectangle clientRect = NativeMethods.GetAbsoluteClientRect(hWnd); parameters.BackBufferHeight = clientRect.Height; parameters.BackBufferWidth = clientRect.Width; parameters.Multisample = SlimDX.Direct3D9.MultisampleType.None; parameters.SwapEffect = SlimDX.Direct3D9.SwapEffect.Discard; parameters.DeviceWindowHandle = hWnd; parameters.PresentationInterval = SlimDX.Direct3D9.PresentInterval.Default; parameters.FullScreenRefreshRateInHertz = 0; // Create the Direct3D device device = new SlimDX.Direct3D9.Device(_direct3D9, adapterInfo.Adapter, SlimDX.Direct3D9.DeviceType.Hardware, hWnd, SlimDX.Direct3D9.CreateFlags.SoftwareVertexProcessing, parameters); _direct3DDeviceCache.Add(hWnd, device); } #endregion // Capture the screen and copy the region into a Bitmap using ( SlimDX.Direct3D9.Surface surface = SlimDX.Direct3D9.Surface.CreateOffscreenPlain(device, adapterInfo.CurrentDisplayMode.Width, adapterInfo.CurrentDisplayMode.Height, SlimDX.Direct3D9.Format.A8R8G8B8, SlimDX.Direct3D9.Pool.SystemMemory)) { device.GetFrontBufferData(0, surface); // Update: thanks digitalutopia1 for pointing out that SlimDX have fixed a bug // where they previously expected a RECT type structure for their Rectangle bitmap = new Bitmap(SlimDX.Direct3D9.Surface.ToStream(surface, SlimDX.Direct3D9.ImageFileFormat.Bmp, new Rectangle(region.Left, region.Top, region.Width, region.Height))); // Previous SlimDX bug workaround: new Rectangle(region.Left, region.Top, region.Right, region.Bottom))); } return(bitmap); }
public static void Copy(SlimDX.Direct3D9.Surface source, SlimDX.Direct3D9.Texture destination) { DataRectangle read = source.LockRectangle(SlimDX.Direct3D9.LockFlags.ReadOnly); DataRectangle write = destination.LockRectangle(0, SlimDX.Direct3D9.LockFlags.Discard); byte[] buffer = new byte[read.Pitch]; while (read.Data.Position < read.Data.Length) { read.Data.Read(buffer, 0, buffer.Length); write.Data.Write(buffer, 0, buffer.Length); if (write.Pitch != read.Pitch) { write.Data.Seek(Math.Max(0, write.Pitch - read.Pitch), System.IO.SeekOrigin.Current); } } destination.UnlockRectangle(0); source.UnlockRectangle(); }
private TextureHandle LoadBlpTexture(SlimDX.Direct3D9.Device Render, System.IO.BinaryReader reader) { reader.BaseStream.Position += 4; byte compression = reader.ReadByte(); byte alphaDepth = reader.ReadByte(); byte alphaEncoding = reader.ReadByte(); byte hasMipMap = reader.ReadByte(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int[] Offsets = new int[16]; int[] Sizes = new int[16]; byte[] ofsTmp = reader.ReadBytes(16 * 4); byte[] sizTmp = reader.ReadBytes(16 * 4); int levelCount = 0; int blockSize = 0; for (int i = 0; i < 16; ++i) { Offsets[i] = BitConverter.ToInt32(ofsTmp, 4 * i); Sizes[i] = BitConverter.ToInt32(sizTmp, 4 * i); if (Offsets[i] != 0 && Sizes[i] != 0) { ++levelCount; } } SlimDX.Direct3D9.Format texFmt = SlimDX.Direct3D9.Format.Unknown; if (compression == 2) { switch (alphaEncoding) { case 0: texFmt = SlimDX.Direct3D9.Format.Dxt1; blockSize = 2; break; case 1: texFmt = SlimDX.Direct3D9.Format.Dxt3; blockSize = 4; break; case 7: texFmt = SlimDX.Direct3D9.Format.Dxt5; blockSize = 4; break; } } if (compression == 3) { texFmt = SlimDX.Direct3D9.Format.A8R8G8B8; blockSize = 4; } if (texFmt == SlimDX.Direct3D9.Format.Unknown) { throw new FormatException("This format is not yet supported, sorry!"); } var texture = new SlimDX.Direct3D9.Texture(Render, width, height, levelCount, SlimDX.Direct3D9.Usage.None, texFmt, SlimDX.Direct3D9.Pool.Managed); int curLevel = 0; for (int i = 0; i < 16; ++i) { if (Sizes[i] != 0 && Offsets[i] != 0) { reader.BaseStream.Position = Offsets[i]; byte[] layerData = reader.ReadBytes(Sizes[i]); SlimDX.Direct3D9.Surface surf = texture.GetSurfaceLevel(curLevel); SlimDX.Direct3D9.SurfaceDescription desc = texture.GetLevelDescription(curLevel); System.Drawing.Rectangle rec = System.Drawing.Rectangle.FromLTRB(0, 0, desc.Width, desc.Height); SlimDX.Direct3D9.Surface.FromMemory(surf, layerData, SlimDX.Direct3D9.Filter.Triangle, 0, texFmt, blockSize * rec.Width, rec); ++curLevel; } } return(new TextureHandle(texture)); }