Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2021-12-10 18:14:36 +0300
committerJeroen Bakker <jeroen@blender.org>2021-12-10 18:14:36 +0300
commit943aed0de35621e32896bc14d67dd261d7ce6c01 (patch)
tree83de47f49e38e3f51b82a08e56fcb68e9406c34f /source/blender
parent60a9703de80002cbcef9c2db5f4ee8569185ca1c (diff)
ImBuf: Extracted UV Wrapping from the Interpolation functions.
Improvement of the IMB_transform function by separating the UVWrapping method from the color interpolation function. This would allow us to perform uv wrapping operations separate from the interpolation function. Currently this wrapping is only supported when interpolating colors. This change would allow us to perform it on non-color image buffers.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/imbuf/intern/transform.cc104
1 files changed, 90 insertions, 14 deletions
diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc
index 7c130c658c4..caa43fc4e8d 100644
--- a/source/blender/imbuf/intern/transform.cc
+++ b/source/blender/imbuf/intern/transform.cc
@@ -192,6 +192,68 @@ class TexelPointer {
}
};
+/**
+ * \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.
@@ -209,9 +271,16 @@ template<
* \brief Kernel to store to the destination buffer.
* Should be an TexelPointer
*/
- typename OutputTexelPointer>
+ typename OutputTexelPointer,
+
+ /**
+ * \brief Wrapping method to perform
+ * Should be a subclass of BaseUVWrapper
+ */
+ typename UVWrapping>
class ScanlineProcessor {
Discard discarder;
+ UVWrapping uv_wrapping;
OutputTexelPointer output;
public:
@@ -225,8 +294,11 @@ class ScanlineProcessor {
output.init_pixel_pointer(user_data->dst, 0, scanline);
for (int xi = 0; xi < width; xi++) {
if (!discarder.should_discard(*user_data, uv)) {
- ColorInterpolation(
- user_data->src, output.get_uchar_pointer(), output.get_float_pointer(), uv[0], uv[1]);
+ ColorInterpolation(user_data->src,
+ output.get_uchar_pointer(),
+ output.get_float_pointer(),
+ uv_wrapping.modify_u(*user_data, uv[0]),
+ uv_wrapping.modify_v(*user_data, uv[1]));
}
add_v2_v2(uv, user_data->add_x);
@@ -242,20 +314,26 @@ template<typename Processor> void transform_scanline_function(void *custom_data,
processor.process(user_data, scanline);
}
-template<InterpolationColorFunction DefaultFunction, InterpolationColorFunction WrapRepeatFunction>
+template<InterpolationColorFunction InterpolationFunction>
ScanlineThreadFunc get_scanline_function(const eIMBTransformMode mode)
{
switch (mode) {
case IMB_TRANSFORM_MODE_REGULAR:
- return transform_scanline_function<
- ScanlineProcessor<NoDiscard, DefaultFunction, TexelPointer<float, 4>>>;
+ return transform_scanline_function<ScanlineProcessor<NoDiscard,
+ InterpolationFunction,
+ TexelPointer<float, 4>,
+ PassThroughUV>>;
case IMB_TRANSFORM_MODE_CROP_SRC:
- return transform_scanline_function<
- ScanlineProcessor<CropSource, DefaultFunction, TexelPointer<float, 4>>>;
+ return transform_scanline_function<ScanlineProcessor<CropSource,
+ InterpolationFunction,
+ TexelPointer<float, 4>,
+ PassThroughUV>>;
case IMB_TRANSFORM_MODE_WRAP_REPEAT:
- return transform_scanline_function<
- ScanlineProcessor<NoDiscard, WrapRepeatFunction, TexelPointer<float, 4>>>;
+ return transform_scanline_function<ScanlineProcessor<NoDiscard,
+ InterpolationFunction,
+ TexelPointer<float, 4>,
+ WrapRepeatUV>>;
}
BLI_assert_unreachable();
@@ -271,15 +349,13 @@ static void transform(TransformUserData *user_data, const eIMBTransformMode mode
constexpr InterpolationColorFunction interpolation_function =
Filter == IMB_FILTER_NEAREST ? nearest_interpolation_color_fl :
bilinear_interpolation_color_fl;
- scanline_func =
- get_scanline_function<interpolation_function, nearest_interpolation_color_wrap>(mode);
+ scanline_func = get_scanline_function<interpolation_function>(mode);
}
else if (user_data->dst->rect) {
constexpr InterpolationColorFunction interpolation_function =
Filter == IMB_FILTER_NEAREST ? nearest_interpolation_color_char :
bilinear_interpolation_color_char;
- scanline_func =
- get_scanline_function<interpolation_function, nearest_interpolation_color_wrap>(mode);
+ scanline_func = get_scanline_function<interpolation_function>(mode);
}
if (scanline_func != nullptr) {