/// <summary> /// Gets the handle that can be used for resource sharing. /// </summary> /// <param name="texture">The texture to be shared.</param> private IntPtr GetSharedHandle(D3D11.ID3D11Texture2D texture) { texture.EnsureNotNull(nameof(texture)); using (var resource = texture.QueryInterface <IDXGIResource>()) { return(resource.SharedHandle); } }
/// <summary> /// Loads a bitmap from the given texture. Be careful: The texture must have CPU read access and this only matches for staging textures. /// </summary> /// <param name="device">The device on which the texture is created.</param> /// <param name="stagingTexture">The texture to be loaded into the bitmap.</param> /// <param name="targetBitmap">The target bitmap to write all contents to.</param> /// <param name="pixelWidth">With of the bitmap in pixels.</param> /// <param name="pixelHeight">Height of the bitmap in pixels.</param> /// <param name="lockTimeout">Timeout for locking the target bitmap.</param> internal static void LoadBitmapFromStagingTexture(EngineDevice device, D3D11.ID3D11Texture2D stagingTexture, WriteableBitmap targetBitmap, int pixelWidth, int pixelHeight, TimeSpan lockTimeout) { device.EnsureNotNull(nameof(device)); stagingTexture.EnsureNotNull(nameof(stagingTexture)); targetBitmap.EnsureNotNull(nameof(targetBitmap)); var textureDesc = stagingTexture.Description; pixelWidth.EnsureEqualComparable(textureDesc.Width, $"{nameof(textureDesc)}.{nameof(textureDesc.Width)}"); pixelHeight.EnsureEqualComparable(textureDesc.Height, $"{nameof(textureDesc)}.{nameof(textureDesc.Height)}"); // Prepare target bitmap var dataBox = device.Internals.DeviceImmediateContextD3D11.Map(stagingTexture, 0, D3D11.MapMode.Read, D3D11.MapFlags.None); try { if (!targetBitmap.TryLock(new Duration(lockTimeout))) { return; } try { // Copy data row by row // => Rows from data source may have more pixels because driver changes the size of textures var rowPitch = (uint)(pixelWidth * 4); for (var loopRow = 0; loopRow < pixelHeight; loopRow++) { var rowPitchSource = dataBox.RowPitch; var rowPitchDestination = pixelWidth * 4; SeeingSharpUtil.CopyMemory( dataBox.DataPointer + loopRow * rowPitchSource, targetBitmap.BackBuffer + loopRow * rowPitchDestination, rowPitch); } } finally { targetBitmap.AddDirtyRect(new Int32Rect(0, 0, pixelWidth, pixelHeight)); targetBitmap.Unlock(); } } finally { device.Internals.DeviceImmediateContextD3D11.Unmap(stagingTexture, 0); } }
/// <summary> /// Loads a bitmap from the given texture. Be careful: The texture must have CPU read access and this only matches for staging textures. /// </summary> /// <param name="device">The device on which the texture is created.</param> /// <param name="stagingTexture">The texture to be loaded into the bitmap.</param> /// <param name="width">The width of the texture.</param> /// <param name="height">The height of the texture.</param> internal static GDI.Bitmap LoadBitmapFromStagingTexture(EngineDevice device, D3D11.ID3D11Texture2D stagingTexture, int width, int height) { device.EnsureNotNull(nameof(device)); stagingTexture.EnsureNotNull(nameof(stagingTexture)); width.EnsurePositiveOrZero(nameof(width)); height.EnsurePositiveOrZero(nameof(height)); //Prepare target bitmap var resultBitmap = new GDI.Bitmap(width, height); var dataBox = device.Internals.DeviceImmediateContextD3D11.Map(stagingTexture, 0, D3D11.MapMode.Read, D3D11.MapFlags.None); try { //Lock bitmap so it can be accessed for texture loading var bitmapData = resultBitmap.LockBits( new GDI.Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); try { //Copy data row by row // => Rows form data source may have more pixels because driver changes the size of textures var rowPitch = (uint)(width * 4); for (var loopRow = 0; loopRow < height; loopRow++) { // Copy bitmap data var rowPitchSource = dataBox.RowPitch; var rowPitchDestination = width * 4; SeeingSharpUtil.CopyMemory( dataBox.DataPointer + loopRow * rowPitchSource, bitmapData.Scan0 + loopRow * rowPitchDestination, rowPitch); } } finally { resultBitmap.UnlockBits(bitmapData); } } finally { device.Internals.DeviceImmediateContextD3D11.Unmap(stagingTexture, 0); } return(resultBitmap); }