예제 #1
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, SharpDX.DXGI.PresentFlags flags)
        {
            this.Frame();
            SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;
            {
                try
                {
                    #region Draw overlay
                    using (Texture2D texture = Texture2D.FromSwapChain <SharpDX.Direct3D10.Texture2D>(swapChain, 0))
                    {
                        foreach (var text in Texts)
                        {
                            using (Font font = new Font(texture.Device, text.FontDescription))
                            {
                                DrawText(font, text.Position, text.Text, text.Color);
                            }
                        }
                    }
                    #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
                swapChain.Present(syncInterval, flags);
                return(SharpDX.Result.Ok.Code);
            }
        }
예제 #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, SharpDX.DXGI.PresentFlags flags)
        {
            this.Frame();
            SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;

            try
            {
                #region Draw overlay (after screenshot so we don't capture overlay as well)
                // Initialise Overlay Engine
                if (_swapChainPointer != swapChain.NativePointer || OverlayEngine == null)
                {
                    if (OverlayEngine != null)
                    {
                        OverlayEngine.Dispose();
                    }

                    OverlayEngine = new DX11.DXOverlayEngine();
                    OverlayEngine.Overlays.Add(new DirectXHook.Hook.Common.Overlay
                    {
                        Elements =
                        {
                            new Common.ImageElement(new Bitmap(1920,                  1080))
                            {
                                Location = new System.Drawing.Point(0,                                                          0)
                            },
                            //new Common.TextElement(new System.Drawing.Font("Times New Roman", 22)) { Text = "Test", Location = new System.Drawing.Point(200, 200), Color = System.Drawing.Color.Yellow, AntiAliased = false},
                            new Common.FramesPerSecond(new System.Drawing.Font("Arial",                  16))
                            {
                                Location = new System.Drawing.Point(5, 5), Color = System.Drawing.Color.Red, AntiAliased = true
                            },
                        }
                    });
                    OverlayEngine.Initialise(swapChain);

                    _swapChainPointer = swapChain.NativePointer;
                }

                // Draw Overlay(s)
                else if (OverlayEngine != null)
                {
                    foreach (var overlay in OverlayEngine.Overlays)
                    {
                        overlay.Frame();
                    }
                    OverlayEngine.Draw();
                }
                #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.ToString());
                //return unchecked((int)0x8000FFFF); //E_UNEXPECTED
            }

            // As always we need to call the original method, note that EasyHook will automatically skip the hook and call the original method
            // i.e. calling it here will not cause a stack overflow into this function
            return(DXGISwapChain_PresentHook.Original(swapChainPtr, syncInterval, flags));
        }
예제 #3
0
        private int Detour_Present(IntPtr swapChainPtr, int syncInterval, SharpDX.DXGI.PresentFlags flags)
        {
            SwapChain swapChain = (SwapChain)swapChainPtr;

            DrawFramesPerSecond(swapChain);

            return(_d3DPresentHook.Original(swapChainPtr, syncInterval, flags));
        }
예제 #4
0
        private void CreateSwapChain(IntPtr window, bool vsync)
        {
            using (SharpDX.DXGI.Factory4 factory = new Factory4())
            {
                //SharpDX.DXGI.Adapter adapter = factory.GetAdapterByLuid(_dev.AdapterLuid);
                //System.Console.WriteLine($"  Adapter: {adapter.Description.Description}");
                System.Console.WriteLine($"  Adapter: {factory.Adapters[0].Description.Description}");

                if (!vsync)
                {
                    using (SharpDX.DXGI.Factory5 factory5 = factory.QueryInterface <Factory5>())
                    {
                        if (factory5 != null)
                        {
                            SharpDX.Mathematics.Interop.RawBool tearing = false;
                            GCHandle pinnedInt = GCHandle.Alloc(tearing, GCHandleType.Pinned);
                            IntPtr   pointer   = pinnedInt.AddrOfPinnedObject();

                            factory5.CheckFeatureSupport(SharpDX.DXGI.Feature.PresentAllowTearing, pointer, System.Runtime.InteropServices.Marshal.SizeOf(tearing));
                            if (tearing != false)
                            {
                                _swapChainFlags = SharpDX.DXGI.SwapChainFlags.AllowTearing;
                                _presentFlags   = SharpDX.DXGI.PresentFlags.AllowTearing;
                            }

                            pinnedInt.Free();
                        }
                    }

                    _syncInterval = 0;
                }
                else
                {
                    _syncInterval = 1;
                }

                SharpDX.DXGI.SwapChainDescription1 desc = new SharpDX.DXGI.SwapChainDescription1();
                desc.Width             = 0;
                desc.Height            = 0;
                desc.Format            = SharpDX.DXGI.Format.R8G8B8A8_UNorm;
                desc.Stereo            = false;
                desc.SampleDescription = new SampleDescription {
                    Count = 1, Quality = 0
                };
                desc.Usage       = SharpDX.DXGI.Usage.RenderTargetOutput;
                desc.BufferCount = FrameCount;
                desc.Scaling     = SharpDX.DXGI.Scaling.Stretch;
                desc.SwapEffect  = SharpDX.DXGI.SwapEffect.FlipDiscard;
                desc.AlphaMode   = SharpDX.DXGI.AlphaMode.Unspecified;
                desc.Flags       = _swapChainFlags;

                using (SharpDX.DXGI.SwapChain1 swapChain = new SharpDX.DXGI.SwapChain1(factory, _queue, window, ref desc))
                {
                    factory.MakeWindowAssociation(window, WindowAssociationFlags.IgnoreAltEnter);
                    _swapChain = swapChain.QueryInterface <SharpDX.DXGI.SwapChain3>();
                }
            }
        }
예제 #5
0
        int PresentHook(IntPtr swapChainPtr, int syncInterval, SharpDX.DXGI.PresentFlags flags)
        {
            SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;

            //SharpDX.Direct3D11.Device device = swapChain.GetDevice<SharpDX.Direct3D11.Device>();

            if (!closed)
            {
                if (dx11gui == null)
                {
                    dx11gui = new DX11GUI(swapChain);
                }

                dx11gui.RenderCrosshair();

                connection.getFPS = fpsTool.getFPS();
                fpsTool.limitFPS();
            }

            swapChain.Present(syncInterval, flags);
            return(SharpDX.Result.Ok.Code);
        }
예제 #6
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, SharpDX.DXGI.PresentFlags flags)
        {
            this.Frame();
            SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;

            try
            {
                #region Screenshot Request
                if (this.Request != null)
                {
                    this.DebugMessage("PresentHook: Request Start");
                    DateTime startTime = DateTime.Now;
                    using (Texture2D currentRT = Texture2D.FromSwapChain <Texture2D>(swapChain, 0))
                    {
                        #region Determine region to capture
                        Rectangle captureRegion = new Rectangle(0, 0, currentRT.Description.Width, currentRT.Description.Height);

                        if (this.Request.RegionToCapture.Width > 0)
                        {
                            captureRegion = new Rectangle(this.Request.RegionToCapture.Left, this.Request.RegionToCapture.Top, this.Request.RegionToCapture.Right, this.Request.RegionToCapture.Bottom);
                        }
                        else if (this.Request.Resize.HasValue)
                        {
                            captureRegion = new Rectangle(0, 0, this.Request.Resize.Value.Width, this.Request.Resize.Value.Height);
                        }
                        #endregion

                        // Create / Recreate resources as necessary
                        EnsureResources(currentRT.Device, currentRT.Description, captureRegion, Request);

                        Texture2D sourceTexture = null;

                        // If texture is multisampled, then we can use ResolveSubresource to copy it into a non-multisampled texture
                        if (currentRT.Description.SampleDescription.Count > 1 || Request.Resize.HasValue)
                        {
                            if (Request.Resize.HasValue)
                            {
                                this.DebugMessage("PresentHook: resizing texture");
                            }
                            else
                            {
                                this.DebugMessage("PresentHook: resolving multi-sampled texture");
                            }

                            // Resolve into _resolvedRT
                            if (_resolvedRTKeyedMutex != null)
                            {
                                _resolvedRTKeyedMutex.Acquire(0, int.MaxValue);
                            }
                            currentRT.Device.ImmediateContext.ResolveSubresource(currentRT, 0, _resolvedRT, 0, _resolvedRT.Description.Format);
                            if (_resolvedRTKeyedMutex != null)
                            {
                                _resolvedRTKeyedMutex.Release(1);
                            }

                            if (Request.Resize.HasValue)
                            {
                                lock (_lock)
                                {
                                    if (_resolvedRTKeyedMutex_Dev2 != null)
                                    {
                                        _resolvedRTKeyedMutex_Dev2.Acquire(1, int.MaxValue);
                                    }
                                    _saQuad.ShaderResource   = _resolvedSharedSRV;
                                    _saQuad.RenderTargetView = _resizedRTV;
                                    _saQuad.RenderTarget     = _resizedRT;
                                    _saQuad.Render();
                                    if (_resolvedRTKeyedMutex_Dev2 != null)
                                    {
                                        _resolvedRTKeyedMutex_Dev2.Release(0);
                                    }
                                }

                                // set sourceTexture to the resized RT
                                sourceTexture = _resizedRT;
                            }
                            else
                            {
                                // Make sourceTexture be the resolved texture
                                sourceTexture = _resolvedRTShared;
                            }
                        }
                        else
                        {
                            // Copy the resource into the shared texture
                            if (_resolvedRTKeyedMutex != null)
                            {
                                _resolvedRTKeyedMutex.Acquire(0, int.MaxValue);
                            }
                            currentRT.Device.ImmediateContext.CopySubresourceRegion(currentRT, 0, null, _resolvedRT, 0);
                            if (_resolvedRTKeyedMutex != null)
                            {
                                _resolvedRTKeyedMutex.Release(1);
                            }
                            sourceTexture = _resolvedRTShared;
                        }

                        // 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
                        _requestCopy = this.Request.Clone(); // this.Request gets set to null, so copy the Request for use in the thread

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

                        bool acquireLock = sourceTexture == _resolvedRTShared;

                        ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
                        {
                            // Acquire lock on second device
                            if (acquireLock && _resolvedRTKeyedMutex_Dev2 != null)
                            {
                                _resolvedRTKeyedMutex_Dev2.Acquire(1, int.MaxValue);
                            }

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

                                // Release lock upon shared surface on second device
                                if (acquireLock && _resolvedRTKeyedMutex_Dev2 != null)
                                {
                                    _resolvedRTKeyedMutex_Dev2.Release(0);
                                }

                                _finalRT.Device.ImmediateContext.End(_query);
                                _queryIssued = true;
                                while (!_finalRT.Device.ImmediateContext.GetData(_query).ReadBoolean())
                                {
                                    // Spin (usually no spin takes place)
                                }

                                DateTime startCopyToSystemMemory = DateTime.Now;
                                try
                                {
                                    DataBox db = default(DataBox);
                                    //Arvy added to support features required by average color capture
                                    if (_requestCopy.Format == ImageFormat.PixelData || _requestCopy.Format == ImageFormat.AverageColor)
                                    {
                                        db             = _finalRT.Device.ImmediateContext.MapSubresource(_finalRT, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.DoNotWait);
                                        _finalRTMapped = true;
                                    }
                                    _queryIssued = false;

                                    try
                                    {
                                        using (MemoryStream ms = new MemoryStream())
                                        {
                                            switch (_requestCopy.Format)
                                            {
                                            case ImageFormat.Bitmap:
                                                Texture2D.ToStream(_finalRT.Device.ImmediateContext, _finalRT, ImageFileFormat.Bmp, ms);
                                                break;

                                            case ImageFormat.Jpeg:
                                                Texture2D.ToStream(_finalRT.Device.ImmediateContext, _finalRT, ImageFileFormat.Jpg, ms);
                                                break;

                                            case ImageFormat.Png:
                                                Texture2D.ToStream(_finalRT.Device.ImmediateContext, _finalRT, ImageFileFormat.Png, ms);
                                                break;

                                            case ImageFormat.PixelData:
                                            //Arvy added to support features required by average color capture
                                            case ImageFormat.AverageColor:
                                                if (db.DataPointer != IntPtr.Zero)
                                                {
                                                    ProcessCapture(_finalRT.Description.Width, _finalRT.Description.Height, db.RowPitch, System.Drawing.Imaging.PixelFormat.Format32bppArgb, db.DataPointer, _requestCopy);
                                                }
                                                return;
                                            }
                                            ms.Position = 0;
                                            ProcessCapture(ms, _requestCopy);
                                        }
                                    }
                                    finally
                                    {
                                        this.DebugMessage("PresentHook: Copy to System Memory time: " + (DateTime.Now - startCopyToSystemMemory).ToString());
                                    }

                                    if (_finalRTMapped)
                                    {
                                        lock (_lock)
                                        {
                                            _finalRT.Device.ImmediateContext.UnmapSubresource(_finalRT, 0);
                                            _finalRTMapped = false;
                                        }
                                    }
                                }
                                catch (SharpDX.SharpDXException exc)
                                {
                                    // Catch DXGI_ERROR_WAS_STILL_DRAWING and ignore - the data isn't available yet
                                }
                            }
                        }));


                        // Note: it would be possible to capture multiple frames and process them in a background thread
                    }
                    this.DebugMessage("PresentHook: Copy BackBuffer time: " + (DateTime.Now - startTime).ToString());
                    this.DebugMessage("PresentHook: Request End");
                }
                #endregion

                #region Draw overlay (after screenshot so we don't capture overlay as well)
                if (this.Config.ShowOverlay)
                {
                    // Initialise Overlay Engine
                    if (_swapChainPointer != swapChain.NativePointer || _overlayEngine == null)
                    {
                        if (_overlayEngine != null)
                        {
                            _overlayEngine.Dispose();
                        }

                        _overlayEngine = new DX11.DXOverlayEngine();
                        _overlayEngine.Overlays.Add(new Capture.Hook.Common.Overlay
                        {
                            Elements =
                            {
                                //new Capture.Hook.Common.TextElement(new System.Drawing.Font("Times New Roman", 22)) { Text = "Test", Location = new System.Drawing.Point(200, 200), Color = System.Drawing.Color.Yellow, AntiAliased = false},
                                new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial",                               16))
                                {
                                    Location = new System.Drawing.Point(5, 5), Color = System.Drawing.Color.Red, AntiAliased = true
                                },
                                //new Capture.Hook.Common.ImageElement(@"C:\Temp\test.bmp") { Location = new System.Drawing.Point(20, 20) }
                            }
                        });
                        _overlayEngine.Initialise(swapChain);

                        _swapChainPointer = swapChain.NativePointer;
                    }
                    // Draw Overlay(s)
                    else if (_overlayEngine != null)
                    {
                        foreach (var overlay in _overlayEngine.Overlays)
                        {
                            overlay.Frame();
                        }
                        _overlayEngine.Draw();
                    }
                }
                #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.ToString());
                //return unchecked((int)0x8000FFFF); //E_UNEXPECTED
            }

            // As always we need to call the original method, note that EasyHook will automatically skip the hook and call the original method
            // i.e. calling it here will not cause a stack overflow into this function
            return(DXGISwapChain_PresentHook.Original(swapChainPtr, syncInterval, flags));
        }
예제 #7
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, SharpDX.DXGI.PresentFlags flags)
        {
            this.Frame();
            SwapChain3 swapChain = (SharpDX.DXGI.SwapChain3)swapChainPtr;

            //if (!init)
            //{
            //    InitText(swapChain);
            //}

            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 SharpDX.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 = SharpDX.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 SharpDX.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;
                //                ProcessCapture(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 Draw overlay (after screenshot so we don't capture overlay as well)
                if (this.Config.ShowOverlay)
                {
                    // Initialise Overlay Engine
                    if (_swapChainPointer != swapChain.NativePointer || _overlayEngine == null)
                    {
                        if (_overlayEngine != null)
                        {
                            _overlayEngine.Dispose();
                        }

                        _overlayEngine = new DX11.DXOverlayEngine();
                        _overlayEngine.Overlays.Add(new Common.Overlay
                        {
                            Elements =
                            {
                                //new Common.TextElement(new System.Drawing.Font("Times New Roman", 22)) { Text = "Test", Location = new System.Drawing.Point(200, 200), Color = System.Drawing.Color.Yellow, AntiAliased = false},
                                new Common.FramesPerSecond(new System.Drawing.Font("Arial",                  12))
                                {
                                    Location = new System.Drawing.Point(5, 5), Color = System.Drawing.Color.Red, AntiAliased = true
                                },
                                //new Common.ProcessLoad(new System.Drawing.Font("Arial", 12)){ Location = new System.Drawing.Point(5,20), Color = System.Drawing.Color.Red, AntiAliased = true },
                                ProcessLoad
                            }
                        });
                        _overlayEngine.Initialise(swapChain);

                        _swapChainPointer = swapChain.NativePointer;
                    }
                    // Draw Overlay(s)
                    else if (_overlayEngine != null)
                    {
                        foreach (var overlay in _overlayEngine.Overlays)
                        {
                            overlay.Frame();
                        }
                        _overlayEngine.Draw();
                    }

                    //direct2DRenderTarget[frameIndex].BeginDraw();
                    //int time = Environment.TickCount % 10000;
                    //int t = time / 2000;
                    //float f = (time - (t * 2000)) / 2000.0F;
                    //textBrush.Color = Color4.Lerp(colors[t], colors[t + 1], f);
                    //direct2DRenderTarget[frameIndex].DrawText("Hello Text", textFormat, new SharpDX.Mathematics.Interop.RawRectangleF((float)Math.Sin(Environment.TickCount / 1000.0F) * 200 + 400, 10, 2000, 500), textBrush);
                    //direct2DRenderTarget[frameIndex].EndDraw();
                }
                #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.ToString());
                //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
            swapChain.Present(syncInterval, flags);
            return(SharpDX.Result.Ok.Code);
        }
예제 #8
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, SharpDX.DXGI.PresentFlags flags)
        {
            this.Frame();
            SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;
            {
                try
                {
                    #region Screenshot Request
                    //if (this.Request != null)
                    //{
                    //    try
                    //    {
                    //        this.DebugMessage("PresentHook: Request Start");
                    //        DateTime startTime = DateTime.Now;
                    //        using (Texture2D texture = Texture2D.FromSwapChain<SharpDX.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 SharpDX.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 = SharpDX.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 SharpDX.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;
                    //                    ProcessCapture(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.Config.ShowOverlay)
                    {
                        using (Texture2D texture = Texture2D.FromSwapChain <SharpDX.Direct3D10.Texture2D>(swapChain, 0))
                        {
                            if (FPS.GetFPS() >= 1)
                            {
                                FontDescription fd = new SharpDX.Direct3D10.FontDescription()
                                {
                                    Height          = 16,
                                    FaceName        = "Arial",
                                    Italic          = false,
                                    Width           = 0,
                                    MipLevels       = 1,
                                    CharacterSet    = SharpDX.Direct3D10.FontCharacterSet.Default,
                                    OutputPrecision = SharpDX.Direct3D10.FontPrecision.Default,
                                    Quality         = SharpDX.Direct3D10.FontQuality.Antialiased,
                                    PitchAndFamily  = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare,
                                    Weight          = FontWeight.Bold
                                };

                                // TODO: do not create font every frame!
                                using (Font font = new Font(texture.Device, fd))
                                {
                                    DrawText(font, new Vector2(5, 5), String.Format("{0:N0} fps", FPS.GetFPS()), new Color4(Color.Red.ToColor3()));

                                    if (this.TextDisplay != null && this.TextDisplay.Display)
                                    {
                                        DrawText(font, new Vector2(5, 25), this.TextDisplay.Text, new Color4(Color.Red.ToColor3(), (Math.Abs(1.0f - TextDisplay.Remaining))));
                                    }
                                }
                            }
                        }
                    }
                    #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
                swapChain.Present(syncInterval, flags);
                return(SharpDX.Result.Ok.Code);
            }
        }