public Color readTexture(float u, float v, AddressType addressType, bool flipU = false, bool flipV = false) { BilinearCoordinates coordinates = calculateBilinearCoordinates(u, v, flipU, flipV); coordinates = applyAddressTypeOnBilinearCoordinates(coordinates, addressType); return(bilinearInterpolation( readBilinearCoordinateColor(coordinates, BilinearCoordinatesType.UminVmin), readBilinearCoordinateColor(coordinates, BilinearCoordinatesType.UmaxVmin), readBilinearCoordinateColor(coordinates, BilinearCoordinatesType.UminVmax), readBilinearCoordinateColor(coordinates, BilinearCoordinatesType.UmaxVmax), coordinates.ucoef, coordinates.vcoef )); }
public Color readBilinearCoordinateColor(BilinearCoordinates coordinates, BilinearCoordinatesType coordinateType) { switch (coordinateType) { default: case BilinearCoordinatesType.UminVmin: return(_textureArray[coordinates.umin + _width * coordinates.vmin]); case BilinearCoordinatesType.UmaxVmin: return(_textureArray[coordinates.umax + _width * coordinates.vmin]); case BilinearCoordinatesType.UminVmax: return(_textureArray[coordinates.umin + _width * coordinates.vmax]); case BilinearCoordinatesType.UmaxVmax: return(_textureArray[coordinates.umax + _width * coordinates.vmax]); } }
public BilinearCoordinates calculateBilinearCoordinates(float u, float v, bool flipU = false, bool flipV = false) { u = Math.Abs(u); v = Math.Abs(v); u = flipU ? 1 - u : u; v = flipV ? 1 - v : v; BilinearCoordinates coordinates = new BilinearCoordinates(); coordinates.umin = (int)(_width * u); coordinates.vmin = (int)(_height * v); coordinates.umax = (int)(_width * u) + 1; //this could end up on a different texture, when using multiple textures coordinates.vmax = (int)(_height * v) + 1; //this could end up on a different texture. Three textures is max what should be blended from, if wrapping is to be supported for multiple textures coordinates.ucoef = Math.Abs(_width * u - coordinates.umin); coordinates.vcoef = Math.Abs(_height * v - coordinates.vmin); return(coordinates); }
public BilinearCoordinates applyAddressTypeOnBilinearCoordinates(BilinearCoordinates coordinates, AddressType addressType) { // The texture is being addressed on [0,1] // There should be an addressing type in order to // determine how we should access texels when // the coordinates are beyond those boundaries. // Clamping is done by bringing anything below zero to the coordinate zero and everything beyond one, to one. // WrapAround is using modulus to wrap the coordinates off the end to the other side of the texture switch (addressType) { case AddressType.WrapV_ClampU: coordinates.vmin = mod(coordinates.vmin, _width); coordinates.vmax = mod(coordinates.vmax, _width); coordinates.umin = Math.Min(Math.Max(coordinates.umin, 0), _height - 1); coordinates.umax = Math.Min(Math.Max(coordinates.umax, 0), _height - 1); break; case AddressType.WrapU_ClampV: coordinates.umin = mod(coordinates.umin, _width); coordinates.umax = mod(coordinates.umax, _width); coordinates.vmin = Math.Min(Math.Max(coordinates.vmin, 0), _height - 1); coordinates.vmax = Math.Min(Math.Max(coordinates.vmax, 0), _height - 1); break; case AddressType.WrapAround: coordinates.umin = mod(coordinates.umin, _width); coordinates.umax = mod(coordinates.umax, _width); coordinates.vmin = mod(coordinates.vmin, _height); coordinates.vmax = mod(coordinates.vmax, _height); break; case AddressType.Clamping: default: coordinates.umin = Math.Min(Math.Max(coordinates.umin, 0), _width - 1); coordinates.umax = Math.Min(Math.Max(coordinates.umax, 0), _width - 1); coordinates.vmin = Math.Min(Math.Max(coordinates.vmin, 0), _height - 1); coordinates.vmax = Math.Min(Math.Max(coordinates.vmax, 0), _height - 1); break; } return(coordinates); }