blob: e929a4206dd7923d4f1cfb66b2023c0324415793 [file] [log] [blame]
#ifndef IMAGE_SAMPLER
#define IMAGE_SAMPLER
#include <stdint.h>
namespace rive
{
enum class ImageFilter : uint8_t
{
// High fidelity linear filter in all 2 directions: x, y
bilinear = 0,
// Sample with low fidelity, good for things like pixel art.
nearest = 1,
};
constexpr size_t NUM_IMAGE_FILTERS = 2;
enum class ImageWrap : uint8_t
{
// Clamp to the color of the nearest edge when a texture sample falls
// outside 0..1.
clamp = 0,
// Repeat when a texture sample falls outside 0..1 (e.g., fmod(coord, 1)).
repeat = 1,
// Similar to repeat, but also mirror the coordinate with each repeat.
mirror = 2,
};
constexpr size_t NUM_IMAGE_WRAP = 3;
struct ImageSampler
{
static constexpr ImageSampler LinearClamp() { return {}; }
constexpr static uint8_t LINEAR_CLAMP_SAMPLER_KEY = 0;
ImageWrap wrapX = ImageWrap::clamp;
ImageWrap wrapY = ImageWrap::clamp;
// How to sample the texture, this will be for both MIN and MAG filtering.
ImageFilter filter = ImageFilter::bilinear;
bool operator==(const ImageSampler other) const
{
return other.wrapX == wrapX && other.wrapY == wrapY &&
other.filter == filter;
}
bool operator!=(const ImageSampler other) const
{
return !(*this == other);
}
// The maximum number of possible combinations of sampler options. Used for
// array length in implementations.
static constexpr size_t MAX_SAMPLER_PERMUTATIONS =
NUM_IMAGE_FILTERS * NUM_IMAGE_WRAP * NUM_IMAGE_WRAP;
// Convert struct to a key that can be used to index an array to get a
// unique sampler that represents these options.
const uint8_t asKey() const
{
return static_cast<int>(wrapX) +
(static_cast<int>(wrapY) * NUM_IMAGE_WRAP) +
(static_cast<int>(filter) * NUM_IMAGE_WRAP * NUM_IMAGE_WRAP);
}
static ImageSampler SamplerFromKey(uint8_t key)
{
// Android wouldn't compile with {} style initialization so do it this
// way instead.
ImageSampler sampler;
sampler.wrapX = GetWrapXOptionFromKey(key);
sampler.wrapY = GetWrapYOptionFromKey(key);
sampler.filter = GetFilterOptionFromKey(key);
return sampler;
}
static ImageWrap GetWrapXOptionFromKey(uint8_t key)
{
return static_cast<ImageWrap>(key % NUM_IMAGE_WRAP);
}
static ImageWrap GetWrapYOptionFromKey(uint8_t key)
{
return static_cast<ImageWrap>((key / NUM_IMAGE_WRAP) % NUM_IMAGE_WRAP);
}
static ImageFilter GetFilterOptionFromKey(uint8_t key)
{
return static_cast<ImageFilter>(key /
(NUM_IMAGE_WRAP * NUM_IMAGE_WRAP));
}
};
} // namespace rive
#endif