From fd11f5e7ef03d98067f1ca74d91ebd699349a073 Mon Sep 17 00:00:00 2001 From: castano Date: Wed, 21 Oct 2009 07:39:59 +0000 Subject: [PATCH] Implement generic swizzle, remove specialized ones. --- src/nvimage/ColorBlock.cpp | 82 ++++++++++++++++++++++++++++---------- src/nvimage/ColorBlock.h | 7 ++-- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/nvimage/ColorBlock.cpp b/src/nvimage/ColorBlock.cpp index 27d07ef..16cd922 100644 --- a/src/nvimage/ColorBlock.cpp +++ b/src/nvimage/ColorBlock.cpp @@ -58,9 +58,7 @@ void ColorBlock::init(const Image * img, uint x, uint y) const uint bw = min(img->width() - x, 4U); const uint bh = min(img->height() - y, 4U); - - nvDebugCheck(bw != 0); - nvDebugCheck(bh != 0); + nvDebugCheck(bw != 0 && bh != 0); static const int remainder[] = { 0, 0, 0, 0, @@ -83,43 +81,83 @@ void ColorBlock::init(const Image * img, uint x, uint y) } } - -void ColorBlock::swizzleDXT5n() +void ColorBlock::init(uint w, uint h, uint * data, uint x, uint y) { - for(int i = 0; i < 16; i++) + nvDebugCheck(data != NULL); + + const uint bw = min(w - x, 4U); + const uint bh = min(h - y, 4U); + nvDebugCheck(bw != 0 && bh != 0); + + // Blocks that are smaller than 4x4 are handled by repeating the pixels. + // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :( + + for (uint i = 0; i < 4; i++) { - Color32 c = m_color[i]; - m_color[i] = Color32(0xFF, c.g, 0, c.r); + const int by = i % bh; + + for (uint e = 0; e < 4; e++) + { + const int bx = e % bw; + const uint idx = (y + by) * w + x + bx; + + color(e, i).u = data[idx]; + } } } -void ColorBlock::swizzleSTB() +void ColorBlock::init(uint w, uint h, float * data, uint x, uint y) { - for(int i = 0; i < 16; i++) + nvDebugCheck(data != NULL); + + const uint bw = min(w - x, 4U); + const uint bh = min(h - y, 4U); + nvDebugCheck(bw != 0 && bh != 0); + + // Blocks that are smaller than 4x4 are handled by repeating the pixels. + // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :( + + for (uint i = 0; i < 4; i++) { - Color32 c = m_color[i]; - m_color[i] = Color32(c.b, c.g, c.r, c.a); + const uint by = i % bh; + + for (uint e = 0; e < 4; e++) + { + const uint bx = e % bw; + const uint idx = ((y + by) * w + x + bx) * 4; + + Color32 & c = color(e, i); + c.r = uint8(255 * clamp(data[idx + 0], 0.0f, 1.0f)); + c.g = uint8(255 * clamp(data[idx + 1], 0.0f, 1.0f)); + c.b = uint8(255 * clamp(data[idx + 2], 0.0f, 1.0f)); + c.a = uint8(255 * clamp(data[idx + 3], 0.0f, 1.0f)); + } } } -void ColorBlock::splatX() +static inline uint8 component(Color32 c, uint i) { - for(int i = 0; i < 16; i++) - { - uint8 x = m_color[i].r; - m_color[i] = Color32(x, x, x, x); - } + if (i == 0) return c.r; + if (i == 1) return c.g; + if (i == 2) return c.b; + if (i == 3) return c.a; + if (i == 4) return 0xFF; + return 0; } -void ColorBlock::splatY() +void ColorBlock::swizzle(uint x, uint y, uint z, uint w) { - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { - uint8 y = m_color[i].g; - m_color[i] = Color32(y, y, y, y); + Color32 c = m_color[i]; + m_color[i].r = component(c, x); + m_color[i].g = component(c, y); + m_color[i].b = component(c, z); + m_color[i].a = component(c, w); } } + /// Returns true if the block has a single color. bool ColorBlock::isSingleColor() const { diff --git a/src/nvimage/ColorBlock.h b/src/nvimage/ColorBlock.h index 3b8b77e..0588d92 100644 --- a/src/nvimage/ColorBlock.h +++ b/src/nvimage/ColorBlock.h @@ -18,11 +18,10 @@ namespace nv ColorBlock(const Image * img, uint x, uint y); void init(const Image * img, uint x, uint y); + void init(uint w, uint h, uint * data, uint x, uint y); + void init(uint w, uint h, float * data, uint x, uint y); - void swizzleDXT5n(); - void swizzleSTB(); - void splatX(); - void splatY(); + void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0 bool isSingleColor() const; bool isSingleColorNoAlpha() const;