diff --git a/src/nvimage/FloatImage.cpp b/src/nvimage/FloatImage.cpp index 8cfb5f7..9e51d00 100644 --- a/src/nvimage/FloatImage.cpp +++ b/src/nvimage/FloatImage.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "FloatImage.h" #include "Filter.h" @@ -240,6 +241,52 @@ void FloatImage::exponentiate(uint base_component, uint num, float power) } } +/// Apply linear transform. +void FloatImage::transform(uint base_component, const Matrix & m) +{ + nvCheck(base_component + 4 <= m_componentNum); + + const uint size = m_width * m_height; + + float * r = this->channel(base_component + 0); + float * g = this->channel(base_component + 1); + float * b = this->channel(base_component + 2); + float * a = this->channel(base_component + 3); + + for (uint i = 0; i < size; i++) + { + Vector4 color = nv::transform(m, Vector4(*r, *g, *b, *a)); + + *r++ = color.x(); + *g++ = color.y(); + *b++ = color.z(); + *a++ = color.w(); + } +} + +void FloatImage::swizzle(uint base_component, uint r, uint g, uint b, uint a) +{ + nvCheck(base_component + 4 <= m_componentNum); + + const uint size = m_width * m_height; + + float * c[4]; + c[0] = this->channel(base_component + 0); + c[1] = this->channel(base_component + 1); + c[2] = this->channel(base_component + 2); + c[3] = this->channel(base_component + 3); + + for (uint i = 0; i < size; i++) + { + float tmp[4] = { c[r], c[g], c[b], c[a] }; + + *r++ = tmp[0]; + *g++ = tmp[1]; + *b++ = tmp[2]; + *a++ = tmp[3]; + } +} + float FloatImage::sampleNearest(const float x, const float y, const int c, const WrapMode wm) const { if( wm == WrapMode_Clamp ) return sampleNearestClamp(x, y, c); diff --git a/src/nvimage/FloatImage.h b/src/nvimage/FloatImage.h index 4bbdae0..494c22f 100644 --- a/src/nvimage/FloatImage.h +++ b/src/nvimage/FloatImage.h @@ -11,6 +11,7 @@ namespace nv { +class Matrix; class Image; class Filter; class Kernel1; @@ -62,6 +63,8 @@ public: NVIMAGE_API void toGamma(uint base_component, uint num, float gamma = 2.2f); NVIMAGE_API void exponentiate(uint base_component, uint num, float power); + NVIMAGE_API void transform(uint base_component, const Matrix & m); + NVIMAGE_API void swizzle(uint base_component, uint r, uint g, uint b, uint a); NVIMAGE_API FloatImage * fastDownSample() const; NVIMAGE_API FloatImage * downSample(const Filter & filter, WrapMode wm) const; diff --git a/src/nvtt/Compressor.cpp b/src/nvtt/Compressor.cpp index bddd391..7534631 100644 --- a/src/nvtt/Compressor.cpp +++ b/src/nvtt/Compressor.cpp @@ -651,9 +651,20 @@ void Compressor::Private::processInputImage(Mipmap & mipmap, const InputOptions: { mipmap.toFloatImage(inputOptions); } - } - // @@ Linear and swizzle color transforms should be done here. + // Apply linear transforms in linear space. + FloatImage * image = mipmap.asFloatImage(); + nvDebugCheck(image != NULL); + + if (inputOptions.colorTransform == ColorTransform_Linear) + { + image->transform(0, inputOptions.linearTransform); + } + else if (inputOptions.colorTransform == ColorTransform_Swizzle) + { + image->swizzle(0, input.swizzleTransform[0], input.swizzleTransform[1], input.swizzleTransform[2], input.swizzleTransform[3]); + } + } } diff --git a/src/nvtt/InputOptions.cpp b/src/nvtt/InputOptions.cpp index d4a6f63..b537e42 100644 --- a/src/nvtt/InputOptions.cpp +++ b/src/nvtt/InputOptions.cpp @@ -316,10 +316,10 @@ void InputOptions::setSwizzleTransform(int x, int y, int z, int w) nvCheck(z >= 0 && z < 3); nvCheck(w >= 0 && w < 3); - // m.xswizzle = x; - // m.yswizzle = y; - // m.zswizzle = z; - // m.wswizzle = w; + m.swizzleTransform[0] = x; + m.swizzleTransform[1] = y; + m.swizzleTransform[2] = z; + m.swizzleTransform[3] = w; } void InputOptions::setMaxExtents(int e) diff --git a/src/nvtt/InputOptions.h b/src/nvtt/InputOptions.h index b8c5525..a4e487c 100644 --- a/src/nvtt/InputOptions.h +++ b/src/nvtt/InputOptions.h @@ -56,6 +56,7 @@ namespace nvtt // Color transform. ColorTransform colorTransform; nv::Matrix linearTransform; + uint swizzleTransform[4]; // Mipmap generation options. bool generateMipmaps;