Example #1
0
        void game_FrameEnd(object sender, EventArgs e)
        {
            SlimDX.DXGI.PresentFlags flags = SlimDX.DXGI.PresentFlags.None;
            if (renderingOccluded)
            {
                flags = SlimDX.DXGI.PresentFlags.Test;
            }
            else
            {
                flags = CurrentSettings.Direct3D10.PresentFlags;
            }
            Result result = Direct3D10.SwapChain.Present(CurrentSettings.Direct3D10.SyncInterval, flags);

            if (result == SlimDX.DXGI.ResultCode.Occluded)
            {
                renderingOccluded = true;
            }
            else if (result == SlimDX.DXGI.ResultCode.DeviceReset)
            {
                ResetDevice();
            }
            else
            {
                renderingOccluded = false;
            }
        }
Example #2
0
        /// <summary>
        /// Our present hook that will grab a copy of the backbuffer when requested. Note: this supports multi-sampling (anti-aliasing)
        /// </summary>
        /// <param name="swapChainPtr"></param>
        /// <param name="syncInterval"></param>
        /// <param name="flags"></param>
        /// <returns>The HRESULT of the original method</returns>
        int PresentHook(IntPtr swapChainPtr, int syncInterval, SlimDX.DXGI.PresentFlags flags)
        {
            if (swapChainPtr != _swapChainPointer)
            {
                _swapChain = SlimDX.DXGI.SwapChain.FromPointer(swapChainPtr);
            }
            SwapChain swapChain = _swapChain;
            //using (SlimDX.DXGI.SwapChain swapChain = SlimDX.DXGI.SwapChain.FromPointer(swapChainPtr))
            {
                try
                {
                    #region Screenshot Request
                    if (this.Request != null)
                    {
                        try
                        {
                            this.DebugMessage("PresentHook: Request Start");
                            DateTime startTime = DateTime.Now;
                            using (Texture2D texture = Texture2D.FromSwapChain <SlimDX.Direct3D10.Texture2D>(swapChain, 0))
                            {
                                #region Determine region to capture
                                System.Drawing.Rectangle regionToCapture = new System.Drawing.Rectangle(0, 0, texture.Description.Width, texture.Description.Height);

                                if (this.Request.RegionToCapture.Width > 0)
                                {
                                    regionToCapture = this.Request.RegionToCapture;
                                }
                                #endregion

                                var theTexture = texture;

                                // If texture is multisampled, then we can use ResolveSubresource to copy it into a non-multisampled texture
                                Texture2D textureResolved = null;
                                if (texture.Description.SampleDescription.Count > 1)
                                {
                                    this.DebugMessage("PresentHook: resolving multi-sampled texture");
                                    // texture is multi-sampled, lets resolve it down to single sample
                                    textureResolved = new Texture2D(texture.Device, new Texture2DDescription()
                                    {
                                        CpuAccessFlags    = CpuAccessFlags.None,
                                        Format            = texture.Description.Format,
                                        Height            = texture.Description.Height,
                                        Usage             = ResourceUsage.Default,
                                        Width             = texture.Description.Width,
                                        ArraySize         = 1,
                                        SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                                        BindFlags         = BindFlags.None,
                                        MipLevels         = 1,
                                        OptionFlags       = texture.Description.OptionFlags
                                    });
                                    // Resolve into textureResolved
                                    texture.Device.ResolveSubresource(texture, 0, textureResolved, 0, texture.Description.Format);

                                    // Make "theTexture" be the resolved texture
                                    theTexture = textureResolved;
                                }

                                // Create destination texture
                                Texture2D textureDest = new Texture2D(texture.Device, new Texture2DDescription()
                                {
                                    CpuAccessFlags    = CpuAccessFlags.None,                     // CpuAccessFlags.Write | CpuAccessFlags.Read,
                                    Format            = SlimDX.DXGI.Format.R8G8B8A8_UNorm,       // Supports BMP/PNG
                                    Height            = regionToCapture.Height,
                                    Usage             = ResourceUsage.Default,                   // ResourceUsage.Staging,
                                    Width             = regionToCapture.Width,
                                    ArraySize         = 1,                                       //texture.Description.ArraySize,
                                    SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // texture.Description.SampleDescription,
                                    BindFlags         = BindFlags.None,
                                    MipLevels         = 1,                                       //texture.Description.MipLevels,
                                    OptionFlags       = texture.Description.OptionFlags
                                });

                                // Copy the subresource region, we are dealing with a flat 2D texture with no MipMapping, so 0 is the subresource index
                                theTexture.Device.CopySubresourceRegion(theTexture, 0, new ResourceRegion()
                                {
                                    Top    = regionToCapture.Top,
                                    Bottom = regionToCapture.Bottom,
                                    Left   = regionToCapture.Left,
                                    Right  = regionToCapture.Right,
                                    Front  = 0,
                                    Back   = 1 // Must be 1 or only black will be copied
                                }, textureDest, 0, 0, 0, 0);

                                // Note: it would be possible to capture multiple frames and process them in a background thread

                                // Copy to memory and send back to host process on a background thread so that we do not cause any delay in the rendering pipeline
                                Guid requestId = this.Request.RequestId; // this.Request gets set to null, so copy the RequestId for use in the thread
                                ThreadPool.QueueUserWorkItem(delegate
                                {
                                    //FileStream fs = new FileStream(@"c:\temp\temp.bmp", FileMode.Create);
                                    //Texture2D.ToStream(testSubResourceCopy, ImageFileFormat.Bmp, fs);

                                    DateTime startCopyToSystemMemory = DateTime.Now;
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        Texture2D.ToStream(textureDest, ImageFileFormat.Bmp, ms);
                                        ms.Position = 0;
                                        this.DebugMessage("PresentHook: Copy to System Memory time: " + (DateTime.Now - startCopyToSystemMemory).ToString());

                                        DateTime startSendResponse = DateTime.Now;
                                        SendResponse(ms, requestId);
                                        this.DebugMessage("PresentHook: Send response time: " + (DateTime.Now - startSendResponse).ToString());
                                    }

                                    // Free the textureDest as we no longer need it.
                                    textureDest.Dispose();
                                    textureDest = null;
                                    this.DebugMessage("PresentHook: Full Capture time: " + (DateTime.Now - startTime).ToString());
                                });

                                // Make sure we free up the resolved texture if it was created
                                if (textureResolved != null)
                                {
                                    textureResolved.Dispose();
                                    textureResolved = null;
                                }
                            }

                            this.DebugMessage("PresentHook: Copy BackBuffer time: " + (DateTime.Now - startTime).ToString());
                            this.DebugMessage("PresentHook: Request End");
                        }
                        finally
                        {
                            // Prevent the request from being processed a second time
                            this.Request = null;
                        }
                    }
                    #endregion

                    #region Example: Draw overlay (after screenshot so we don't capture overlay as well)
                    if (this.ShowOverlay)
                    {
                        using (Texture2D texture = Texture2D.FromSwapChain <SlimDX.Direct3D10.Texture2D>(swapChain, 0))
                        {
                            if (_lastFrame != null)
                            {
                                FontDescription fd = new SlimDX.Direct3D10.FontDescription()
                                {
                                    Height         = 16,
                                    FaceName       = "Times New Roman",
                                    IsItalic       = false,
                                    Width          = 0,
                                    MipLevels      = 1,
                                    CharacterSet   = SlimDX.Direct3D10.FontCharacterSet.Default,
                                    Precision      = SlimDX.Direct3D10.FontPrecision.Default,
                                    Quality        = SlimDX.Direct3D10.FontQuality.Antialiased,
                                    PitchAndFamily = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare
                                };

                                using (Font font = new Font(texture.Device, fd))
                                {
                                    DrawText(font, new Vector2(100, 100), String.Format("{0}", DateTime.Now), new Color4(System.Drawing.Color.Red));
                                }
                            }
                            _lastFrame = DateTime.Now;
                        }
                    }
                    #endregion
                }
                catch (Exception e)
                {
                    // If there is an error we do not want to crash the hooked application, so swallow the exception
                    this.DebugMessage("PresentHook: Exeception: " + e.GetType().FullName + ": " + e.Message);
                }

                // As always we need to call the original method, note that EasyHook has already repatched the original method
                // so calling it here will not cause an endless recursion to this function
                return(swapChain.Present(syncInterval, flags).Code);
            }
        }
Example #3
0
        /// <summary>
        /// Our present hook that will grab a copy of the backbuffer when requested. Note: this supports multi-sampling (anti-aliasing)
        /// </summary>
        /// <param name="swapChainPtr"></param>
        /// <param name="syncInterval"></param>
        /// <param name="flags"></param>
        /// <returns>The HRESULT of the original method</returns>
        int PresentHook(IntPtr swapChainPtr, int syncInterval, SlimDX.DXGI.PresentFlags flags)
        {
            using (SlimDX.DXGI.SwapChain swapChain = SlimDX.DXGI.SwapChain.FromPointer(swapChainPtr))
            {
                try
                {
                    #region Screenshot Request
                    if (this.Request != null)
                    {
                        this.DebugMessage("PresentHook: Request Start");
                        DateTime startTime = DateTime.Now;
                        using (Texture2D texture = Texture2D.FromSwapChain <Texture2D>(swapChain, 0))
                        {
                            #region Determine region to capture
                            System.Drawing.Rectangle regionToCapture = new System.Drawing.Rectangle(0, 0, texture.Description.Width, texture.Description.Height);

                            if (this.Request.RegionToCapture.Width > 0)
                            {
                                regionToCapture = this.Request.RegionToCapture;
                            }
                            #endregion

                            var theTexture = texture;

                            // If texture is multisampled, then we can use ResolveSubresource to copy it into a non-multisampled texture
                            Texture2D textureResolved = null;
                            if (texture.Description.SampleDescription.Count > 1)
                            {
                                this.DebugMessage("PresentHook: resolving multi-sampled texture");
                                // texture is multi-sampled, lets resolve it down to single sample
                                textureResolved = new Texture2D(texture.Device, new Texture2DDescription()
                                {
                                    CpuAccessFlags    = CpuAccessFlags.None,
                                    Format            = texture.Description.Format,
                                    Height            = texture.Description.Height,
                                    Usage             = ResourceUsage.Default,
                                    Width             = texture.Description.Width,
                                    ArraySize         = 1,
                                    SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                                    BindFlags         = BindFlags.None,
                                    MipLevels         = 1,
                                    OptionFlags       = texture.Description.OptionFlags
                                });
                                // Resolve into textureResolved
                                texture.Device.ImmediateContext.ResolveSubresource(texture, 0, textureResolved, 0, texture.Description.Format);

                                // Make "theTexture" be the resolved texture
                                theTexture = textureResolved;
                            }

                            // Create destination texture
                            Texture2D textureDest = new Texture2D(texture.Device, new Texture2DDescription()
                            {
                                CpuAccessFlags    = CpuAccessFlags.None,                     // CpuAccessFlags.Write | CpuAccessFlags.Read,
                                Format            = SlimDX.DXGI.Format.R8G8B8A8_UNorm,       // Supports BMP/PNG
                                Height            = regionToCapture.Height,
                                Usage             = ResourceUsage.Default,                   // ResourceUsage.Staging,
                                Width             = regionToCapture.Width,
                                ArraySize         = 1,                                       //texture.Description.ArraySize,
                                SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // texture.Description.SampleDescription,
                                BindFlags         = BindFlags.None,
                                MipLevels         = 1,                                       //texture.Description.MipLevels,
                                OptionFlags       = texture.Description.OptionFlags
                            });

                            // Copy the subresource region, we are dealing with a flat 2D texture with no MipMapping, so 0 is the subresource index
                            theTexture.Device.ImmediateContext.CopySubresourceRegion(theTexture, 0, new ResourceRegion()
                            {
                                Top    = regionToCapture.Top,
                                Bottom = regionToCapture.Bottom,
                                Left   = regionToCapture.Left,
                                Right  = regionToCapture.Right,
                                Front  = 0,
                                Back   = 1 // Must be 1 or only black will be copied
                            }, textureDest, 0, 0, 0, 0);

                            // Note: it would be possible to capture multiple frames and process them in a background thread

                            // Copy to memory and send back to host process on a background thread so that we do not cause any delay in the rendering pipeline
                            Guid requestId = this.Request.RequestId; // this.Request gets set to null, so copy the RequestId for use in the thread
                            ThreadPool.QueueUserWorkItem(delegate
                            {
                                //FileStream fs = new FileStream(@"c:\temp\temp.bmp", FileMode.Create);
                                //Texture2D.ToStream(testSubResourceCopy, ImageFileFormat.Bmp, fs);

                                DateTime startCopyToSystemMemory = DateTime.Now;
                                using (MemoryStream ms = new MemoryStream())
                                {
                                    Texture2D.ToStream(textureDest.Device.ImmediateContext, textureDest, ImageFileFormat.Bmp, ms);
                                    ms.Position = 0;
                                    this.DebugMessage("PresentHook: Copy to System Memory time: " + (DateTime.Now - startCopyToSystemMemory).ToString());

                                    DateTime startSendResponse = DateTime.Now;
                                    SendResponse(ms, requestId);
                                    this.DebugMessage("PresentHook: Send response time: " + (DateTime.Now - startSendResponse).ToString());
                                }

                                // Free the textureDest as we no longer need it.
                                textureDest.Dispose();
                                textureDest = null;
                                this.DebugMessage("PresentHook: Full Capture time: " + (DateTime.Now - startTime).ToString());
                            });

                            // Prevent the request from being processed a second time
                            this.Request = null;

                            // Make sure we free up the resolved texture if it was created
                            if (textureResolved != null)
                            {
                                textureResolved.Dispose();
                                textureResolved = null;
                            }
                        }
                        this.DebugMessage("PresentHook: Copy BackBuffer time: " + (DateTime.Now - startTime).ToString());
                        this.DebugMessage("PresentHook: Request End");
                    }
                    #endregion

                    #region TODO: Draw overlay (after screenshot so we don't capture overlay as well)

                    // Note: Direct3D 11 doesn't have font support, so I believe the approach is to use
                    //       a Direct3D 10.1 device with Direct2d, render to a texture, and then blend
                    //       this into the Direct3D 11 backbuffer - hmm sounds like fun.
                    // http://forums.create.msdn.com/forums/t/38961.aspx
                    // http://www.gamedev.net/topic/547920-how-to-use-d2d-with-d3d11/

                    #endregion
                }
                catch (Exception e)
                {
                    // If there is an error we do not want to crash the hooked application, so swallow the exception
                    this.DebugMessage("PresentHook: Exeception: " + e.GetType().FullName + ": " + e.Message);
                    //return unchecked((int)0x8000FFFF); //E_UNEXPECTED
                }

                // As always we need to call the original method, note that EasyHook has already repatched the original method
                // so calling it here will not cause an endless recursion to this function
                return(swapChain.Present(syncInterval, flags).Code);
            }
        }
        /// <summary>
        /// Our present hook that will grab a copy of the backbuffer when requested. Note: this supports multi-sampling (anti-aliasing)
        /// </summary>
        /// <param name="swapChainPtr"></param>
        /// <param name="syncInterval"></param>
        /// <param name="flags"></param>
        /// <returns>The HRESULT of the original method</returns>
        int PresentHook(IntPtr swapChainPtr, int syncInterval, SlimDX.DXGI.PresentFlags flags)
        {
            try
            {
                if (_swapChain == null)
                {
                    _swapChain = SlimDX.DXGI.SwapChain.FromPointer(swapChainPtr);
                }
                SwapChain swapChain = _swapChain;
                {
                    CheckAuto();
                    UpdateFPS();

                    try
                    {
                        #region Screenshot Request
                        if (this.Request != null)
                        {
                            try
                            {
                                this.DebugMessage("PresentHook: Request Start");
                                LastRequestTime = DateTime.Now;
                                DateTime startTime = DateTime.Now;
                                using (Texture2D texture = Texture2D.FromSwapChain <SlimDX.Direct3D10.Texture2D>(swapChain, 0))
                                {
                                    #region Determine region to capture
                                    System.Drawing.Rectangle regionToCapture     = new System.Drawing.Rectangle(0, 0, texture.Description.Width, texture.Description.Height);
                                    System.Drawing.Rectangle regionToCaptureDest = new System.Drawing.Rectangle(0, 0, texture.Description.Width, texture.Description.Height);

                                    DebugMessage("from " + regionToCapture.ToString() + " to " + regionToCaptureDest.ToString());

                                    //DebugMessage("Flags: "+flags.ToString());
                                    //if (this.Request.RegionToCapture.Width > 0)
                                    //{
                                    //    regionToCapture = this.Request.RegionToCapture;
                                    //}
                                    #endregion

                                    ////start old
                                    //var theTexture = texture;

                                    //// If texture is multisampled, then we can use ResolveSubresource to copy it into a non-multisampled texture
                                    //Texture2D textureResolved = null;
                                    //if (texture.Description.SampleDescription.Count > 1)
                                    //{
                                    //    this.DebugMessage("PresentHook: resolving multi-sampled texture");
                                    //    // texture is multi-sampled, lets resolve it down to single sample
                                    //    textureResolved = new Texture2D(texture.Device, new Texture2DDescription()
                                    //    {
                                    //        CpuAccessFlags = CpuAccessFlags.None,
                                    //        Format = texture.Description.Format,
                                    //        Height = texture.Description.Height,
                                    //        Usage = ResourceUsage.Default,
                                    //        Width = texture.Description.Width,
                                    //        ArraySize = 1,
                                    //        SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                                    //        BindFlags = BindFlags.None,
                                    //        MipLevels = 1,
                                    //        OptionFlags = texture.Description.OptionFlags
                                    //    });
                                    //    // Resolve into textureResolved
                                    //    texture.Device.ResolveSubresource(texture, 0, textureResolved, 0, texture.Description.Format);

                                    //    // Make "theTexture" be the resolved texture
                                    //    theTexture = textureResolved;
                                    //}

                                    //// Create destination texture
                                    //Texture2D textureDest = new Texture2D(texture.Device, new Texture2DDescription()
                                    //{
                                    //    CpuAccessFlags = CpuAccessFlags.None,// CpuAccessFlags.Write | CpuAccessFlags.Read,
                                    //    Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, // Supports BMP/PNG
                                    //    Height = regionToCapture.Height,
                                    //    Usage = ResourceUsage.Default,// ResourceUsage.Staging,
                                    //    Width = regionToCapture.Width,
                                    //    ArraySize = 1,//texture.Description.ArraySize,
                                    //    SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0),// texture.Description.SampleDescription,
                                    //    BindFlags = BindFlags.None,
                                    //    MipLevels = 1,//texture.Description.MipLevels,
                                    //    OptionFlags = texture.Description.OptionFlags
                                    //});

                                    //// Copy the subresource region, we are dealing with a flat 2D texture with no MipMapping, so 0 is the subresource index
                                    //theTexture.Device.CopySubresourceRegion(theTexture, 0, new ResourceRegion()
                                    //{
                                    //    Top = regionToCapture.Top,
                                    //    Bottom = regionToCapture.Bottom,
                                    //    Left = regionToCapture.Left,
                                    //    Right = regionToCapture.Right,
                                    //    Front = 0,
                                    //    Back = 1 // Must be 1 or only black will be copied
                                    //}, textureDest, 0, 0, 0, 0);
                                    ////end old

                                    var theTexture = texture;
                                    DebugMessage(texture.Description.Format.ToString());
                                    // If texture is multisampled, then we can use ResolveSubresource to copy it into a non-multisampled texture
                                    Texture2D textureResolved = null;
                                    if (texture.Description.SampleDescription.Count > 1)
                                    {
                                        this.DebugMessage("PresentHook: resolving multi-sampled texture");
                                        // texture is multi-sampled, lets resolve it down to single sample
                                        textureResolved = new Texture2D(texture.Device, new Texture2DDescription()
                                        {
                                            CpuAccessFlags    = CpuAccessFlags.None,
                                            Format            = texture.Description.Format,
                                            Height            = texture.Description.Height,
                                            Usage             = ResourceUsage.Default,
                                            Width             = texture.Description.Width,
                                            ArraySize         = 1,
                                            SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                                            BindFlags         = BindFlags.None,
                                            MipLevels         = 1,
                                            OptionFlags       = texture.Description.OptionFlags
                                        });
                                        // Resolve into textureResolved
                                        texture.Device.ResolveSubresource(texture, 0, textureResolved, 0, texture.Description.Format);

                                        // Make "theTexture" be the resolved texture
                                        theTexture = textureResolved;
                                    }

                                    //SlimDX.Direct3D10.Device d2 = new SlimDX.Direct3D10_1.Device1(DriverType.Hardware, SlimDX.Direct3D10.DeviceCreationFlags.None, FeatureLevel.Level_10_1);

                                    // Create destination texture
                                    if (textureDest == null)
                                    {
                                        textureDest = new Texture2D(texture.Device, new Texture2DDescription()
                                        {
                                            CpuAccessFlags    = CpuAccessFlags.Read,                     //CpuAccessFlags.Read,
                                            Format            = SlimDX.DXGI.Format.R8G8B8A8_UNorm,       // Supports BMP/PNG
                                            Height            = regionToCaptureDest.Height,
                                            Usage             = ResourceUsage.Staging,                   // ResourceUsage.Default,
                                            Width             = regionToCaptureDest.Width,
                                            ArraySize         = 1,                                       //texture.Description.ArraySize,
                                            SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // texture.Description.SampleDescription,
                                            BindFlags         = BindFlags.None,
                                            MipLevels         = 1,                                       //texture.Description.MipLevels,
                                            OptionFlags       = texture.Description.OptionFlags          //| ResourceOptionFlags.GdiCompatible
                                        });
                                    }


                                    Texture2D theTexture2 = new Texture2D(texture.Device, new Texture2DDescription()
                                    {
                                        CpuAccessFlags    = CpuAccessFlags.None,
                                        Format            = SlimDX.DXGI.Format.R8G8B8A8_UNorm,//texture.Description.Format,
                                        Height            = regionToCaptureDest.Height,
                                        Usage             = ResourceUsage.Default,
                                        Width             = regionToCaptureDest.Width,
                                        ArraySize         = 1,
                                        SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                                        BindFlags         = BindFlags.None,
                                        MipLevels         = 1,
                                        OptionFlags       = texture.Description.OptionFlags //| ResourceOptionFlags.GdiCompatible
                                    });

                                    Result r = SlimDX.Direct3D10.Resource.LoadTextureFromTexture(theTexture, theTexture2,
                                                                                                 new TextureLoadInformation()
                                    {
                                        SourceRegion = new ResourceRegion()
                                        {
                                            Top    = regionToCapture.Top,
                                            Bottom = regionToCapture.Bottom,
                                            Left   = regionToCapture.Left,
                                            Right  = regionToCapture.Right,
                                            Front  = 0,
                                            Back   = 1   // Must be 1 or only black will be copied
                                        },
                                        DestinationRegion = new ResourceRegion()
                                        {
                                            Top    = regionToCaptureDest.Top,
                                            Bottom = regionToCaptureDest.Bottom,
                                            Left   = regionToCaptureDest.Left,
                                            Right  = regionToCaptureDest.Right,
                                            Front  = 0,
                                            Back   = 1   // Must be 1 or only black will be copied
                                        },
                                        ElementCount            = 1,
                                        Filter                  = FilterFlags.Linear,
                                        FirstDestinationElement = 0,
                                        FirstDestinationMip     = 0,
                                        FirstSourceElement      = 0,
                                        FirstSourceMip          = 0,
                                        MipCount                = 1,
                                        MipFilter               = FilterFlags.Linear
                                    });
                                    DebugMessage("Result: " + r.ToString());
                                    // Copy the subresource region, we are dealing with a flat 2D texture with no MipMapping, so 0 is the subresource index
                                    theTexture.Device.CopySubresourceRegion(theTexture2, 0, new ResourceRegion()
                                    {
                                        Top    = regionToCaptureDest.Top,
                                        Bottom = regionToCaptureDest.Bottom,
                                        Left   = regionToCaptureDest.Left,
                                        Right  = regionToCaptureDest.Right,
                                        Front  = 0,
                                        Back   = 1 // Must be 1 or only black will be copied
                                    }, textureDest, 0, 0, 0, 0);
                                    theTexture.Device.CopyResource(theTexture, textureDest);

                                    #region copy f*****g texture to f*****g bitmap and save it


                                    DataRectangle dr   = textureDest.Map(0, MapMode.Read, SlimDX.Direct3D10.MapFlags.None);
                                    IntPtr        data = dr.Data.DataPointer;

                                    int width  = textureDest.Description.Width;
                                    int height = textureDest.Description.Height;


                                    //WriteableBitmap wbmap = new WriteableBitmap(width, height, 300, 300, PixelFormats.Bgra32, null);
                                    //CopyMemory(wbmap.BackBuffer, data, (uint)(width * height * 4));


                                    if (bitmap == null)
                                    {
                                        bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
                                        dd     = new byte[width * height * 4];
                                    }
                                    Marshal.Copy(data, dd, 0, dd.Length);

                                    textureDest.Unmap(0);

                                    for (int i = 0; i < dd.Length; i += 4)
                                    {
                                        byte tmp = dd[i];
                                        dd[i]     = dd[i + 2];
                                        dd[i + 2] = tmp;
                                    }

                                    BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat);

                                    Marshal.Copy(dd, 0, bd.Scan0, dd.Length);
                                    //CopyMemory(bd.Scan0, data, (uint)(width * height * 4));
                                    bitmap.UnlockBits(bd);

                                    //textureDest.Unmap(0);



                                    //FileStream stream = new FileStream(@"c:\temp\new.png", FileMode.Create);
                                    //PngBitmapEncoder encoder = new PngBitmapEncoder();
                                    ////TextBlock myTextBlock = new TextBlock();
                                    ////myTextBlock.Text = "Codec Author is: " + encoder.CodecInfo.Author.ToString();
                                    //encoder.Interlace = PngInterlaceOption.On;
                                    //encoder.Frames.Add(BitmapFrame.Create(wbmap));
                                    //encoder.Save(stream);

                                    SaveFile();
                                    #endregion

                                    //Texture2D.ToFile(textureDest, ImageFileFormat.Png, @"c:\temp\dx10.png");
                                    //Texture2D.ToFile(textureDest, GetImageFileFormat(this.Request.Format), this.Request.FileName);

                                    // Make sure we free up the resolved texture if it was created
                                    if (textureResolved != null)
                                    {
                                        textureResolved.Dispose();
                                        textureResolved = null;
                                    }
                                }



                                this.DebugMessage("PresentHook: Copy BackBuffer time: " + (DateTime.Now - startTime).ToString());
                                this.DebugMessage("PresentHook: Request End");
                            }
                            finally
                            {
                                // Prevent the request from being processed a second time
                                this.Request = null;
                            }
                        }
                        #endregion

                        #region Draw the f*****g overlay
                        using (Texture2D texture = Texture2D.FromSwapChain <SlimDX.Direct3D10.Texture2D>(swapChain, 0))
                        {
                            DrawOverlay(texture);
                            //DrawSprite(texture.Device);
                        }
                        #endregion

                        #region Example: Draw overlay (after screenshot so we don't capture overlay as well)
                        //if (this.ShowOverlay)
                        //{
                        //    using (Texture2D texture = Texture2D.FromSwapChain<SlimDX.Direct3D10.Texture2D>(swapChain, 0))
                        //    {
                        //        if (_lastFrame != null)
                        //        {
                        //            FontDescription fd = new SlimDX.Direct3D10.FontDescription()
                        //            {
                        //                Height = 16,
                        //                FaceName = "Times New Roman",
                        //                IsItalic = false,
                        //                Width = 0,
                        //                MipLevels = 1,
                        //                CharacterSet = SlimDX.Direct3D10.FontCharacterSet.Default,
                        //                Precision = SlimDX.Direct3D10.FontPrecision.Default,
                        //                Quality = SlimDX.Direct3D10.FontQuality.Antialiased,
                        //                PitchAndFamily = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare
                        //            };

                        //            using (Font font = new Font(texture.Device, fd))
                        //            {
                        //                DrawText(font, new Vector2(100, 100), String.Format("{0}", DateTime.Now), new Color4(System.Drawing.Color.Red.R, System.Drawing.Color.Red.G, System.Drawing.Color.Red.B, System.Drawing.Color.Red.A));
                        //            }
                        //        }
                        //        _lastFrame = DateTime.Now;
                        //    }
                        //}
                        #endregion
                    }
                    catch (Exception e)
                    {
                        // If there is an error we do not want to crash the hooked application, so swallow the exception
                        this.DebugMessage(e.ToString());
                    }

                    // As always we need to call the original method, note that EasyHook has already repatched the original method
                    // so calling it here will not cause an endless recursion to this function
                    return(swapChain.Present(syncInterval, flags).Code);
                }
            }
            catch (Exception ex)
            {
                DebugMessage(ex.ToString());
                return(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
            }
        }