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();
}
}
}