[Bf-blender-cvs] [6739b4756de] temp-gpu-image-engine: Moved UVWrapping to template argument of the sampler.
Jeroen Bakker
noreply at git.blender.org
Mon Dec 13 12:47:44 CET 2021
Commit: 6739b4756de4cf0d97f2b1351d71b065f70337c7
Author: Jeroen Bakker
Date: Mon Dec 13 12:46:37 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rB6739b4756de4cf0d97f2b1351d71b065f70337c7
Moved UVWrapping to template argument of the sampler.
This adds back wrap repeat linear sampling.
===================================================================
M source/blender/imbuf/intern/transform.cc
===================================================================
diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc
index 922e313bada..86a1eefb419 100644
--- a/source/blender/imbuf/intern/transform.cc
+++ b/source/blender/imbuf/intern/transform.cc
@@ -138,7 +138,7 @@ class NoDiscard : public BaseDiscard {
};
/**
- * \brief pointer to a texel to write or read serial.
+ * \brief Pointer to a texel to write or read serial.
*/
template<
/**
@@ -190,7 +190,79 @@ class TexelPointer {
}
};
-template<eIMBInterpolationFilterMode Filter, typename StorageType, int NumChannels> class Sampler {
+/**
+ * \brief Wrapping mode for the uv coordinates.
+ *
+ * Subclasses have the ability to change the UV coordinates before the source buffer will be
+ * sampled.
+ */
+class BaseUVWrapping {
+ public:
+ /**
+ * \brief modify the given u coordinate.
+ */
+ virtual float modify_u(const ImBuf *source_buffer, float u) = 0;
+
+ /**
+ * \brief modify the given v coordinate.
+ */
+ virtual float modify_v(const ImBuf *source_buffer, float v) = 0;
+};
+
+/**
+ * \brief UVWrapping method that does not modify the UV coordinates.
+ */
+class PassThroughUV : public BaseUVWrapping {
+ public:
+ float modify_u(const ImBuf *UNUSED(source_buffer), float u) override
+ {
+ return u;
+ }
+
+ float modify_v(const ImBuf *UNUSED(source_buffer), float v) override
+ {
+ return v;
+ }
+};
+
+/**
+ * \brief UVWrapping method that wrap repeats the UV coordinates.
+ */
+class WrapRepeatUV : public BaseUVWrapping {
+ public:
+ float modify_u(const ImBuf *source_buffer, float u) override
+
+ {
+ int x = (int)floor(u);
+ x = x % source_buffer->x;
+ if (x < 0) {
+ x += source_buffer->x;
+ }
+ return x;
+ }
+
+ float modify_v(const ImBuf *source_buffer, float v) override
+ {
+ int y = (int)floor(v);
+ y = y % source_buffer->y;
+ if (y < 0) {
+ y += source_buffer->y;
+ }
+ return y;
+ }
+};
+
+template<eIMBInterpolationFilterMode Filter,
+ typename StorageType,
+ int NumChannels,
+ /**
+ * \brief Wrapping method to perform
+ * Should be a subclass of BaseUVWrapper
+ */
+ typename UVWrapping>
+class Sampler {
+ UVWrapping uv_wrapper;
+
public:
using ChannelType = StorageType;
static const int ChannelLen = NumChannels;
@@ -198,20 +270,45 @@ template<eIMBInterpolationFilterMode Filter, typename StorageType, int NumChanne
void sample(const ImBuf *source, const float u, const float v, SampleType &r_sample)
{
+ const float wrapped_u = uv_wrapper.modify_u(source, u);
+ const float wrapped_v = uv_wrapper.modify_v(source, v);
+
if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float> &&
NumChannels == 4) {
- bilinear_interpolation_color_fl(source, nullptr, r_sample.begin(), u, v);
+ bilinear_interpolation_color_fl(source, nullptr, r_sample.begin(), wrapped_u, wrapped_v);
}
else if constexpr (Filter == IMB_FILTER_NEAREST &&
std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
- nearest_interpolation_color_char(source, r_sample.begin(), nullptr, u, v);
+ nearest_interpolation_color_char(source, r_sample.begin(), nullptr, wrapped_u, wrapped_v);
}
else if constexpr (Filter == IMB_FILTER_BILINEAR &&
std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
- bilinear_interpolation_color_char(source, r_sample.begin(), nullptr, u, v);
+ bilinear_interpolation_color_char(source, r_sample.begin(), nullptr, wrapped_u, wrapped_v);
+ }
+ else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float>) {
+ if constexpr (std::is_same_v<UVWrapping, WrapRepeatUV>) {
+ BLI_bilinear_interpolation_wrap_fl(source->rect_float,
+ r_sample.begin(),
+ source->x,
+ source->y,
+ NumChannels,
+ u,
+ v,
+ true,
+ true);
+ }
+ else {
+ BLI_bilinear_interpolation_fl(source->rect_float,
+ r_sample.begin(),
+ source->x,
+ source->y,
+ NumChannels,
+ wrapped_u,
+ wrapped_v);
+ }
}
else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, float>) {
- sample_nearest_float(source, u, v, r_sample);
+ sample_nearest_float(source, wrapped_u, wrapped_v, r_sample);
}
else {
/* Unsupported sampler. */
@@ -298,68 +395,6 @@ class ChannelConverter {
}
};
-/**
- * \brief Wrapping mode for the uv coordinates.
- *
- * Subclasses have the ability to change the UV coordinates before the source buffer will be
- * sampled.
- */
-class BaseUVWrapping {
- public:
- /**
- * \brief modify the given u coordinate.
- */
- virtual float modify_u(const TransformUserData &user_data, float u) = 0;
-
- /**
- * \brief modify the given v coordinate.
- */
- virtual float modify_v(const TransformUserData &user_data, float v) = 0;
-};
-
-/**
- * \brief UVWrapping method that does not modify the UV coordinates.
- */
-class PassThroughUV : public BaseUVWrapping {
- public:
- float modify_u(const TransformUserData &UNUSED(user_data), float u) override
- {
- return u;
- }
-
- float modify_v(const TransformUserData &UNUSED(user_data), float v) override
- {
- return v;
- }
-};
-
-/**
- * \brief UVWrapping method that wrap repeats the UV coordinates.
- */
-class WrapRepeatUV : public BaseUVWrapping {
- public:
- float modify_u(const TransformUserData &user_data, float u) override
-
- {
- int x = (int)floor(u);
- x = x % user_data.src->x;
- if (x < 0) {
- x += user_data.src->x;
- }
- return x;
- }
-
- float modify_v(const TransformUserData &user_data, float v) override
- {
- int y = (int)floor(v);
- y = y % user_data.src->y;
- if (y < 0) {
- y += user_data.src->y;
- }
- return y;
- }
-};
-
template<
/**
* \brief Discard function to use.
@@ -377,16 +412,9 @@ template<
* \brief Kernel to store to the destination buffer.
* Should be an TexelPointer
*/
- typename OutputTexelPointer,
-
- /**
- * \brief Wrapping method to perform
- * Should be a subclass of BaseUVWrapper
- */
- typename UVWrapping>
+ typename OutputTexelPointer>
class ScanlineProcessor {
Discard discarder;
- UVWrapping uv_wrapping;
OutputTexelPointer output;
Sampler sampler;
ChannelConverter<typename Sampler::ChannelType,
@@ -406,10 +434,7 @@ class ScanlineProcessor {
for (int xi = 0; xi < width; xi++) {
if (!discarder.should_discard(*user_data, uv)) {
typename Sampler::SampleType sample;
- sampler.sample(user_data->src,
- uv_wrapping.modify_u(*user_data, uv[0]),
- uv_wrapping.modify_v(*user_data, uv[1]),
- sample);
+ sampler.sample(user_data->src, uv[0], uv[1], sample);
channel_converter.convert_and_store(sample, output);
}
@@ -437,21 +462,18 @@ ScanlineThreadFunc get_scanline_function(const eIMBTransformMode mode)
case IMB_TRANSFORM_MODE_REGULAR:
return transform_scanline_function<
ScanlineProcessor<NoDiscard,
- Sampler<Filter, StorageType, SourceNumChannels>,
- TexelPointer<StorageType, DestinationNumChannels>,
- PassThroughUV>>;
+ Sampler<Filter, StorageType, SourceNumChannels, PassThroughUV>,
+ TexelPointer<StorageType, DestinationNumChannels>>>;
case IMB_TRANSFORM_MODE_CROP_SRC:
return transform_scanline_function<
ScanlineProcessor<CropSource,
- Sampler<Filter, StorageType, SourceNumChannels>,
- TexelPointer<StorageType, DestinationNumChannels>,
- PassThroughUV>>;
+ Sampler<Filter, StorageType, SourceNumChannels, PassThroughUV>,
+ TexelPointer<StorageType, DestinationNumChannels>>>;
case IMB_TRANSFORM_MODE_WRAP_REPEAT:
return transform_scanline_function<
ScanlineProcessor<NoDiscard,
- Sampler<Filter, StorageType, SourceNumChannels>,
- TexelPointer<StorageType, DestinationNumChannels>,
- WrapRepeatUV>>;
+ Sampler<Filter, StorageType, SourceNumChannels, WrapRepeatUV>,
+ TexelPointer<StorageType, DestinationNumChannels>>>;
}
BLI_assert_unreachable();
More information about the Bf-blender-cvs
mailing list