/// <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="texture">The texture to be loaded into the bitmap.</param>
        public static GDI.Bitmap LoadBitmapFromMemoryMappedTexture(MemoryMappedTexture <int> texture)
        {
            texture.EnsureNotNullOrDisposed(nameof(texture));

            var width  = texture.Width;
            var height = texture.Height;

            // Create and lock bitmap so it can be accessed for texture loading
            var resultBitmap = new GDI.Bitmap(width, height);
            var bitmapData   = resultBitmap.LockBits(
                new GDI.Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            try
            {
                SeeingSharpUtil.CopyMemory(
                    texture.Pointer, bitmapData.Scan0, texture.SizeInBytes);
            }
            finally
            {
                resultBitmap.UnlockBits(bitmapData);
            }

            return(resultBitmap);
        }
示例#2
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="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);
        }
示例#4
0
        /// <summary>
        /// Upload a texture from the graphics hardware.
        /// </summary>
        /// <param name="textureToUpload">The texture to be uploaded.</param>
        /// <param name="targetFloatBuffer">The target buffer to which to copy all data.</param>
        internal unsafe void UploadToMemoryMappedTexture <T>(D3D11.ID3D11Texture2D textureToUpload, MemoryMappedTexture <T> targetFloatBuffer)
            where T : unmanaged
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(nameof(TextureUploader));
            }
            this.EnsureNotNullOrDisposed(nameof(targetFloatBuffer));

            // Check input texture
            var textureDesc = textureToUpload.Description;

            if (textureDesc.Width != _width)
            {
                throw new SeeingSharpGraphicsException($"Invalid texture: Width does not match (given: {textureDesc.Width}, expected: {_width})!");
            }
            if (textureDesc.Height != _height)
            {
                throw new SeeingSharpGraphicsException($"Invalid texture: Height does not match (given: {textureDesc.Height}, expected: {_height})!");
            }
            if (textureDesc.Format != _format)
            {
                throw new SeeingSharpGraphicsException($"Invalid texture: Format does not match (given: {textureDesc.Format}, expected: {_format})!");
            }
            if (GraphicsHelper.IsMultisampled(textureDesc) != _isMultisampled)
            {
                throw new SeeingSharpGraphicsException($"Invalid texture: Multisampling does not match (given: {GraphicsHelper.IsMultisampled(textureDesc)}, expected: {_isMultisampled})!");
            }

            // Check source and destination size
            var targetPixelSize = targetFloatBuffer.PixelSize;

            if (targetPixelSize.Width != _width)
            {
                throw new SeeingSharpGraphicsException("The width of the textures during texture upload does not match!");
            }
            if (targetPixelSize.Height != _height)
            {
                throw new SeeingSharpGraphicsException("The height of the textures during texture upload does not match!");
            }

            // Check format compatibility
            var textureFormatByteSize = FormatHelper.SizeOfInBytes(_format);

            if (textureFormatByteSize != sizeof(T))
            {
                throw new SeeingSharpGraphicsException(
                          "Format of the texture to upload and the destination buffer does not match " +
                          $"(source: {_format} / {textureFormatByteSize} bytes, target: {typeof(T).Name} / {sizeof(T)} bytes)!");
            }

            // Upload the texture
            this.CopyTextureToStagingResource(textureToUpload);

            // Read the data into the .Net data block
            var dataBox = _device.DeviceImmediateContextD3D11.Map(
                _copyHelperTextureStaging, 0, D3D11.MapMode.Read, D3D11.MapFlags.None);

            try
            {
                var rowPitchSource      = dataBox.RowPitch;
                var rowPitchDestination = targetFloatBuffer.Width * sizeof(T);
                if (rowPitchSource > 0 && rowPitchDestination > 0)
                {
                    for (var loopY = 0; loopY < _height; loopY++)
                    {
                        SeeingSharpUtil.CopyMemory(
                            dataBox.DataPointer + loopY * rowPitchSource,
                            targetFloatBuffer.Pointer + loopY * rowPitchDestination,
                            (uint)rowPitchDestination);
                    }
                }
                else
                {
                    throw new SeeingSharpGraphicsException($"Invalid row pitch (source: {rowPitchSource}, destination: {rowPitchDestination})!");
                }
            }
            finally
            {
                _device.DeviceImmediateContextD3D11.Unmap(_copyHelperTextureStaging, 0);
            }
        }