/// <summary> /// Saves a texture to a specified stream. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="stream">The stream to save the image to.</param> /// <param name="format">The target image format to use.</param> public static void Save <T>(this ReadBackTexture2D <T> texture, Stream stream, ImageFormat format) where T : unmanaged { Guard.IsNotNull(stream, nameof(stream)); WICHelper.Instance.SaveTexture(texture.View, stream, format); }
/// <summary> /// Saves a texture to a specified file. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="filename">The filename of the image file to save.</param> public static void Save <T>(this ReadBackTexture2D <T> texture, ReadOnlySpan <char> filename) where T : unmanaged { Guard.IsNotNull(texture); WICHelper.Instance.SaveTexture(texture.View, filename); }
/// <summary> /// Saves a texture to a specified file. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="filename">The filename of the image file to save.</param> public static void Save <T>(this ReadBackTexture2D <T> texture, string filename) where T : unmanaged { Guard.IsNotNull(filename, nameof(filename)); WICHelper.Instance.SaveTexture(texture.View, filename.AsSpan()); }
public unsafe void Allocate_ReadBackTexture2D_Copy_Range(Device device, int x, int y, int width, int height) { int[,] source = new int[2048, 2048]; fixed(int *p = source) { new Random(42).NextBytes(new Span <int>(p, source.Length).AsBytes()); } using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source); using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(2048, 2048); readOnlyTexture2D.CopyTo(readBackTexture2D, x, y, width, height); fixed(int *p = source) { for (int i = 0; i < height; i++) { Span <int> sourceRow = new Span <int>(Unsafe.AsPointer(ref source[i + y, 0]), source.GetLength(1)).Slice(x, width); Span <int> destinationRow = readBackTexture2D.View.GetRowSpan(i).Slice(0, width); Assert.IsTrue(sourceRow.SequenceEqual(destinationRow)); } } }
public unsafe void Allocate_ReadBackTexture2D_Copy_Full(Device device) { int[,] source = new int[256, 256]; fixed(int *p = source) { new Random(42).NextBytes(new Span <int>(p, source.Length).AsBytes()); } using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source); using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(256, 256); readOnlyTexture2D.CopyTo(readBackTexture2D); Assert.AreEqual(readBackTexture2D.Width, 256); Assert.AreEqual(readBackTexture2D.Height, 256); fixed(int *p = source) { for (int i = 0; i < readBackTexture2D.Height; i++) { Assert.IsTrue(readBackTexture2D.View.GetRowSpan(i).SequenceEqual(new Span <int>(Unsafe.AsPointer(ref source[i, 0]), source.GetLength(1)))); } } }
/// <summary> /// Saves a texture to a specified buffer writer. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="writer">The buffer writer to save the image to.</param> /// <param name="format">The target image format to use.</param> public static void Save <T>(this ReadBackTexture2D <T> texture, IBufferWriter <byte> writer, ImageFormat format) where T : unmanaged { Guard.IsNotNull(writer, nameof(writer)); WICHelper.Instance.SaveTexture(texture.View, writer, format); }
public void AddObject(ReadBackTexture2D texture) { lock (readBackTextureList) { readBackTextureList.Add(texture); } }
/// <summary> /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance. /// </summary> /// <typeparam name="T">The type of items stored on the texture.</typeparam> /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param> /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param> public static void CopyTo <T>(this Texture2D <T> source, ReadBackTexture2D <T> destination) where T : unmanaged { Guard.IsNotNull(source); Guard.IsNotNull(destination); source.CopyTo(destination, 0, 0, 0, 0, source.Width, source.Height); }
/// <summary> /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance. /// </summary> /// <typeparam name="T">The type of items stored on the texture.</typeparam> /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param> /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param> /// <param name="sourceOffsetX">The horizontal offset in the source texture.</param> /// <param name="sourceOffsetY">The vertical offset in the source texture.</param> /// <param name="destinationOffsetX">The horizontal offset in the destination texture.</param> /// <param name="destinationOffsetY">The vertical offset in the destination texture.</param> /// <param name="width">The width of the memory area to copy.</param> /// <param name="height">The height of the memory area to copy.</param> public static void CopyTo <T>(this Texture2D <T> source, ReadBackTexture2D <T> destination, int sourceOffsetX, int sourceOffsetY, int destinationOffsetX, int destinationOffsetY, int width, int height) where T : unmanaged { Guard.IsNotNull(source); Guard.IsNotNull(destination); source.CopyTo(destination, sourceOffsetX, sourceOffsetY, destinationOffsetX, destinationOffsetY, width, height); }
/// <summary> /// Saves a texture to a specified file. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="filename">The filename of the image file to save.</param> public static void Save <T>(this Texture2D <T> texture, ReadOnlySpan <char> filename) where T : unmanaged { using ReadBackTexture2D <T> readback = texture.GraphicsDevice.AllocateReadBackTexture2D <T>(texture.Width, texture.Height); texture.CopyTo(readback); WICHelper.Instance.SaveTexture(readback.View, filename); }
/// <summary> /// Saves a texture to a specified buffer writer. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="writer">The buffer writer to save the image to.</param> /// <param name="format">The target image format to use.</param> public static void Save <T>(this Texture2D <T> texture, IBufferWriter <byte> writer, ImageFormat format) where T : unmanaged { Guard.IsNotNull(writer, nameof(writer)); using ReadBackTexture2D <T> readback = texture.GraphicsDevice.AllocateReadBackTexture2D <T>(texture.Width, texture.Height); texture.CopyTo(readback); WICHelper.Instance.SaveTexture(readback.View, writer, format); }
/// <summary> /// Saves a texture to a specified stream. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <param name="texture">The texture to save to an image.</param> /// <param name="stream">The stream to save the image to.</param> /// <param name="format">The target image format to use.</param> public static void Save <T>(this Texture2D <T> texture, Stream stream, ImageFormat format) where T : unmanaged { Guard.IsNotNull(stream, nameof(stream)); using ReadBackTexture2D <T> readback = texture.GraphicsDevice.AllocateReadBackTexture2D <T>(texture.Width, texture.Height); texture.CopyTo(readback); WICHelper.Instance.SaveTexture(readback.View, stream, format); }
public void SaveRgba32AsJpeg_ToBufferWriter_WithReadBackTexture_WithNullBufferWriter(Device device, Type textureType) { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) !, "Imaging", "city.jpg"); using Texture2D <Rgba32> texture = device.Get().LoadTexture2D <Rgba32, float4>(textureType, typeof(string), path); using ReadBackTexture2D <Rgba32> readback = device.Get().AllocateReadBackTexture2D <Rgba32>(texture.Width, texture.Height); texture.CopyTo(readback); readback.Save((IBufferWriter <byte>)null !, ImageFormat.Jpeg); }
/// <summary> /// Reads the contents of the specified range from the current <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance. /// </summary> /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param> /// <param name="destinationX">The horizontal offset within <paramref name="destination"/>.</param> /// <param name="destinationY">The vertical offset within <paramref name="destination"/>.</param> /// <param name="sourceX">The horizontal offset in the source texture.</param> /// <param name="sourceY">The vertical offset in the source texture.</param> /// <param name="width">The width of the memory area to copy.</param> /// <param name="height">The height of the memory area to copy.</param> internal void CopyTo(ReadBackTexture2D <T> destination, int destinationX, int destinationY, int sourceX, int sourceY, int width, int height) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); destination.ThrowIfDeviceMismatch(GraphicsDevice); destination.ThrowIfDisposed(); Guard.IsInRange(destinationX, 0, destination.Width, nameof(destinationX)); Guard.IsInRange(destinationY, 0, destination.Height, nameof(destinationY)); Guard.IsInRange(sourceX, 0, Width, nameof(sourceX)); Guard.IsInRange(sourceY, 0, Height, nameof(sourceY)); Guard.IsBetweenOrEqualTo(width, 1, Width, nameof(width)); Guard.IsBetweenOrEqualTo(height, 1, Height, nameof(height)); Guard.IsBetweenOrEqualTo(width, 1, destination.Width, nameof(width)); Guard.IsBetweenOrEqualTo(height, 1, destination.Height, nameof(height)); Guard.IsBetweenOrEqualTo(destinationX + width, 1, destination.Width, nameof(destinationX)); Guard.IsBetweenOrEqualTo(destinationY + height, 1, destination.Height, nameof(destinationY)); Guard.IsLessThanOrEqualTo(sourceX + width, Width, nameof(sourceX)); Guard.IsLessThanOrEqualTo(sourceY + height, Height, nameof(sourceY)); using CommandList copyCommandList = new(GraphicsDevice, this.d3D12CommandListType); if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE) { copyCommandList.D3D12GraphicsCommandList->ResourceBarrier(D3D12Resource, this.d3D12ResourceState, D3D12_RESOURCE_STATE_COPY_SOURCE); } fixed(D3D12_PLACED_SUBRESOURCE_FOOTPRINT *d3D12PlacedSubresourceFootprintDestination = &destination.D3D12PlacedSubresourceFootprint) { copyCommandList.D3D12GraphicsCommandList->CopyTextureRegion( d3D12ResourceDestination: destination.D3D12Resource, d3D12PlacedSubresourceFootprintDestination, (uint)destinationX, (uint)destinationY, destinationZ: 0, d3D12ResourceSource: D3D12Resource, (uint)sourceX, (uint)sourceY, sourceZ: 0, (uint)width, (uint)height, 1); } if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE) { copyCommandList.D3D12GraphicsCommandList->ResourceBarrier(D3D12Resource, D3D12_RESOURCE_STATE_COPY_SOURCE, this.d3D12ResourceState); } copyCommandList.ExecuteAndWaitForCompletion(); }
public void SaveRgba32AsJpeg_ToFile_WithReadBackTexture(Device device, Type textureType, Type inputType) { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) !, "Imaging"); string expectedPath = Path.Combine(path, "city.jpg"); string actualPath = Path.Combine(path, "city_rgba32_saved.jpg"); using Texture2D <Rgba32> texture = device.Get().LoadTexture2D <Rgba32, float4>(textureType, inputType, expectedPath); using ReadBackTexture2D <Rgba32> readback = device.Get().AllocateReadBackTexture2D <Rgba32>(texture.Width, texture.Height); texture.CopyTo(readback); readback.Save(inputType, actualPath); TolerantImageComparer.AssertEqual(expectedPath, actualPath, 0.00001023f); }
public void SaveRgba32AsJpeg_ToBufferWriter_WithReadBackTexture(Device device, Type textureType) { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) !, "Imaging"); string expectedPath = Path.Combine(path, "city.jpg"); string actualPath = Path.Combine(path, "city_rgba32_saved.jpg"); using Texture2D <Rgba32> texture = device.Get().LoadTexture2D <Rgba32, float4>(textureType, typeof(string), expectedPath); using ReadBackTexture2D <Rgba32> readback = device.Get().AllocateReadBackTexture2D <Rgba32>(texture.Width, texture.Height); texture.CopyTo(readback); using (ArrayPoolBufferWriter <byte> writer = new()) { readback.Save(writer, ImageFormat.Jpeg); File.WriteAllBytes(actualPath, writer.WrittenSpan.ToArray()); } TolerantImageComparer.AssertEqual(expectedPath, actualPath, 0.00001023f); }
public void Allocate_ReadBackTexture2D_Copy_Range(Device device, int x, int y, int width, int height) { int[,] source = new int[2048, 2048]; for (int i = 0; i < 2048; i++) { new Random(42).NextBytes(source.GetRowSpan(i).AsBytes()); } using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source); using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(2048, 2048); readOnlyTexture2D.CopyTo(readBackTexture2D, x, y, width, height); for (int i = 0; i < height; i++) { Span <int> sourceRow = source.GetRowSpan(i + y).Slice(x, width); Span <int> destinationRow = readBackTexture2D.View.GetRowSpan(i).Slice(0, width); Assert.IsTrue(sourceRow.SequenceEqual(destinationRow)); } }
public void Allocate_ReadBackTexture2D_Copy_Full(Device device) { int[,] source = new int[256, 256]; for (int i = 0; i < 256; i++) { new Random(42).NextBytes(source.GetRowSpan(i).AsBytes()); } using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source); using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(256, 256); readOnlyTexture2D.CopyTo(readBackTexture2D); Assert.AreEqual(readBackTexture2D.Width, 256); Assert.AreEqual(readBackTexture2D.Height, 256); for (int i = 0; i < readBackTexture2D.Height; i++) { Assert.IsTrue(readBackTexture2D.View.GetRowSpan(i).SequenceEqual(source.GetRowSpan(i))); } }
public void UnsafeAdd(ReadBackTexture2D texture) { readBackTextureList.Add(texture); }
/// <summary> /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance. /// </summary> /// <typeparam name="T">The type of items stored on the texture.</typeparam> /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param> /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param> public static void CopyFrom <T>(this ReadBackTexture2D <T> destination, Texture2D <T> source) where T : unmanaged { source.CopyTo(destination, 0, 0, 0, 0, source.Width, source.Height); }
/// <summary> /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance. /// </summary> /// <typeparam name="T">The type of items stored on the texture.</typeparam> /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param> /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param> /// <param name="sourceOffsetX">The horizontal offset in the source texture.</param> /// <param name="sourceOffsetY">The vertical offset in the source texture.</param> /// <param name="destinationOffsetX">The horizontal offset in the destination texture.</param> /// <param name="destinationOffsetY">The vertical offset in the destination texture.</param> /// <param name="width">The width of the memory area to copy.</param> /// <param name="height">The height of the memory area to copy.</param> public static void CopyFrom <T>(this ReadBackTexture2D <T> destination, Texture2D <T> source, int sourceOffsetX, int sourceOffsetY, int destinationOffsetX, int destinationOffsetY, int width, int height) where T : unmanaged { source.CopyTo(destination, sourceOffsetX, sourceOffsetY, destinationOffsetX, destinationOffsetY, width, height); }