Browse Source

Math: added scatter(), renamed swizzle() to gather().

The swizzle() function is still present, only marked as deprecated and
scheduled to be removed in some future release.
pull/326/merge
Vladimír Vondruš 7 years ago
parent
commit
acc8d8994b
  1. 3
      doc/changelog.dox
  2. 4
      doc/matrix-vector.dox
  3. 27
      doc/snippets/MagnumMath.cpp
  4. 83
      src/Magnum/Math/Swizzle.h
  5. 8
      src/Magnum/Math/Test/ColorTest.cpp
  6. 89
      src/Magnum/Math/Test/SwizzleTest.cpp
  7. 2
      src/Magnum/Math/Test/Vector2Test.cpp
  8. 2
      src/Magnum/Math/Test/Vector3Test.cpp
  9. 2
      src/Magnum/Math/Test/Vector4Test.cpp
  10. 4
      src/Magnum/Math/Vector3.h
  11. 4
      src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp
  12. 4
      src/MagnumPlugins/TgaImporter/TgaImporter.cpp

3
doc/changelog.dox

@ -210,6 +210,7 @@ See also:
- Scalar and vector @ref Math::equal() and @ref Math::notEqual() which do a - Scalar and vector @ref Math::equal() and @ref Math::notEqual() which do a
component-wise comparison in the vector case, as the equality/non-equality component-wise comparison in the vector case, as the equality/non-equality
operators return a single @cpp bool @ce operators return a single @cpp bool @ce
- @ref Math::scatter() as an inverse operation to @ref math::gather()
@subsubsection changelog-latest-new-meshtools MeshTools library @subsubsection changelog-latest-new-meshtools MeshTools library
@ -678,6 +679,8 @@ See also:
the wrong thing. For backwards compatibility the wrong thing. For backwards compatibility
@ref Platform::BasicScreenedApplication is convertible to a pointer and @ref Platform::BasicScreenedApplication is convertible to a pointer and
implements @cpp operator-> @ce, but this conversion is deprecated. implements @cpp operator-> @ce, but this conversion is deprecated.
- @cpp Math::swizzle() @ce is deprecated, use @ref Math::gather() instead as
that fits better with the new @ref Math::scatter()
@subsection changelog-latest-compatibility Potential compatibility breakages, removed APIs @subsection changelog-latest-compatibility Potential compatibility breakages, removed APIs

4
doc/matrix-vector.dox

@ -147,8 +147,8 @@ and subparts:
@ref Color3 and @ref Color4 name their components `rgba` instead of `xyzw`. @ref Color3 and @ref Color4 name their components `rgba` instead of `xyzw`.
For more involved operations with components there is the @ref Math::swizzle() For more involved operations with components there is the @ref Math::gather()
function: and @ref Math::scatter() functions:
@snippet MagnumMath.cpp matrix-vector-access-swizzle @snippet MagnumMath.cpp matrix-vector-access-swizzle

27
doc/snippets/MagnumMath.cpp

@ -162,9 +162,14 @@ static_cast<void>(x);
{ {
/* [matrix-vector-access-swizzle] */ /* [matrix-vector-access-swizzle] */
Vector4i orig{-1, 2, 3, 4}; Vector4i orig{-1, 2, 3, 4};
Vector4i bgra = Math::swizzle<'b', 'g', 'r', 'a'>(orig); // { 3, 2, -1, 4 } Vector4i bgra = Math::gather<'b', 'g', 'r', 'a'>(orig); // { 3, 2, -1, 4 }
Math::Vector<6, Int> w10xyz = Math::swizzle<'w', '1', '0', 'x', 'y', 'z'>(orig); Math::Vector<6, Int> w10xyz = Math::gather<'w', '1', '0', 'x', 'y', 'z'>(orig);
// { 4, 1, 0, -1, 2, 3 } // { 4, 1, 0, -1, 2, 3 }
Vector4 vec{1.5f, 3.0f, 0.1f, 1.1f};
Vector2 coords{5.0f, -2.0f};
Math::scatter<'z', 'w'>(vec, coords); // { 1.5, 3.0, 5.0, -2.0 }
/* [matrix-vector-access-swizzle] */ /* [matrix-vector-access-swizzle] */
static_cast<void>(bgra); static_cast<void>(bgra);
static_cast<void>(w10xyz); static_cast<void>(w10xyz);
@ -1077,15 +1082,27 @@ static_cast<void>(mySet);
} }
{ {
/* [swizzle] */ /* [gather] */
Vector4i original(-1, 2, 3, 4); Vector4i original(-1, 2, 3, 4);
auto vec = Math::swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); auto vec = Math::gather<'w', '1', '0', 'x', 'y', 'z'>(original);
// vec == { 4, 1, 0, -1, 2, 3 } // vec == { 4, 1, 0, -1, 2, 3 }
/* [swizzle] */ /* [gather] */
static_cast<void>(vec); static_cast<void>(vec);
} }
{
/* [scatter] */
Vector4 vec{1.5f, 3.0f, 0.1f, 1.1f};
Vector2 coords{5.0f, -2.0f};
vec = Math::scatter<'z', 'w'>(vec, coords); // { 1.5, 3.0, 5.0, -2.0 }
/* Combine the two for more advanced swizzles */
Vector4 vec2;
vec2 = Math::scatter<'w', 'x', 'y'>(vec2, Math::gather<'x', 'w', 'y'>(vec));
/* [scatter] */
}
{ {
Float a{}, b{}; Float a{}, b{};
/* [TypeTraits-equalsZero] */ /* [TypeTraits-equalsZero] */

83
src/Magnum/Math/Swizzle.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Function @ref Magnum::Math::swizzle() * @brief Function @ref Magnum::Math::gather(), @ref Magnum::Math::scatter()
*/ */
#include "Magnum/Math/Vector.h" #include "Magnum/Math/Vector.h"
@ -35,9 +35,11 @@ namespace Magnum { namespace Math {
namespace Implementation { namespace Implementation {
template<std::size_t size, std::size_t position> struct ComponentAtPosition { template<std::size_t size, std::size_t position> struct ComponentAtPosition {
static_assert(size > position, "Swizzle parameter out of range of base vector"); static_assert(size > position, "swizzle parameter out of range of gather vector");
template<class T> constexpr static T value(const Math::Vector<size, T>& vector) { return vector[position]; } template<class T> constexpr static T value(const Math::Vector<size, T>& vector) {
return vector[position];
}
}; };
template<std::size_t size, char component> struct Component {}; template<std::size_t size, char component> struct Component {};
@ -59,14 +61,51 @@ namespace Implementation {
template<std::size_t size, class T> struct TypeForSize { template<std::size_t size, class T> struct TypeForSize {
typedef Math::Vector<size, typename T::Type> Type; typedef Math::Vector<size, typename T::Type> Type;
}; };
template<std::size_t size, char component, std::size_t i> struct ComponentOr {
static_assert(component == 'x' || component == 'r' ||
((component == 'y' || component == 'g') && size > 1) ||
((component == 'z' || component == 'b') && size > 2) ||
((component == 'w' || component == 'a') && size > 3),
"swizzle parameter out of range of scatter vector");
template<class T> constexpr static T value(const Math::Vector<size, T>& vector, const T&) {
return vector[i];
}
};
template<std::size_t size, std::size_t position> struct Value {
template<class T> constexpr static T value(const Math::Vector<size, T>&, const T& value) {
return value;
}
};
template<std::size_t size> struct ComponentOr<size, 'x', 0>: Value<size, 0> {};
template<std::size_t size> struct ComponentOr<size, 'y', 1>: Value<size, 1> {};
template<std::size_t size> struct ComponentOr<size, 'z', 2>: Value<size, 2> {};
template<std::size_t size> struct ComponentOr<size, 'w', 3>: Value<size, 3> {};
template<std::size_t size> struct ComponentOr<size, 'r', 0>: Value<size, 0> {};
template<std::size_t size> struct ComponentOr<size, 'g', 1>: Value<size, 1> {};
template<std::size_t size> struct ComponentOr<size, 'b', 2>: Value<size, 2> {};
template<std::size_t size> struct ComponentOr<size, 'a', 3>: Value<size, 3> {};
template<class T, char component, std::size_t ...sequence> constexpr T componentOr(const T& vector, const typename T::Type& value, Sequence<sequence...>) {
return {ComponentOr<T::Size, component, sequence>::value(vector, value)...};
}
template<class T, std::size_t valueSize> constexpr T scatterRecursive(const T& vector, const Math::Vector<valueSize, typename T::Type>&, std::size_t) {
return vector;
}
template<class T, std::size_t valueSize, char component, char ...next> constexpr T scatterRecursive(const T& vector, const Math::Vector<valueSize, typename T::Type>& values, std::size_t valueIndex) {
return scatterRecursive<T, valueSize, next...>(
componentOr<T, component>(vector, values[valueIndex], typename GenerateSequence<T::Size>::Type{}),
values, valueIndex + 1);
}
} }
/** /**
@brief Swizzle @ref Vector components @brief Gather @ref Vector components
Creates new vector from given components. Example: Creates a new vector from given components. Example:
@snippet MagnumMath.cpp swizzle @snippet MagnumMath.cpp gather
You can use letters @cpp 'x' @ce, @cpp 'y' @ce, @cpp 'z' @ce, @cpp 'w' @ce and You can use letters @cpp 'x' @ce, @cpp 'y' @ce, @cpp 'z' @ce, @cpp 'w' @ce and
@cpp 'r' @ce, @cpp 'g' @ce, @cpp 'b' @ce, @cpp 'a' @ce for addressing @cpp 'r' @ce, @cpp 'g' @ce, @cpp 'b' @ce, @cpp 'a' @ce for addressing
@ -75,13 +114,41 @@ elements is unlimited, but must be at least one. If the resulting vector is
two, three or four-component, corresponding @ref Vector2, @ref Vector3, two, three or four-component, corresponding @ref Vector2, @ref Vector3,
@ref Vector4, @ref Color3 or @ref Color4 specialization is returned. @ref Vector4, @ref Color3 or @ref Color4 specialization is returned.
@see @ref matrix-vector-component-access, @ref Vector4::xyz(), @see @ref scatter(), @ref matrix-vector-component-access, @ref Vector4::xyz(),
@ref Vector4::rgb(), @ref Vector4::xy(), @ref Vector3::xy() @ref Vector4::rgb(), @ref Vector4::xy(), @ref Vector3::xy()
*/ */
template<char ...components, class T> constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector) { template<char ...components, class T> constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type gather(const T& vector) {
return {Implementation::Component<T::Size, components>::value(vector)...}; return {Implementation::Component<T::Size, components>::value(vector)...};
} }
/**
@brief Scatter @ref Vector components
@param vector Vector to update
@param values Values to update it with
@return Updated vector
Returns a copy of @p vector with particular components updated from @p values.
Inverse to @ref gather(), supporting the same component addressing except for
@cpp '0' @ce and @cpp '1' @ce. Example:
@snippet MagnumMath.cpp scatter
@see @ref matrix-vector-component-access, @ref Vector4::xyz(),
@ref Vector4::rgb(), @ref Vector4::xy(), @ref Vector3::xy()
*/
template<char ...components, class T> constexpr T scatter(const T& vector, const Vector<sizeof...(components), typename T::Type>& values) {
return Implementation::scatterRecursive<T, sizeof...(components), components...>(vector, values, 0);
}
#ifdef MAGNUM_BUILD_DEPRECATED
/** @brief @copybrief gather()
* @deprecated Use @ref gather instead.
*/
template<char ...components, class T> CORRADE_DEPRECATED("use gather() instead") constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector) {
return gather<components...>(vector);
}
#endif
}} }}
#endif #endif

8
src/Magnum/Math/Test/ColorTest.cpp

@ -990,16 +990,16 @@ void ColorTest::swizzleType() {
constexpr Color3 origColor3; constexpr Color3 origColor3;
constexpr Color4ub origColor4; constexpr Color4ub origColor4;
constexpr auto a = Math::swizzle<'y', 'z', 'r'>(origColor3); constexpr auto a = Math::gather<'y', 'z', 'r'>(origColor3);
CORRADE_VERIFY((std::is_same<decltype(a), const Color3>::value)); CORRADE_VERIFY((std::is_same<decltype(a), const Color3>::value));
constexpr auto b = Math::swizzle<'y', 'z', 'a'>(origColor4); constexpr auto b = Math::gather<'y', 'z', 'a'>(origColor4);
CORRADE_VERIFY((std::is_same<decltype(b), const Color3ub>::value)); CORRADE_VERIFY((std::is_same<decltype(b), const Color3ub>::value));
constexpr auto c = Math::swizzle<'y', 'z', 'y', 'x'>(origColor3); constexpr auto c = Math::gather<'y', 'z', 'y', 'x'>(origColor3);
CORRADE_VERIFY((std::is_same<decltype(c), const Color4>::value)); CORRADE_VERIFY((std::is_same<decltype(c), const Color4>::value));
constexpr auto d = Math::swizzle<'y', 'a', 'y', 'x'>(origColor4); constexpr auto d = Math::gather<'y', 'a', 'y', 'x'>(origColor4);
CORRADE_VERIFY((std::is_same<decltype(d), const Color4ub>::value)); CORRADE_VERIFY((std::is_same<decltype(d), const Color4ub>::value));
} }

89
src/Magnum/Math/Test/SwizzleTest.cpp

@ -32,45 +32,86 @@ namespace Magnum { namespace Math { namespace Test { namespace {
struct SwizzleTest: Corrade::TestSuite::Tester { struct SwizzleTest: Corrade::TestSuite::Tester {
explicit SwizzleTest(); explicit SwizzleTest();
void components(); void gather();
void constants(); void gatherConstants();
void rgba(); void gatherDifferentSize();
void sizes();
void scatter();
void scatterOneComponent();
void scatterRepeatedComponents();
void scatterOverwriteAllComponents();
}; };
typedef Vector<2, Int> Vector2i;
typedef Vector<3, Int> Vector3i;
typedef Vector<4, Int> Vector4i; typedef Vector<4, Int> Vector4i;
SwizzleTest::SwizzleTest() { SwizzleTest::SwizzleTest() {
addTests({&SwizzleTest::components, addTests({&SwizzleTest::gather,
&SwizzleTest::constants, &SwizzleTest::gatherConstants,
&SwizzleTest::rgba, &SwizzleTest::gatherDifferentSize,
&SwizzleTest::sizes});
&SwizzleTest::scatter,
&SwizzleTest::scatterOneComponent,
&SwizzleTest::scatterRepeatedComponents,
&SwizzleTest::scatterOverwriteAllComponents});
} }
void SwizzleTest::components() { void SwizzleTest::gather() {
constexpr auto a = swizzle<'z', 'x', 'w', 'y'>(Vector4i(2, 4, 5, 7)); constexpr auto a = Math::gather<'z', 'x', 'w', 'y'>(Vector4i{2, 4, 5, 7});
CORRADE_COMPARE(a, Vector4i(5, 2, 7, 4)); constexpr auto b = Math::gather<'b', 'r', 'a', 'g'>(Vector4i{2, 4, 5, 7});
CORRADE_COMPARE(a, (Vector4i{5, 2, 7, 4}));
CORRADE_COMPARE(b, (Vector4i{5, 2, 7, 4}));
} }
void SwizzleTest::constants() { void SwizzleTest::gatherConstants() {
constexpr auto a = swizzle<'1', 'w', '0', 'y'>(Vector4i(2, 4, 5, 7)); constexpr auto a = Math::gather<'1', 'w', '0', 'y'>(Vector4i{2, 4, 5, 7});
CORRADE_COMPARE(a, Vector4i(1, 7, 0, 4)); constexpr auto b = Math::gather<'1', 3, '0', 2>(Vector4i{2, 4, 5, 7});
CORRADE_COMPARE(a, (Vector4i{1, 7, 0, 4}));
CORRADE_COMPARE(b, (Vector4i{1, 7, 0, 4}));
} }
void SwizzleTest::rgba() { void SwizzleTest::gatherDifferentSize() {
constexpr auto a = swizzle<'b', 'r', 'a', 'g'>(Vector4i(2, 4, 5, 7)); constexpr auto a = Math::gather<'y', 'x', 'x'>(Vector<2, Int>{1, 2});
CORRADE_COMPARE(a, Vector4i(5, 2, 7, 4)); CORRADE_COMPARE(a, (Vector3i{2, 1, 1}));
constexpr auto b = Math::gather<'z'>(Vector4i{1, 2, 3, 4});
CORRADE_COMPARE(b, (Vector<1, Int>{3}));
constexpr auto c = Math::gather<'z', 'x', 'w', 'y', 'z', 'y', 'x'>(Vector4i{1, 2, 3, 4});
CORRADE_COMPARE(c, (Vector<7, Int>{3, 1, 4, 2, 3, 2, 1}));
} }
void SwizzleTest::sizes() { void SwizzleTest::scatter() {
constexpr auto a = swizzle<'y', 'x', 'x'>(Vector<2, Int>(1, 2)); constexpr auto a = Math::scatter<'w', 'y'>(Vector4i{2, 4, 5, 7}, Vector2i{1, 3});
CORRADE_COMPARE(a, (Vector<3, Int>(2, 1, 1))); constexpr auto b = Math::scatter<'a', 'g'>(Vector4i{2, 4, 5, 7}, Vector2i{1, 3});
CORRADE_COMPARE(a, (Vector4i{2, 3, 5, 1}));
CORRADE_COMPARE(b, (Vector4i{2, 3, 5, 1}));
/* It's an inverse, so doing the same gather should result back in the
original values */
CORRADE_COMPARE((Math::gather<'w', 'y'>(a)), (Vector2i{1, 3}));
}
constexpr auto b = swizzle<'z'>(Vector4i(1, 2, 3, 4)); void SwizzleTest::scatterOneComponent() {
CORRADE_COMPARE(b, (Vector<1, Int>(3))); constexpr auto a = Math::scatter<'w'>(Vector<7, Int>{2, 4, 5, 7, 0, 3, 2}, 1);
constexpr auto b = Math::scatter<'a'>(Vector<7, Int>{2, 4, 5, 7, 0, 3, 2}, 1);
CORRADE_COMPARE(a, (Vector<7, Int>{2, 4, 5, 1, 0, 3, 2}));
CORRADE_COMPARE(b, (Vector<7, Int>{2, 4, 5, 1, 0, 3, 2}));
}
void SwizzleTest::scatterRepeatedComponents() {
constexpr auto a = Math::scatter<'x', 'y', 'z', 'y', 'x'>(Vector3i{6, 12, 19}, Vector<5, Int>{1, 2, 3, 4, 5});
constexpr auto b = Math::scatter<'r', 'g', 'b', 'g', 'r'>(Vector3i{6, 12, 19}, Vector<5, Int>{1, 2, 3, 4, 5});
CORRADE_COMPARE(a, (Vector3i{5, 4, 3}));
CORRADE_COMPARE(b, (Vector3i{5, 4, 3}));
}
constexpr auto c = swizzle<'z', 'x', 'w', 'y', 'z', 'y', 'x'>(Vector4i(1, 2, 3, 4)); void SwizzleTest::scatterOverwriteAllComponents() {
CORRADE_COMPARE(c, (Vector<7, Int>(3, 1, 4, 2, 3, 2, 1))); constexpr auto a = Math::scatter<'w', 'y', 'z', 'x'>(Vector4i{2, 4, 5, 7}, Vector4i{1, 3, 6, 9});
constexpr auto b = Math::gather<'w', 'y', 'z', 'x'>(Vector4i{1, 3, 6, 9});
CORRADE_COMPARE(a, (Vector4i{9, 3, 6, 1}));
CORRADE_COMPARE(b, (Vector4i{9, 3, 6, 1}));
} }
}}}} }}}}

2
src/Magnum/Math/Test/Vector2Test.cpp

@ -250,7 +250,7 @@ void Vector2Test::strictWeakOrdering() {
void Vector2Test::swizzleType() { void Vector2Test::swizzleType() {
constexpr Vector<4, Int> orig; constexpr Vector<4, Int> orig;
constexpr auto a = swizzle<'y', 'a'>(orig); constexpr auto a = gather<'y', 'a'>(orig);
CORRADE_VERIFY((std::is_same<decltype(a), const Vector2i>::value)); CORRADE_VERIFY((std::is_same<decltype(a), const Vector2i>::value));
} }

2
src/Magnum/Math/Test/Vector3Test.cpp

@ -274,7 +274,7 @@ void Vector3Test::strictWeakOrdering() {
void Vector3Test::swizzleType() { void Vector3Test::swizzleType() {
constexpr Vector<4, Int> orig; constexpr Vector<4, Int> orig;
constexpr auto b = swizzle<'y', 'z', 'a'>(orig); constexpr auto b = gather<'y', 'z', 'a'>(orig);
CORRADE_VERIFY((std::is_same<decltype(b), const Vector3i>::value)); CORRADE_VERIFY((std::is_same<decltype(b), const Vector3i>::value));
} }

2
src/Magnum/Math/Test/Vector4Test.cpp

@ -317,7 +317,7 @@ void Vector4Test::strictWeakOrdering() {
void Vector4Test::swizzleType() { void Vector4Test::swizzleType() {
constexpr Vector4i orig; constexpr Vector4i orig;
constexpr auto c = swizzle<'y', 'a', 'y', 'x'>(orig); constexpr auto c = gather<'y', 'a', 'y', 'x'>(orig);
CORRADE_VERIFY((std::is_same<decltype(c), const Vector4i>::value)); CORRADE_VERIFY((std::is_same<decltype(c), const Vector4i>::value));
} }

4
src/Magnum/Math/Vector3.h

@ -51,8 +51,8 @@ https://twitter.com/sjb3d/status/563640846671953920): @f[
@see @ref cross(const Vector2<T>&, const Vector2<T>&), @ref planeEquation() @see @ref cross(const Vector2<T>&, const Vector2<T>&), @ref planeEquation()
*/ */
template<class T> inline Vector3<T> cross(const Vector3<T>& a, const Vector3<T>& b) { template<class T> inline Vector3<T> cross(const Vector3<T>& a, const Vector3<T>& b) {
return swizzle<'y', 'z', 'x'>(a*swizzle<'y', 'z', 'x'>(b) - return gather<'y', 'z', 'x'>(a*gather<'y', 'z', 'x'>(b) -
b*swizzle<'y', 'z', 'x'>(a)); b*gather<'y', 'z', 'x'>(a));
} }
/** /**

4
src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp

@ -82,11 +82,11 @@ Containers::Array<char> TgaImageConverter::doExportToData(const ImageView2D& ima
if(image.format() == PixelFormat::RGB8Unorm) { if(image.format() == PixelFormat::RGB8Unorm) {
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.begin()+sizeof(Implementation::TgaHeader)); auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.begin()+sizeof(Implementation::TgaHeader));
std::transform(pixels, pixels + image.size().product(), pixels, std::transform(pixels, pixels + image.size().product(), pixels,
[](Math::Vector3<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r'>(pixel); }); [](Math::Vector3<UnsignedByte> pixel) { return Math::gather<'b', 'g', 'r'>(pixel); });
} else if(image.format() == PixelFormat::RGBA8Unorm) { } else if(image.format() == PixelFormat::RGBA8Unorm) {
auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.begin()+sizeof(Implementation::TgaHeader)); auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.begin()+sizeof(Implementation::TgaHeader));
std::transform(pixels, pixels + image.size().product(), pixels, std::transform(pixels, pixels + image.size().product(), pixels,
[](Math::Vector4<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r', 'a'>(pixel); }); [](Math::Vector4<UnsignedByte> pixel) { return Math::gather<'b', 'g', 'r', 'a'>(pixel); });
} }
return data; return data;

4
src/MagnumPlugins/TgaImporter/TgaImporter.cpp

@ -136,11 +136,11 @@ Containers::Optional<ImageData2D> TgaImporter::doImage2D(UnsignedInt) {
if(format == PixelFormat::RGB8Unorm) { if(format == PixelFormat::RGB8Unorm) {
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.data()); auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.data());
std::transform(pixels, pixels + size.product(), pixels, std::transform(pixels, pixels + size.product(), pixels,
[](Math::Vector3<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r'>(pixel); }); [](Math::Vector3<UnsignedByte> pixel) { return Math::gather<'b', 'g', 'r'>(pixel); });
} else if(format == PixelFormat::RGBA8Unorm) { } else if(format == PixelFormat::RGBA8Unorm) {
auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.data()); auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.data());
std::transform(pixels, pixels + size.product(), pixels, std::transform(pixels, pixels + size.product(), pixels,
[](Math::Vector4<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r', 'a'>(pixel); }); [](Math::Vector4<UnsignedByte> pixel) { return Math::gather<'b', 'g', 'r', 'a'>(pixel); });
} }
return ImageData2D{storage, format, size, std::move(data)}; return ImageData2D{storage, format, size, std::move(data)};

Loading…
Cancel
Save