public static SharpDX.Direct3D11.Texture2D CreateTex2DFromBitmap(SharpDX.WIC.BitmapSource bsource, GraphicsDevice device) { SharpDX.Direct3D11.Texture2DDescription desc; desc.Width = bsource.Size.Width; desc.Height = bsource.Size.Height; desc.ArraySize = 1; desc.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource; desc.Usage = SharpDX.Direct3D11.ResourceUsage.Default; desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; desc.Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm; desc.MipLevels = 1; desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; SharpDX.Direct3D11.Texture2D dx11Texture; using(SharpDX.DataStream s = new SharpDX.DataStream(bsource.Size.Height * bsource.Size.Width * 4, true, true)) { bsource.CopyPixels(bsource.Size.Width * 4, s); SharpDX.DataRectangle rect = new SharpDX.DataRectangle(s.DataPointer, bsource.Size.Width * 4); dx11Texture = new SharpDX.Direct3D11.Texture2D(device._d3dDevice, desc, rect); } return dx11Texture; }
void reset() { if (offscreen == null) { return; } SharpDX.DataRectangle stream = offscreen.LockRectangle(LockFlags.ReadOnly); VideoFrame.copySurfaceToBuffer(stream.DataPointer, offscreen.Description.Width, offscreen.Description.Height, stream.Pitch, offscreenBuffer); offscreen.UnlockRectangle(); releaseResources(); D3D.PresentParameters[] presentParams = createPresentParams(windowed, owner); device.Reset(presentParams); aquireResources(); stream = offscreen.LockRectangle(LockFlags.None); VideoFrame.copyBufferToSurface(offscreenBuffer, stream.DataPointer, offscreen.Description.Width, offscreen.Description.Height, stream.Pitch); offscreen.UnlockRectangle(); }
public ISpriteTexture CreateSpriteTexture(int width, int height, byte[] data) { if (width <= 0 || width > 65536) { throw new ArgumentOutOfRangeException(nameof(width), "Must be between 1 and 65536"); } if (height <= 0 || height > 65536) { throw new ArgumentOutOfRangeException(nameof(height), "Must be between 1 and 65536"); } var desc = new d3d.Texture2DDescription { Width = width, Height = height, MipLevels = 1, ArraySize = 1, Format = dxgi.Format.B8G8R8A8_UNorm, CpuAccessFlags = d3d.CpuAccessFlags.None, OptionFlags = d3d.ResourceOptionFlags.None, SampleDescription = new dxgi.SampleDescription(1, 0) }; desc.Usage = d3d.ResourceUsage.Immutable; desc.BindFlags = d3d.BindFlags.ShaderResource; var srcDataPtr = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); var dataSource = new SharpDX.DataRectangle(srcDataPtr, width * sizeof(int)); var texture = new d3d.Texture2D(Device, desc, new[] { dataSource }); var shaderResourceView = new d3d.ShaderResourceView(Device, texture); return(new CSpriteTexture(texture, shaderResourceView)); }
public static Texture2D CreateTex2DFromBitmap(SharpDX.Direct3D11.Device device, BitmapSource bsource) { Texture2DDescription desc; desc.Width = bsource.Size.Width; desc.Height = bsource.Size.Height; desc.ArraySize = 1; desc.BindFlags = BindFlags.ShaderResource; desc.Usage = ResourceUsage.Default; desc.CpuAccessFlags = CpuAccessFlags.None; desc.Format = Format.R8G8B8A8_UNorm; desc.MipLevels = 1; desc.OptionFlags = ResourceOptionFlags.None; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; var s = new SharpDX.DataStream(bsource.Size.Height * bsource.Size.Width * 4, true, true); bsource.CopyPixels(bsource.Size.Width * 4, s); var rect = new SharpDX.DataRectangle(s.DataPointer, bsource.Size.Width * 4); var t2D = new Texture2D(device, desc, rect); return(t2D); }
//TODO: check this way to getting back texture //public BitmapSource ToBitmap() { // if (_d3D11Image == null) // return null; // // Copy back buffer to WriteableBitmap. // int width = _d3D11Image.PixelWidth; // int height = _d3D11Image.PixelHeight; // var format = EnableAlpha ? PixelFormats.Bgra32 : PixelFormats.Bgr32; // var writeableBitmap = new WriteableBitmap(width, height, 96, 96, format, null); // writeableBitmap.Lock(); // try { // uint[] data = new uint[width * height]; // _d3D11Image.TryGetData(data); // // Get a pointer to the back buffer. // unsafe { // uint* pBackbuffer = (uint*)writeableBitmap.BackBuffer; // for (int i = 0; i < data.Length; i++) // pBackbuffer[i] = data[i]; // } // writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, width, height)); // } finally { // writeableBitmap.Unlock(); // } // return writeableBitmap; //} static void Copy(Texture2D texture, Stream stream, SharpDX.Direct3D11.Device device) { var desc = new Texture2DDescription { Width = (int)texture.Description.Width, Height = (int)texture.Description.Height, MipLevels = 1, ArraySize = 1, Format = texture.Description.Format, Usage = ResourceUsage.Staging, SampleDescription = new SampleDescription(1, 0), BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, OptionFlags = ResourceOptionFlags.None }; using (var factory = new SharpDX.WIC.ImagingFactory()) { using (var textureCopy = new Texture2D(device, desc)) { device.ImmediateContext.CopyResource(texture, textureCopy); var dataBox = device.ImmediateContext.MapSubresource( textureCopy, 0, 0, MapMode.Read, global::SharpDX.Direct3D11.MapFlags.None, out SharpDX.DataStream dataStream); using (dataStream) { var t = dataStream.ReadByte(); //ReadFloat(); var dataRectangle = new SharpDX.DataRectangle { DataPointer = dataStream.DataPointer, Pitch = dataBox.RowPitch }; //https://github.com/sharpdx/Toolkit/blob/master/Source/Toolkit/SharpDX.Toolkit.Graphics/WICHelper.cs using (var bitmap = new SharpDX.WIC.Bitmap(factory, textureCopy.Description.Width, textureCopy.Description.Height, SharpDX.WIC.PixelFormat.Format32bppRGBA, dataRectangle, 0)) { stream.Position = 0; using (var bitmapEncoder = new SharpDX.WIC.PngBitmapEncoder(factory, stream)) { using (var bitmapFrameEncode = new SharpDX.WIC.BitmapFrameEncode(bitmapEncoder)) { bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(bitmap.Size.Width, bitmap.Size.Height); var pixelFormat = SharpDX.WIC.PixelFormat.FormatDontCare; bitmapFrameEncode.SetPixelFormat(ref pixelFormat); bitmapFrameEncode.WriteSource(bitmap); bitmapFrameEncode.Commit(); bitmapEncoder.Commit(); } } } device.ImmediateContext.UnmapSubresource(textureCopy, 0); } } } }
public Texture2D loadImage(string srcFile, ref SharpDX.Direct3D11.Device dev) { var imgDecoder = new BitmapDecoder(factory, srcFile, DecodeOptions.CacheOnDemand); fmtConverter.Initialize(imgDecoder.GetFrame(0), SharpDX.WIC.PixelFormat.Format32bppPRGBA, BitmapDitherType.None, null, alphaThresholdPct, BitmapPaletteType.Custom); var imgSource = (BitmapSource)fmtConverter; int bmpW = imgSource.Size.Width; int bmpH = imgSource.Size.Height; var buffer = new SharpDX.DataStream(bmpW * bmpH * 4, true, true); imgSource.CopyPixels(bmpW * 4, buffer); // Create a texture description Texture2DDescription tex2Ddesc; tex2Ddesc = new Texture2DDescription() { Width = bmpW, Height = bmpH, ArraySize = 1, MipLevels = 1, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), Usage = ResourceUsage.Immutable, Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm }; // Create a data box SharpDX.DataRectangle dr; dr = new SharpDX.DataRectangle(buffer.DataPointer, bmpW * 4); // Create a texture object Texture2D tex; tex = new Texture2D(dev, tex2Ddesc, dr); return(tex); }
private void writeFacePixels(CubeMapFace face, byte[] pixels, int width, int height) { byte[] pixelsWithAlpha = new byte[width * height * 4]; for (int i = 0; i < width * height; i++) { pixelsWithAlpha[i * 4 + 0] = pixels[i * 4 + 2]; pixelsWithAlpha[i * 4 + 1] = pixels[i * 4 + 1]; pixelsWithAlpha[i * 4 + 2] = pixels[i * 4 + 0]; pixelsWithAlpha[i * 4 + 3] = pixels[i * 4 + 3]; } SharpDX.DataStream stream; SharpDX.DataRectangle r = _cubeMap.LockRectangle(face, 0, LockFlags.None, out stream); Direct3D9Texture.WritePixelsToTextureDataStream(stream, pixelsWithAlpha, width, height); _cubeMap.UnlockRectangle(face, 0); }
private void convertToDirect3D9Texture(bool resizeToPowerOfTwo, bool clamp) { byte[] pixels = _pixels; _actualPixelWidth = _width; _actualPixelHeight = _height; _actualWidth = 1.0f; _actualHeight = 1.0f; if (resizeToPowerOfTwo && ((_width & (_width - 1)) != 0 || (_height & (_height - 1)) != 0)) { byte[] newPixels; ConvertToPowerOfTwo(pixels, _width, _height, out newPixels, out _actualPixelWidth, out _actualPixelHeight); _actualWidth = _width / (float)_actualPixelWidth; _actualHeight = _height / (float)_actualPixelHeight; pixels = fixupAlpha(newPixels, true); } else { pixels = fixupAlpha(null, true); if (pixels == null) { pixels = _pixels; } } Direct3D9Renderer renderer = (Direct3D9Renderer)RendererManager.CurrentRenderer; _texture = new Texture(renderer.Direct3D9Device, _actualPixelWidth, _actualPixelHeight, 0, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed); Surface s = _texture.GetSurfaceLevel(0); SharpDX.DataStream stream; SharpDX.DataRectangle r = s.LockRectangle(LockFlags.None, out stream); WritePixelsToTextureDataStream(stream, pixels, _actualPixelWidth, _actualPixelHeight); s.UnlockRectangle(); }
public override void Update(byte[] pixels) { if (pixels.Length != _width * _height * 4) { throw new ArgumentException("Pixel array is not the expected length"); } // need to swap the R and B components for (int i = 0; i < _width * _height; i++) { byte temp = pixels[i * 4 + 0]; pixels[i * 4 + 0] = pixels[i * 4 + 2]; pixels[i * 4 + 2] = temp; } Surface s = _texture.GetSurfaceLevel(0); SharpDX.DataStream stream; SharpDX.DataRectangle r = s.LockRectangle(LockFlags.None, out stream); Direct3D9Texture.WritePixelsToTextureDataStream(stream, pixels, _width, _height); s.UnlockRectangle(); }
/***********************/ /*** private methods ***/ /***********************/ /// <summary> /// Implementation of capturing from the render target of the Direct3D9 Device (or DeviceEx) /// </summary> /// <param name="device"></param> private void DoCaptureRenderTarget(Device device, Surface surface, string hook) { try { #region Frame capturing // If the resource is initialised we can capture the frame if (this._resourcesInitialised) { // The GPU has finished copying data to _renderTargetCopy, we can now lock // the data and access it on another thread. // 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(() => { ProcessFrame(rect.Width, rect.Height, lockedRect.Pitch, _renderTargetCopy.Description.Format.ToPixelFormat(), lockedRect.DataPointer); }); } int width; int height; if ((surface.Description.Width > this.captureWidth || surface.Description.Height > this.captureHeight)) { if (surface.Description.Width > this.captureWidth) { width = this.captureWidth; height = (int)Math.Round((surface.Description.Height * ((double)this.captureWidth / (double)surface.Description.Width))); } else { height = this.captureHeight; width = (int)Math.Round((surface.Description.Width * ((double)this.captureHeight / (double)surface.Description.Height))); } } else { width = surface.Description.Width; height = surface.Description.Height; } // int width = this.captureWidth; // int height = this.captureHeight; //int width = surface.Description.Width; //int height = surface.Description.Height; //int width = 1280; // 720p //int height = 720; //int width = 720; // 540p // recommended //int height = 540; //int width = 640; // 360p //int height = 360; //int width = 350; // 250p //int height = 250; // 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 != surface.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, surface.Description.Format); } // Resize from render target Surface to resolvedSurface (also deals with resolving multi-sampling) device.StretchRectangle(surface, _resolvedTarget, TextureFilter.None); // If the render target is locked from a previous request unlock it if (_renderTargetCopyLocked) { if (_renderTargetCopyLocked) { _renderTargetCopy.UnlockRectangle(); _renderTargetCopyLocked = false; } } // Copy data from resolved target to our render target copy device.GetRenderTargetData(_resolvedTarget, _renderTargetCopy); #endregion } catch (Exception e) { this.Cleanup(); DebugMessage(e.ToString()); } }
public Texture2D(GraphicsDevice graphicsDevice, int width, int height, TextureFormat format, int arraySize, int mipLevels, ResourceUsage usage = ResourceUsage.Normal, params DataRectangle[] data) : base(graphicsDevice, new StackTrace(1)) { if (width <= 0) { throw new ArgumentOutOfRangeException("width", "Width must be positive."); } if (height <= 0) { throw new ArgumentOutOfRangeException("height", "Height must be positive."); } if (mipLevels < 0) { throw new ArgumentOutOfRangeException("mipLevels", "MipLevels must not be negative."); } if (format == TextureFormat.Unknown) { throw new ArgumentException("Format must not be TextureFormat.Unknown.", "format"); } if (arraySize <= 0) { throw new ArgumentOutOfRangeException("arraySize", "ArraySize must be positive."); } if (usage == ResourceUsage.Immutable && (data == null || data.Length == 0)) { throw new ArgumentException("data", "Immutable textures must be initialized with data."); } if (data != null && data.Length != 0 && data.Length < mipLevels * arraySize) { throw new ArgumentOutOfRangeException("data", data.Length, string.Format("data Lenght is too small for specified arraySize and mipLevels, expected: {0}", mipLevels * arraySize)); } Texture2DDescription desc = new Texture2DDescription() { Width = width, Height = height, Format = EnumConverter.Convert(format), ArraySize = arraySize, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), CpuAccessFlags = CpuAccessFlags.None, MipLevels = mipLevels > 0 ? mipLevels : 1, Usage = EnumConverter.Convert(usage) }; desc.BindFlags |= BindFlags.ShaderResource; if (data != null && data.Length > 1) { SharpDX.DataRectangle[] rects = new SharpDX.DataRectangle[data.Length]; for (int i = 0; i < data.Length; i++) { rects[i] = new SharpDX.DataRectangle(data[i].Pointer, data[i].Pitch); } this.Texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice.Device, desc, rects); } else { this.Texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice.Device, desc); } CreateViews(); }
internal static ShaderResourceView CreateView(out Texture2D texture, Device device, SharpDX.DataStream ds, int width, int height) { Texture2DDescription texDesc = new Texture2DDescription { Width = width, Height = height, MipLevels = 1, ArraySize = 1, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Usage = ResourceUsage.Dynamic, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.Write, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0) }; SharpDX.DataRectangle data = new SharpDX.DataRectangle(ds.DataPointer, width * COLOR_SIZE); texture = new Texture2D(device, texDesc, data); ShaderResourceViewDescription desc = new ShaderResourceViewDescription { Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D, Format = texDesc.Format, Texture2D = { MipLevels = 1, MostDetailedMip = 0 } }; return new ShaderResourceView(device, texture, desc); }
public void display(VideoFrame videoFrame, Color backColor, RenderMode mode) { lock (renderLock) { if (device == null) { return; } SharpDX.Result deviceStatus = device.TestCooperativeLevel(); if (deviceStatus.Success == true) { try { SharpDX.ColorBGRA backColorDX = new SharpDX.ColorBGRA(backColor.R, backColor.G, backColor.B, backColor.A); device.Clear(D3D.ClearFlags.Target, backColorDX, 1.0f, 0); if (mode == RenderMode.CLEAR_SCREEN) { device.Present(); return; } device.BeginScene(); SharpDX.Rectangle videoSourceRect = new SharpDX.Rectangle(); if (mode == RenderMode.NORMAL) { videoSourceRect = new SharpDX.Rectangle(0, 0, videoFrame.Width, videoFrame.Height); SharpDX.DataRectangle stream = offscreen.LockRectangle(LockFlags.None); videoFrame.copyFrameDataToSurface(stream.DataPointer, stream.Pitch); offscreen.UnlockRectangle(); } else if (mode == RenderMode.PAUSED) { videoSourceRect = new SharpDX.Rectangle(0, 0, offscreen.Description.Width, offscreen.Description.Height); } videoDestRect = getVideoDestRect(backBuffer); device.StretchRectangle(offscreen, videoSourceRect, backBuffer, videoDestRect, D3D.TextureFilter.Linear); drawText(); device.EndScene(); device.Present(); RenderMode = mode; } catch (SharpDX.SharpDXException) { //log.Info("lost direct3d device", e); deviceStatus = device.TestCooperativeLevel(); } } if (deviceStatus.Code == D3D.ResultCode.DeviceLost.Result) { //Can't Reset yet, wait for a bit } else if (deviceStatus.Code == D3D.ResultCode.DeviceNotReset.Result) { resetDevice(); } } }
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(); } } }
public ISurface CreateSurface( int width, int height, PixelFormat pixelFormat, SurfaceType type, DataResource dataResource = null) { if (width <= 0 || width > 65536) { throw new ArgumentOutOfRangeException(nameof(width), "Must be between 1 and 65536"); } if (height <= 0 || height > 65536) { throw new ArgumentOutOfRangeException(nameof(height), "Must be between 1 and 65536"); } var desc = new d3d.Texture2DDescription { Width = width, Height = height, MipLevels = 1, ArraySize = 1, Format = dxgi.Format.B8G8R8A8_UNorm, CpuAccessFlags = d3d.CpuAccessFlags.None, OptionFlags = d3d.ResourceOptionFlags.None, SampleDescription = new dxgi.SampleDescription(1, 0) }; switch (type) { case SurfaceType.Input: desc.Usage = d3d.ResourceUsage.Immutable; desc.BindFlags = d3d.BindFlags.ShaderResource; break; case SurfaceType.Output: desc.Usage = d3d.ResourceUsage.Default; desc.BindFlags = d3d.BindFlags.ShaderResource | d3d.BindFlags.RenderTarget; break; case SurfaceType.InputOutput: desc.Usage = d3d.ResourceUsage.Default; desc.BindFlags = d3d.BindFlags.ShaderResource | d3d.BindFlags.RenderTarget; break; } d3d.Texture2D texture; if (dataResource != null) { var srcDataPtr = Marshal.UnsafeAddrOfPinnedArrayElement(dataResource.Data, 0); var dataSource = new SharpDX.DataRectangle(srcDataPtr, dataResource.Stride); texture = new d3d.Texture2D(Device, desc, new[] { dataSource }); } else { texture = new d3d.Texture2D(Device, desc); } var shaderResourceView = new d3d.ShaderResourceView(Device, texture); return(new CSurface(texture, shaderResourceView)); }
/// <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) { _overlayEngine.Dispose(); } _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", 16, FontStyle.Bold)) { Location = new System.Drawing.Point(5, 5), Color= System.Drawing.Color.Red, AntiAliased = true }, // 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()); } }
internal Texture2D(GraphicsDevice graphicsDevice, int width, int height, TextureFormat format, int arraySize, bool isRenderTarget, bool generateMipMaps, ResourceUsage usage = ResourceUsage.Normal, params DataRectangle[] data) : base(graphicsDevice, new StackTrace(1)) { if (width <= 0) { throw new ArgumentOutOfRangeException("width", "Width must be positive."); } if (height <= 0) { throw new ArgumentOutOfRangeException("height", "Height must be positive."); } if (format == TextureFormat.Unknown) { throw new ArgumentException("Format must not be TextureFormat.Unknown.", "format"); } if (arraySize <= 0) { throw new ArgumentOutOfRangeException("arraySize", "ArraySize must be positive."); } if (usage == ResourceUsage.Immutable && (data == null || data.Length == 0)) { throw new ArgumentException("data", "Immutable textures must be initialized with data."); } Texture2DDescription desc = new Texture2DDescription() { Width = width, Height = height, Format = EnumConverter.Convert(format), ArraySize = arraySize, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), CpuAccessFlags = CpuAccessFlags.None, MipLevels = !generateMipMaps ? 1 : 0, Usage = EnumConverter.Convert(usage) }; if (isRenderTarget) { if (format.IsDepth()) { desc.BindFlags |= BindFlags.DepthStencil; } else { desc.BindFlags |= BindFlags.RenderTarget; } } if (generateMipMaps) { desc.BindFlags |= BindFlags.RenderTarget; desc.OptionFlags |= ResourceOptionFlags.GenerateMipMaps; } desc.BindFlags |= BindFlags.ShaderResource; if (data != null && data.Length > 1) { SharpDX.DataRectangle[] rects = new SharpDX.DataRectangle[data.Length]; for (int i = 0; i < data.Length; i++) { rects[i] = new SharpDX.DataRectangle(data[i].Pointer, data[i].Pitch); } this.Texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice.Device, desc, rects); } else { this.Texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice.Device, desc); } CreateViews(); }