using System; using System.Linq; namespace NvAPIWrapper.Display { /// /// Represents a texture of float values /// public class FloatTexture : IEquatable { /// /// Underlying float array containing the values of all channels in all pixels /// protected readonly float[] UnderlyingArray; /// /// Creates a new instance of . /// /// The texture width. /// The texture height. /// The number of texture channels. public FloatTexture(int width, int height, int channels) : this(width, height, channels, null) { } /// /// Creates a new instance of . /// /// The texture width. /// The texture height. /// The number of texture channels. /// The underlying array containing all float values. // ReSharper disable once TooManyDependencies protected FloatTexture(int width, int height, int channels, float[] array) { Width = width; Height = height; Channels = channels; UnderlyingArray = array ?? new float[width * height * channels]; } /// /// Gets the number of texture channels /// public int Channels { get; } /// /// Gets the texture height in pixel /// public int Height { get; } /// /// Gets the texture width in pixels /// public int Width { get; } /// public bool Equals(FloatTexture other) { if (other == null) { return false; } if (ReferenceEquals(this, other)) { return true; } if (other.UnderlyingArray.Length != UnderlyingArray.Length) { return false; } if (other.Width != Width || other.Height != Height || other.Channels != Channels) { return false; } return !UnderlyingArray.Where((t, i) => Math.Abs(other.UnderlyingArray[i] - t) > 0.0001).Any(); } /// /// Returns a new instance of FloatTexture from the passed array of float values. /// /// The texture width. /// The texture height. /// The texture channels. /// The array of float values. /// A new instance of . // ReSharper disable once TooManyArguments public static FloatTexture FromFloatArray(int width, int height, int channels, float[] floats) { if (floats.Length != width * height * channels) { throw new ArgumentOutOfRangeException(nameof(floats)); } return new FloatTexture(width, height, channels, floats.ToArray()); } /// /// Compares two instance of for equality. /// /// The first instance. /// The second instance. /// if both instances are equal, otherwise public static bool operator ==(FloatTexture left, FloatTexture right) { return Equals(left, right) || left?.Equals(right) == true; } /// /// Compares two instance of for in-equality. /// /// The first instance. /// The second instance. /// if both instances are not equal, otherwise public static bool operator !=(FloatTexture left, FloatTexture right) { return !(left == right); } /// public override bool Equals(object obj) { if (obj == null) { return false; } if (ReferenceEquals(this, obj)) { return true; } return Equals(obj as FloatTexture); } /// public override int GetHashCode() { return UnderlyingArray.GetHashCode(); } /// /// Gets the values of each channel at a specific location /// /// The horizontal location. /// The vertical location. /// An array of float values each representing a channel value. public float[] GetValues(int x, int y) { return UnderlyingArray.Skip(y * Width + x).Take(Channels).ToArray(); } /// /// Sets the value of each channel at a specific location /// /// The horizontal location. /// The vertical location. /// An array of float values each representing a channel value. public void SetValues(int x, int y, params float[] floats) { var index = y * Width + x; for (var i = 0; i < Math.Min(Channels, floats.Length); i++) { UnderlyingArray[index + i] = floats[i]; } } /// /// Returns this instance of as an array of float values. /// /// An array of float values representing this instance of . public float[] ToFloatArray() { // Returns a copy of the underlying array return UnderlyingArray.ToArray(); } } }