Beispiel #1
0
        /// <summary>
        /// Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx)
        /// </summary>
        /// <param name="device"></param>
        void DoCaptureRenderTarget(Device device, string hook)
        {
            this.Frame();
            
            try
            {
                #region Screenshot Request

                // If we have issued the command to copy data to our render target, check if it is complete
                bool qryResult;
                if (_queryIssued && _requestCopy != null && _query.GetData(out qryResult, false))
                {
                    // The GPU has finished copying data to _renderTargetCopy, we can now lock
                    // the data and access it on another thread.

                    _queryIssued = false;
                    
                    // Lock the render target
                    SharpDX.Rectangle rect;
                    SharpDX.DataRectangle lockedRect = LockRenderTarget(_renderTargetCopy, out rect);
                    _renderTargetCopyLocked = true;

                    // Copy the data from the render target
                    System.Threading.Tasks.Task.Factory.StartNew(() =>
                    {
                        lock (_lockRenderTarget)
                        {
                            ProcessCapture(rect.Width, rect.Height, lockedRect.Pitch, _renderTargetCopy.Description.Format.ToPixelFormat(), lockedRect.DataPointer, _requestCopy);
                        }
                    });
                }

                // Single frame capture request
                if (this.Request != null)
                {
                    DateTime start = DateTime.Now;
                    try
                    {
                        using (Surface renderTarget = device.GetRenderTarget(0))
                        {
                            int width, height;

                            // If resizing of the captured image, determine correct dimensions
                            if (Request.Resize != null && (renderTarget.Description.Width > Request.Resize.Value.Width || renderTarget.Description.Height > Request.Resize.Value.Height))
                            {
                                if (renderTarget.Description.Width > Request.Resize.Value.Width)
                                {
                                    width = Request.Resize.Value.Width;
                                    height = (int)Math.Round((renderTarget.Description.Height * ((double)Request.Resize.Value.Width / (double)renderTarget.Description.Width)));
                                }
                                else
                                {
                                    height = Request.Resize.Value.Height;
                                    width = (int)Math.Round((renderTarget.Description.Width * ((double)Request.Resize.Value.Height / (double)renderTarget.Description.Height)));
                                }
                            }
                            else
                            {
                                width = renderTarget.Description.Width;
                                height = renderTarget.Description.Height;
                            }

                            // If existing _renderTargetCopy, ensure that it is the correct size and format
                            if (_renderTargetCopy != null && (_renderTargetCopy.Description.Width != width || _renderTargetCopy.Description.Height != height || _renderTargetCopy.Description.Format != renderTarget.Description.Format))
                            {
                                // Cleanup resources
                                Cleanup();
                            }

                            // Ensure that we have something to put the render target data into
                            if (!_resourcesInitialised || _renderTargetCopy == null)
                            {
                                CreateResources(device, width, height, renderTarget.Description.Format);
                            }

                            // Resize from render target Surface to resolvedSurface (also deals with resolving multi-sampling)
                            device.StretchRectangle(renderTarget, _resolvedTarget, TextureFilter.None);
                        }

                        // If the render target is locked from a previous request unlock it
                        if (_renderTargetCopyLocked)
                        {
                            // Wait for the the ProcessCapture thread to finish with it
                            lock (_lockRenderTarget)
                            {
                                if (_renderTargetCopyLocked)
                                {
                                    _renderTargetCopy.UnlockRectangle();
                                    _renderTargetCopyLocked = false;
                                }
                            }
                        }
                            
                        // Copy data from resolved target to our render target copy
                        device.GetRenderTargetData(_resolvedTarget, _renderTargetCopy);

                        _requestCopy = Request.Clone();
                        _query.Issue(Issue.End);
                        _queryIssued = true;
                        
                    }
                    finally
                    {
                        // We have completed the request - mark it as null so we do not continue to try to capture the same request
                        // Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
                        //         and send back to the host application as needed. The IPC overhead significantly slows down 
                        //         the whole process if sending frame by frame.
                        Request = null;
                    }
                    DateTime end = DateTime.Now;
                    this.DebugMessage(hook + ": Capture time: " + (end - start).ToString());
                }

                #endregion

                if (this.Config.ShowOverlay)
                {
                    #region Draw Overlay

                    // Check if overlay needs to be initialised
                    if (_overlayEngine == null || _overlayEngine.Device.NativePointer != device.NativePointer)
                    {
                        // Cleanup if necessary
                        if (_overlayEngine != null)
                            RemoveAndDispose(ref _overlayEngine);

                        _overlayEngine = ToDispose(new DX9.DXOverlayEngine());
                        // Create Overlay
                        _overlayEngine.Overlays.Add(new Capture.Hook.Common.Overlay
                        {
                            Elements =
                            {
                                // Add frame rate
                                new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 14, FontStyle.Bold)) { Location = new System.Drawing.Point(5,5), Color = System.Drawing.Color.Red, AntiAliased = true }/*,
                                new Capture.Hook.Common.TextElement(new System.Drawing.Font("Arial", 16, FontStyle.Bold))
                                {
                                    Location = new Point(20, 50),
                                    Color = Color.Yellow,
                                    Text = "Test"
                                }*/
                                // Example of adding an image to overlay (can implement semi transparency with Tint, e.g. Ting = Color.FromArgb(127, 255, 255, 255))
                                //new Capture.Hook.Common.ImageElement(@"C:\Temp\test.bmp") { Location = new System.Drawing.Point(20, 20) }
                            }
                        });

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

                    #endregion
                }
            }
            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
        private void HandleCaptureRequest(Device device)
        {
            try
            {
                for (int i = 0; i < BUFFERS; i++)
                {
                    bool tmp;
                    if (this.issuedQueries[i] && this.queries[i].GetData(out tmp, false))
                    {
                        this.issuedQueries[i] = false;
                        try
                        {
                            var lockedRect = this.surfaces[i].LockRectangle(LockFlags.ReadOnly);
                            this.surfaceDataPointer = lockedRect.DataPointer;
                            this.currentSurface = i;
                            this.surfaceLocked[i] = true;
                        }
                        catch (Exception ex)
                        {
                            DebugMessage(ex.ToString());
                        }
                    }
                }

                if (previousRequestId != null || lastRequestId != null)
                {
                    this.previousRequestId = null;
                    int nextCapture = (curCapture == BUFFERS - 1) ? 0 : (curCapture + 1);

                    var sourceTexture = copySurfaces[curCapture];
                    try
                    {
                        using (var backbuffer = device.GetBackBuffer(0, 0))
                        {
                            device.StretchRectangle(backbuffer, sourceTexture, TextureFilter.None);
                        }

                        if (copyWait < BUFFERS - 1)
                        {
                            copyWait++;
                        }
                        else
                        {
                            var prevSourceTexture = copySurfaces[nextCapture];
                            var targetTexture = surfaces[nextCapture];

                            if (this.surfaceLocked[nextCapture])
                            {
                                lock (this.surfaceLocks[nextCapture])
                                {
                                    this.surfaces[nextCapture].UnlockRectangle();
                                    this.surfaceLocked[nextCapture] = false;
                                }
                            }

                            try
                            {
                                device.GetRenderTargetData(prevSourceTexture, targetTexture);
                            }
                            catch (Exception ex)
                            {
                                DebugMessage(ex.ToString());
                            }

                            this.queries[nextCapture].Issue(Issue.End);
                            this.issuedQueries[nextCapture] = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        this.DebugMessage(ex.ToString());
                    }

                    curCapture = nextCapture;
                }

            }
            catch (Exception e)
            {
                this.DebugMessage(e.ToString());
            }
        }
Beispiel #3
0
        /// <summary>
        ///     Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx)
        /// </summary>
        /// <param name="device"></param>
        private void DoCaptureRenderTarget(Device device, string hook)
        {
            Frame();

            try
            {
                #region Screenshot Request

                // If we have issued the command to copy data to our render target, check if it is complete
                bool qryResult;
                if (_queryIssued && _requestCopy != null && _query.GetData(out qryResult, false))
                {
                    // The GPU has finished copying data to _renderTargetCopy, we can now lock
                    // the data and access it on another thread.

                    _queryIssued = false;

                    // Lock the render target
                    Rectangle rect;
                    var lockedRect = LockRenderTarget(_renderTargetCopy, out rect);
                    _renderTargetCopyLocked = true;

                    // Copy the data from the render target
                    Task.Factory.StartNew(() =>
                    {
                        lock (_lockRenderTarget)
                        {
                            ProcessCapture(rect.Width, rect.Height, lockedRect.Pitch,
                                _renderTargetCopy.Description.Format.ToPixelFormat(), lockedRect.DataPointer,
                                _requestCopy);
                        }
                    });
                }

                // Single frame capture request
                if (Request != null)
                {
                    var start = DateTime.Now;
                    try
                    {
                        using (var renderTarget = device.GetRenderTarget(0))
                        {
                            int width, height;

                            // If resizing of the captured image, determine correct dimensions
                            if (Request.Resize != null &&
                                (renderTarget.Description.Width > Request.Resize.Value.Width ||
                                 renderTarget.Description.Height > Request.Resize.Value.Height))
                            {
                                if (renderTarget.Description.Width > Request.Resize.Value.Width)
                                {
                                    width = Request.Resize.Value.Width;
                                    height =
                                        (int)
                                            Math.Round((renderTarget.Description.Height*
                                                        (Request.Resize.Value.Width/
                                                         (double) renderTarget.Description.Width)));
                                }
                                else
                                {
                                    height = Request.Resize.Value.Height;
                                    width =
                                        (int)
                                            Math.Round((renderTarget.Description.Width*
                                                        (Request.Resize.Value.Height/
                                                         (double) renderTarget.Description.Height)));
                                }
                            }
                            else
                            {
                                width = renderTarget.Description.Width;
                                height = renderTarget.Description.Height;
                            }

                            // If existing _renderTargetCopy, ensure that it is the correct size and format
                            if (_renderTargetCopy != null &&
                                (_renderTargetCopy.Description.Width != width ||
                                 _renderTargetCopy.Description.Height != height ||
                                 _renderTargetCopy.Description.Format != renderTarget.Description.Format))
                            {
                                // Cleanup resources
                                Cleanup();
                            }

                            // Ensure that we have something to put the render target data into
                            if (!_resourcesInitialised || _renderTargetCopy == null)
                            {
                                CreateResources(device, width, height, renderTarget.Description.Format);
                            }

                            // Resize from render target Surface to resolvedSurface (also deals with resolving multi-sampling)
                            device.StretchRectangle(renderTarget, _resolvedTarget, TextureFilter.None);
                        }

                        // If the render target is locked from a previous request unlock it
                        if (_renderTargetCopyLocked)
                        {
                            // Wait for the the ProcessCapture thread to finish with it
                            lock (_lockRenderTarget)
                            {
                                if (_renderTargetCopyLocked)
                                {
                                    _renderTargetCopy.UnlockRectangle();
                                    _renderTargetCopyLocked = false;
                                }
                            }
                        }

                        // Copy data from resolved target to our render target copy
                        device.GetRenderTargetData(_resolvedTarget, _renderTargetCopy);

                        _requestCopy = Request.Clone();
                        _query.Issue(Issue.End);
                        _queryIssued = true;
                    }
                    finally
                    {
                        // We have completed the request - mark it as null so we do not continue to try to capture the same request
                        // Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
                        //         and send back to the host application as needed. The IPC overhead significantly slows down
                        //         the whole process if sending frame by frame.
                        Request = null;
                    }
                    var end = DateTime.Now;
                    DebugMessage(hook + ": Capture time: " + (end - start));
                }

                #endregion

                if (Config.ShowOverlay)
                {
                    #region Draw Overlay

                    // Check if overlay needs to be initialised
                    if (_overlayEngine == null
                        || _overlayEngine.Device.NativePointer != device.NativePointer
                        || IsOverlayUpdatePending)
                    {
                        // Cleanup if necessary
                        if (_overlayEngine != null)
                            _overlayEngine.Dispose();

                        _overlayEngine = ToDispose(new DXOverlayEngine());

                        // Create Overlay
                        _overlayEngine.Overlays.Add(new Overlay
                        {
                            Elements = OverlayElements
                        });

                        _overlayEngine.Initialise(device);

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

                    #endregion
                }
            }
            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
        /// <summary>
        /// Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx)
        /// </summary>
        /// <param name="device"></param>
        void DoCaptureRenderTarget(Device device, string hook)
        {
            this.Frame();

            try
            {
                    #region Screenshot Request
                // Single frame capture request
                if (this.Request != null)
                {
                    DateTime start = DateTime.Now;
                    try
                    {

                        using (Surface renderTargetTemp = device.GetRenderTarget(0))
                        {
                            int width, height;

                            // TODO: If resizing the captured image is required it can be adjusted here
                            //if (renderTargetTemp.Description.Width > 1280)
                            //{
                            //    width = 1280;
                            //    height = (int)Math.Round((renderTargetTemp.Description.Height * (1280.0 / renderTargetTemp.Description.Width)));
                            //}
                            //else
                            {
                                width = renderTargetTemp.Description.Width;
                                height = renderTargetTemp.Description.Height;
                            }

                            // First ensure we have a Surface to the render target data into
                            if (_renderTarget == null)
                            {
                                // Create offscreen surface to use as copy of render target data
                                using (SwapChain sc = device.GetSwapChain(0))
                                {
                                    _renderTarget = Surface.CreateOffscreenPlain(device, width, height, sc.PresentParameters.BackBufferFormat, Pool.SystemMemory);
                                }
                            }

                            // Create our resolved surface (resizing if necessary and to resolve any multi-sampling)
                            using (Surface resolvedSurface = Surface.CreateRenderTarget(device, width, height, renderTargetTemp.Description.Format, MultisampleType.None, 0, false))
                            {
                                // Resize from Render Surface to resolvedSurface
                                device.StretchRectangle(renderTargetTemp, resolvedSurface, TextureFilter.None);

                                // Get Render Data
                                device.GetRenderTargetData(resolvedSurface, _renderTarget);
                            }
                        }

                        if (Request != null)
                            ProcessRequest();
                    }
                    finally
                    {
                        // We have completed the request - mark it as null so we do not continue to try to capture the same request
                        // Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
                        //         and send back to the host application as needed. The IPC overhead significantly slows down 
                        //         the whole process if sending frame by frame.
                        Request = null;
                    }
                    DateTime end = DateTime.Now;
                    this.DebugMessage(hook + ": Capture time: " + (end - start).ToString());
                }

                #endregion

                if (this.Config.ShowOverlay)
                {
                    #region Draw frame rate

                    // TODO: font needs to be created and then reused, not created each frame!
                    using (SharpDX.Direct3D9.Font font = new SharpDX.Direct3D9.Font(device, new FontDescription()
                                    {
                                        Height = 16,
                                        FaceName = "Arial",
                                        Italic = false,
                                        Width = 0,
                                        MipLevels = 1,
                                        CharacterSet = FontCharacterSet.Default,
                                        OutputPrecision = FontPrecision.Default,
                                        Quality = FontQuality.Antialiased,
                                        PitchAndFamily = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare,
                                        Weight = FontWeight.Bold
                                    }))
                    {

                        if (this.FPS.GetFPS() >= 1)
                        {
                            font.DrawText(null, String.Format("{0:N0} fps", this.FPS.GetFPS()), 5, 5, SharpDX.Color.Red);
                        }

                        if (this.TextDisplay != null && this.TextDisplay.Display)
                        {
                            font.DrawText(null, this.TextDisplay.Text, 5, 25, new SharpDX.ColorBGRA(255, 0, 0, (byte)Math.Round((Math.Abs(1.0f - TextDisplay.Remaining) * 255f))));
                        }
                    }

                    #endregion
                }
            }
            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
        private void HandleCaptureRequest(Device device)
        {
            try
            {
                bool tmp;
                if (this.queryIssued && this.query.GetData(out tmp, false))
                {
                    this.queryIssued = false;
                    var lockedRect = this.surface.LockRectangle(LockFlags.ReadOnly);
                    this.surfaceDataPointer = lockedRect.DataPointer;
                    this.surfaceLocked = true;

                    this.copyEvent.Set();
                }

                using (var backbuffer = device.GetBackBuffer(0, 0))
                {
                    device.StretchRectangle(backbuffer, this.renderTarget, TextureFilter.None);
                }

                if (this.surfaceLocked)
                {
                    lock (this.renderTargetLock)
                    {
                        if (this.surfaceLocked)
                        {
                            this.surface.UnlockRectangle();
                            this.surfaceLocked = false;
                        }
                    }
                }

                try
                {
                    var cooplevel = device.TestCooperativeLevel();
                    if (cooplevel.Code == ResultCode.Success.Code)
                    {
                        device.GetRenderTargetData(this.renderTarget, this.surface);
                        this.query.Issue(Issue.End);
                        this.queryIssued = true;
                    }
                    else
                    {
                        this.DebugMessage(string.Format("DirectX Error: TestCooperativeLevel = {0}", cooplevel.Code));
                    }
                }
                catch (Exception ex)
                {
                    this.DebugMessage(ex.ToString());
                }
            }
            catch (Exception e)
            {
                this.DebugMessage(e.ToString());
            }
        }
Beispiel #6
0
        /// <summary>
        /// Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx)
        /// </summary>
        /// <param name="device"></param>
        void DoCaptureRenderTarget(Device device, string hook)
        {
            this.Frame();

            try
            {
                #region Screenshot Request

                // If we have issued the command to copy data to our render target, check if it is complete
                bool qryResult;
                if (_queryIssued && _requestCopy != null && _query.GetData(out qryResult, false))
                {
                    // The GPU has finished copying data to _renderTargetCopy, we can now lock
                    // the data and access it on another thread.

                    _queryIssued = false;

                    // Lock the render target
                    SharpDX.Rectangle rect;
                    SharpDX.DataRectangle lockedRect = LockRenderTarget(_renderTargetCopy, out rect);
                    _renderTargetCopyLocked = true;

                    // Copy the data from the render target
                    System.Threading.Tasks.Task.Factory.StartNew(() =>
                    {
                        lock (_lockRenderTarget)
                        {
                            ProcessCapture(rect.Width, rect.Height, lockedRect.Pitch, _renderTargetCopy.Description.Format.ToPixelFormat(), lockedRect.DataPointer, _requestCopy);
                        }
                    });
                }

                // Single frame capture request
                if (this.Request != null)
                {
                    DateTime start = DateTime.Now;
                    try
                    {
                        using (Surface renderTarget = device.GetRenderTarget(0))
                        {
                            int width, height;

                            // If resizing of the captured image, determine correct dimensions
                            if (Request.Resize != null && (renderTarget.Description.Width > Request.Resize.Value.Width || renderTarget.Description.Height > Request.Resize.Value.Height))
                            {
                                if (renderTarget.Description.Width > Request.Resize.Value.Width)
                                {
                                    width = Request.Resize.Value.Width;
                                    height = (int)Math.Round((renderTarget.Description.Height * ((double)Request.Resize.Value.Width / (double)renderTarget.Description.Width)));
                                }
                                else
                                {
                                    height = Request.Resize.Value.Height;
                                    width = (int)Math.Round((renderTarget.Description.Width * ((double)Request.Resize.Value.Height / (double)renderTarget.Description.Height)));
                                }
                            }
                            else
                            {
                                width = renderTarget.Description.Width;
                                height = renderTarget.Description.Height;
                            }

                            // If existing _renderTargetCopy, ensure that it is the correct size and format
                            if (_renderTargetCopy != null && (_renderTargetCopy.Description.Width != width || _renderTargetCopy.Description.Height != height || _renderTargetCopy.Description.Format != renderTarget.Description.Format))
                            {
                                // Cleanup resources
                                Cleanup();
                            }

                            // Ensure that we have something to put the render target data into
                            if (!_resourcesInitialised || _renderTargetCopy == null)
                            {
                                CreateResources(device, width, height, renderTarget.Description.Format);
                            }

                            // Resize from render target Surface to resolvedSurface (also deals with resolving multi-sampling)
                            device.StretchRectangle(renderTarget, _resolvedTarget, TextureFilter.None);
                        }

                        // If the render target is locked from a previous request unlock it
                        if (_renderTargetCopyLocked)
                        {
                            // Wait for the the ProcessCapture thread to finish with it
                            lock (_lockRenderTarget)
                            {
                                if (_renderTargetCopyLocked)
                                {
                                    _renderTargetCopy.UnlockRectangle();
                                    _renderTargetCopyLocked = false;
                                }
                            }
                        }

                        // Copy data from resolved target to our render target copy
                        device.GetRenderTargetData(_resolvedTarget, _renderTargetCopy);

                        _requestCopy = Request.Clone();
                        _query.Issue(Issue.End);
                        _queryIssued = true;

                    }
                    finally
                    {
                        // We have completed the request - mark it as null so we do not continue to try to capture the same request
                        // Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
                        //         and send back to the host application as needed. The IPC overhead significantly slows down
                        //         the whole process if sending frame by frame.
                        Request = null;
                    }
                    DateTime end = DateTime.Now;
                    this.DebugMessage(hook + ": Capture time: " + (end - start).ToString());
                }

                #endregion

                if (this.Config.ShowOverlay)
                {
                    #region Draw frame rate

                    if (_font == null || _font.Device.NativePointer != device.NativePointer)
                        CreateFont(device);

                    if (this.FPS.GetFPS() >= 1)
                    {
                        _font.DrawText(null, String.Format("{0:N0} fps", this.FPS.GetFPS()), 5, 5, SharpDX.Color.Red);
                    }

                    if (this.TextDisplay != null && this.TextDisplay.Display)
                    {
                        _font.DrawText(null, this.TextDisplay.Text, 5, 25, new SharpDX.ColorBGRA(255, 0, 0, (byte)Math.Round((Math.Abs(1.0f - TextDisplay.Remaining) * 255f))));
                    }

                    #endregion
                }
            }
            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
Beispiel #7
0
        private void HandleCaptureRequest(Device device)
        {
            if (Request == null)
            {
                return;
            }
            try
            {
                bool tmp;
                if (queryIssued && query.GetData(out tmp, false))
                {
                    queryIssued = false;
                    var lockedRect = surface.LockRectangle(LockFlags.ReadOnly);
                    surfaceDataPointer = lockedRect.DataPointer;
                    surfaceLocked = true;

                    new Thread(HandleCaptureRequestThread).Start();
                }

                using (var backbuffer = device.GetBackBuffer(0, 0))
                {
                    device.StretchRectangle(backbuffer, renderTarget, TextureFilter.None);
                }

                if (surfaceLocked)
                {
                    lock (renderTargetLock)
                    {
                        if (!this.surfaceLocked)
                        {
                            return;
                        }
                        this.surface.UnlockRectangle();
                        this.surfaceLocked = false;
                    }
                }

                try
                {
                    device.GetRenderTargetData(renderTarget, surface);
                    query.Issue(Issue.End);
                    queryIssued = true;
                }
                catch (Exception ex)
                {
                    DebugMessage(ex.ToString());
                }
            }
            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
        private void HandleCaptureRequest(Device device)
        {
            try
            {
                if (_killThread)
                {
                    return;
                }

                for (var i = 0; i < BUFFERS; i++)
                {
                    bool tmp;
                    if (_issuedQueries[i]
                        && _queries[i].GetData(out tmp, false))
                    {
                        _issuedQueries[i] = false;
                        var lockedRect = _surfaces[i].LockRectangle(LockFlags.ReadOnly);
                        _surfaceDataPointer = lockedRect.DataPointer;
                        _currentSurface = i;
                        _surfaceLocked[i] = true;

                        _copyReadySignal.Set();
                    }
                }

                if (_captureWaitHandle.WaitOne(0)
                    || _copyWait < BUFFERS - 1)
                {
                    var nextCapture = (_curCapture == BUFFERS - 1) ? 0 : (_curCapture + 1);

                    try
                    {
                        using (var backbuffer = device.GetBackBuffer(0, 0))
                        {
                            var sourceTexture = _copySurfaces[_curCapture];
                            device.StretchRectangle(backbuffer, sourceTexture, TextureFilter.None);
                        }

                        if (_copyWait < BUFFERS - 1)
                        {
                            _copyWait++;
                        }
                        else
                        {
                            var prevSourceTexture = _copySurfaces[nextCapture];
                            var targetTexture = _surfaces[nextCapture];

                            if (_surfaceLocked[nextCapture])
                            {
                                lock (_surfaceLocks[nextCapture])
                                {
                                    _surfaces[nextCapture].UnlockRectangle();
                                    _surfaceLocked[nextCapture] = false;
                                }
                            }

                            try
                            {
                                device.GetRenderTargetData(prevSourceTexture, targetTexture);
                            }
                            catch (Exception ex)
                            {
                                DebugMessage(ex.ToString());
                            }

                            _queries[nextCapture].Issue(Issue.End);
                            _issuedQueries[nextCapture] = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        DebugMessage(ex.ToString());
                    }
                    finally
                    {
                        _captureWaitHandle.Reset();
                        _curCapture = nextCapture;
                    }
                }
            }
            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
        /// <summary>
        /// Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx)
        /// </summary>
        /// <param name="device"></param>
        void DoCaptureRenderTarget(Device device, string hook)
        {
            try
            {
                #region Screenshot Request

                // Single frame capture request
                if (this.Request != null)
                {
                    DateTime start = DateTime.Now;
                    try
                    {
                        using (Surface renderTargetTemp = device.GetRenderTarget(0))
                        {
                            int width, height;

                            // TODO: If resizing the captured image is required it can be adjusted here
                            //if (renderTargetTemp.Description.Width > 1280)
                            //{
                            //    width = 1280;
                            //    height = (int)Math.Round((renderTargetTemp.Description.Height * (1280.0 / renderTargetTemp.Description.Width)));
                            //}
                            //else
                            {
                                width  = renderTargetTemp.Description.Width;
                                height = renderTargetTemp.Description.Height;
                            }

                            // First ensure we have a Surface to the render target data into
                            if (_renderTarget == null)
                            {
                                // Create offscreen surface to use as copy of render target data
                                using (SwapChain sc = device.GetSwapChain(0))
                                {
                                    _renderTarget = Surface.CreateOffscreenPlain(device, width, height,
                                                                                 sc.PresentParameters.BackBufferFormat, Pool.SystemMemory);
                                }
                            }

                            // Create our resolved surface (resizing if necessary and to resolve any multi-sampling)
                            using (
                                Surface resolvedSurface = Surface.CreateRenderTarget(device, width, height,
                                                                                     renderTargetTemp.Description.Format, MultisampleType.None, 0, false))
                            {
                                // Resize from Render Surface to resolvedSurface
                                device.StretchRectangle(renderTargetTemp, resolvedSurface, TextureFilter.None);

                                // Get Render Data
                                device.GetRenderTargetData(resolvedSurface, _renderTarget);
                            }
                        }

                        if (Request != null)
                        {
                            ProcessRequest();
                        }
                    }
                    finally
                    {
                        // We have completed the request - mark it as null so we do not continue to try to capture the same request
                        // Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
                        //         and send back to the host application as needed. The IPC overhead significantly slows down
                        //         the whole process if sending frame by frame.
                        Request = null;
                    }
                    DateTime end = DateTime.Now;
                    this.DebugMessage(hook + ": Capture time: " + (end - start).ToString());
                }

                #endregion

                if (this.Config.ShowOverlay)
                {
                    // SHIT
                    this.Frame();

                    #region Draw frame rate

                    // TODO: font needs to be created and then reused, not created each frame!

                    using (var font = new SharpDX.Direct3D9.Font(device, new FontDescription()
                    {
                        Height = 26,
                        FaceName = "Quartz MS",
                        Italic = false,
                        Width = 0,
                        MipLevels = 1,
                        CharacterSet = FontCharacterSet.Default,
                        OutputPrecision = FontPrecision.Default,
                        Quality = FontQuality.Antialiased,
                        PitchAndFamily = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare,
                        Weight = FontWeight.Normal
                    }))
                    {
                        // Make a Texture from a file...
                        using (FileStream myFileStream = new FileStream(@"baronbutton.png", System.IO.FileMode.Open))
                        { mytexStream = SharpDX.Direct3D9.Texture.FromStream(device, myFileStream); }

                        Sprite spritezor = new SharpDX.Direct3D9.Sprite(device);
                        spritezor.Begin(SharpDX.Direct3D9.SpriteFlags.None);
                        var baronPos = new Vector3(1476, 812, 0);
                        spritezor.Draw(mytexStream, new ColorBGRA(0xffffffff), null, null, baronPos);

                        // Display always...
                        if (this.Config.TestThisShit != 0)
                        {
                            // Draw sprite...
                            spritezor.End();
                            spritezor.Dispose();

                            // Oritinal Text before sprites worked...
                            //font.DrawText(null, "Timer 1", 5, 10, SharpDX.Color.Lime);
                        }

                        // Display on Timer...
                        if (this.TextDisplay != null && this.TextDisplay.Display)
                        {
                            font.DrawText(null, this.TextDisplay.Text, 1477, 870, new SharpDX.ColorBGRA(255, 0, 0, 255));
                            // Alternate font for timers pulsed with alpha fading between ticks...
                            // font.DrawText(null, this.TextDisplay.Text, 5, 25, new SharpDX.ColorBGRA(255, 0, 0, (byte)Math.Round((Math.Abs(1.0f - TextDisplay.Remaining) * 255f))));
                        }

                        /* DXHookD3D9 Original statements to draw the FPS...
                         * if (this.FPS.GetFPS() >= 1)
                         * {
                         * font.DrawText(null, String.Format("{0:N0} fps", this.FPS.GetFPS()), 5, 5, SharpDX.Color.Red);
                         * }
                         * if (this.TextDisplay != null && this.TextDisplay.Display)
                         * {
                         * font.DrawText(null, this.TextDisplay.Text, 5, 25, new SharpDX.ColorBGRA(255, 0, 0, (byte)Math.Round((Math.Abs(1.0f - TextDisplay.Remaining) * 255f))));
                         * }
                         */
                    }

                    #endregion
                }
            }

            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
Beispiel #10
0
        public void createScreenShot(String screenShotName, double positionSeconds, String videoLocation, int offsetSeconds)
        {
            lock (renderLock)
            {
                if (device == null)
                {
                    return;
                }

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

                Rectangle sourceSize = new Rectangle(0, 0, width, height);
                Rectangle destSize   = calcOutputAspectRatio(sourceSize);

                if (screenShot.Description.Width != destSize.Width ||
                    screenShot.Description.Height != destSize.Height)
                {
                    Utils.removeAndDispose(ref screenShot);

                    screenShot = D3D.Surface.CreateRenderTarget(device,
                                                                destSize.Width,
                                                                destSize.Height,
                                                                D3D.Format.A8R8G8B8,
                                                                MultisampleType.None,
                                                                0,
                                                                true);
                }

                SharpDX.Rectangle sourceSizeDX = new SharpDX.Rectangle(0, 0, sourceSize.Width, sourceSize.Height);
                SharpDX.Rectangle destSizeDX   = new SharpDX.Rectangle(0, 0, destSize.Width, destSize.Height);

                device.StretchRectangle(offscreen, sourceSizeDX,
                                        screenShot, destSizeDX, D3D.TextureFilter.Linear);

                SharpDX.DataRectangle stream = screenShot.LockRectangle(destSizeDX, D3D.LockFlags.ReadOnly);
                try
                {
                    JpegBitmapEncoder encoder  = new JpegBitmapEncoder();
                    BitmapMetadata    metaData = new BitmapMetadata("jpg");

                    UriBuilder uri = new UriBuilder(new Uri(videoLocation).AbsoluteUri);

                    int seconds = (int)Math.Floor(Math.Max(positionSeconds + offsetSeconds, 0));

                    TimeSpan time       = new TimeSpan(0, 0, seconds);
                    String   timeString = "";

                    if (time.Days > 0)
                    {
                        timeString += time.Days + "d";
                    }

                    if (time.Hours > 0)
                    {
                        timeString += time.Hours + "h";
                    }

                    if (time.Minutes > 0)
                    {
                        timeString += time.Minutes + "m";
                    }

                    timeString += time.Seconds + "s";

                    uri.Query = "t=" + timeString;

                    metaData.ApplicationName = "MediaViewer v1.0";
                    metaData.Title           = uri.ToString();
                    metaData.DateTaken       = DateTime.Now.ToString("R");

                    BitmapSource image = System.Windows.Media.Imaging.BitmapSource.Create(
                        destSize.Width,
                        destSize.Height,
                        96,
                        96,
                        System.Windows.Media.PixelFormats.Bgra32,
                        null,
                        stream.DataPointer,
                        height * stream.Pitch,
                        stream.Pitch
                        );

                    float scale = ImageUtils.resizeRectangle(destSize.Width, destSize.Height, Constants.MAX_THUMBNAIL_WIDTH, Constants.MAX_THUMBNAIL_HEIGHT);

                    TransformedBitmap thumbnail = new TransformedBitmap(image, new System.Windows.Media.ScaleTransform(scale, scale));

                    encoder.Frames.Add(BitmapFrame.Create(image, thumbnail, metaData, null));

                    FileStream outputFile = new FileStream(screenShotName, FileMode.Create);
                    //encoder.QualityLevel = asyncState.JpegQuality;
                    encoder.Save(outputFile);

                    outputFile.Close();

                    System.Media.SystemSounds.Exclamation.Play();
                }
                catch (Exception e)
                {
                    throw new VideoPlayerException("Error creating screenshot: " + e.Message, e);
                }
                finally
                {
                    screenShot.UnlockRectangle();
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx)
        /// </summary>
        /// <param name="device"></param>
        void DoCaptureRenderTarget(Device device, string hook)
        {
            try
            {
                #region Screenshot Request

                // Single frame capture request
                if (this.Request != null)
                {
                    DateTime start = DateTime.Now;
                    try
                    {

                        using (Surface renderTargetTemp = device.GetRenderTarget(0))
                        {
                            int width, height;

                            // TODO: If resizing the captured image is required it can be adjusted here
                            //if (renderTargetTemp.Description.Width > 1280)
                            //{
                            //    width = 1280;
                            //    height = (int)Math.Round((renderTargetTemp.Description.Height * (1280.0 / renderTargetTemp.Description.Width)));
                            //}
                            //else
                            {
                                width = renderTargetTemp.Description.Width;
                                height = renderTargetTemp.Description.Height;
                            }

                            // First ensure we have a Surface to the render target data into
                            if (_renderTarget == null)
                            {
                                // Create offscreen surface to use as copy of render target data
                                using (SwapChain sc = device.GetSwapChain(0))
                                {
                                    _renderTarget = Surface.CreateOffscreenPlain(device, width, height,
                                        sc.PresentParameters.BackBufferFormat, Pool.SystemMemory);
                                }
                            }

                            // Create our resolved surface (resizing if necessary and to resolve any multi-sampling)
                            using (
                                Surface resolvedSurface = Surface.CreateRenderTarget(device, width, height,
                                    renderTargetTemp.Description.Format, MultisampleType.None, 0, false))
                            {
                                // Resize from Render Surface to resolvedSurface
                                device.StretchRectangle(renderTargetTemp, resolvedSurface, TextureFilter.None);

                                // Get Render Data
                                device.GetRenderTargetData(resolvedSurface, _renderTarget);
                            }
                        }

                        if (Request != null)
                            ProcessRequest();
                    }
                    finally
                    {
                        // We have completed the request - mark it as null so we do not continue to try to capture the same request
                        // Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
                        //         and send back to the host application as needed. The IPC overhead significantly slows down
                        //         the whole process if sending frame by frame.
                        Request = null;
                    }
                    DateTime end = DateTime.Now;
                    this.DebugMessage(hook + ": Capture time: " + (end - start).ToString());
                }

                #endregion

                if (this.Config.ShowOverlay)
                {

                    // SHIT
                    this.Frame();

                    #region Draw frame rate

                    // TODO: font needs to be created and then reused, not created each frame!

                    using (var font = new SharpDX.Direct3D9.Font(device, new FontDescription()
                    {
                        Height = 26,
                        FaceName = "Quartz MS",
                        Italic = false,
                        Width = 0,
                        MipLevels = 1,
                        CharacterSet = FontCharacterSet.Default,
                        OutputPrecision = FontPrecision.Default,
                        Quality = FontQuality.Antialiased,
                        PitchAndFamily = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare,
                        Weight = FontWeight.Normal
                    }))
                    {

                    // Make a Texture from a file...
                    using (FileStream myFileStream = new FileStream(@"baronbutton.png", System.IO.FileMode.Open))
                    { mytexStream = SharpDX.Direct3D9.Texture.FromStream(device, myFileStream); }

                        Sprite spritezor = new SharpDX.Direct3D9.Sprite(device);
                        spritezor.Begin(SharpDX.Direct3D9.SpriteFlags.None);
                        var baronPos = new Vector3(1476, 812, 0);
                        spritezor.Draw(mytexStream, new ColorBGRA(0xffffffff), null, null, baronPos);

                        // Display always...
                        if (this.Config.TestThisShit != 0)
                        {
                            // Draw sprite...
                            spritezor.End();
                            spritezor.Dispose();

                            // Oritinal Text before sprites worked...
                            //font.DrawText(null, "Timer 1", 5, 10, SharpDX.Color.Lime);
                        }

                        // Display on Timer...
                        if (this.TextDisplay != null && this.TextDisplay.Display)
                        {
                            font.DrawText(null, this.TextDisplay.Text, 1477, 870, new SharpDX.ColorBGRA(255, 0, 0, 255));
                            // Alternate font for timers pulsed with alpha fading between ticks...
                            // font.DrawText(null, this.TextDisplay.Text, 5, 25, new SharpDX.ColorBGRA(255, 0, 0, (byte)Math.Round((Math.Abs(1.0f - TextDisplay.Remaining) * 255f))));
                        }

                        /* DXHookD3D9 Original statements to draw the FPS...
                        if (this.FPS.GetFPS() >= 1)
                        {
                           font.DrawText(null, String.Format("{0:N0} fps", this.FPS.GetFPS()), 5, 5, SharpDX.Color.Red);
                        }
                        if (this.TextDisplay != null && this.TextDisplay.Display)
                        {
                           font.DrawText(null, this.TextDisplay.Text, 5, 25, new SharpDX.ColorBGRA(255, 0, 0, (byte)Math.Round((Math.Abs(1.0f - TextDisplay.Remaining) * 255f))));
                        }
                        */
                    }

                    #endregion
                }
            }

            catch (Exception e)
            {
                DebugMessage(e.ToString());
            }
        }
        private void DoCaptureRenderTarget(Device device, string hook)
        {
            try
            {
                if (isCapturing && signalEnd.WaitOne(0))
                {
                    ClearD3D9Data();
                    isCapturing = false;
                    stopRequested = true;
                }

                if (!isCapturing)
                {
                    return;
                }

                if (!bHasTextures)
                {
                    using (Surface backbuffer = device.GetRenderTarget(0))
                    {
                        copyData.format = (int)backbuffer.Description.Format;
                        copyData.width = backbuffer.Description.Width;
                        copyData.height = backbuffer.Description.Height;
                    }
                    DoD3DHooks(device);
                }

                if (!bHasTextures)
                {
                    return;
                }

                long timeVal = DateTime.Now.Ticks;
                long frameTime = 1000000 / targetFps; // lock at 30 fps
                if (frameTime != 0)
                {
                    for (var i = 0; i < NUM_BUFFERS; i++)
                    {
                        if (issuedQueries[i])
                        {
                            bool tmp;
                            if (queries[i].GetData(out tmp, false))
                            {
                                issuedQueries[i] = false;

                                Surface targetTexture = textures[i];
                                try
                                {
                                    var lockedRect = targetTexture.LockRectangle(LockFlags.ReadOnly);
                                    pCopyData = lockedRect.DataPointer;

                                    curCPUTexture = i;
                                    lockedTextures[i] = true;
                                    hCopyEvent.Set();
                                }
                                catch (Exception ex)
                                {
                                    DebugMessage(ex.ToString());
                                }
                            }
                        }
                    }

                    long timeElapsed = timeVal - lastTime;
                    if (timeElapsed >= frameTime)
                    {
                        lastTime += frameTime;
                        if (timeElapsed > frameTime * 2)
                        {
                            lastTime = timeVal;
                        }

                        var nextCapture = (curCapture == NUM_BUFFERS - 1) ? 0 : (curCapture + 1);

                        Surface sourceTexture = copyD3D9Textures[curCapture];
                        using (var backbuffer = device.GetBackBuffer(0, 0))
                        {
                            device.StretchRectangle(backbuffer, sourceTexture, TextureFilter.None);
                        }
                        if (copyWait < (NUM_BUFFERS - 1))
                        {
                            copyWait++;
                        }
                        else
                        {
                            Surface prevSourceTexture = copyD3D9Textures[nextCapture];
                            Surface targetTexture = textures[nextCapture];

                            if (lockedTextures[nextCapture])
                            {
                                Monitor.Enter(dataMutexes[nextCapture]);

                                targetTexture.UnlockRectangle();
                                lockedTextures[nextCapture] = false;

                                Monitor.Exit(dataMutexes[nextCapture]);
                            }
                            try
                            {
                                device.GetRenderTargetData(prevSourceTexture, targetTexture);
                            }
                            catch (Exception ex)
                            {
                                DebugMessage(ex.ToString());
                            }

                            queries[nextCapture].Issue(Issue.End);
                            issuedQueries[nextCapture] = true;
                        }

                        curCapture = nextCapture;
                    }
                }
            }
            catch (Exception e)
            {
                DebugMessage("Error in PresentHook: " + e);
            }
        }