Example #1
0
        /// <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);
        }
Example #2
0
        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();
        }
Example #3
0
        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));
        }