[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36546] trunk/blender/source/blender/imbuf /intern/dds: Apply second half of [#21590] .dds textures: fix for DXT1n format + sync with upstream nvtt

Nathan Letwory nathan at letworyinteractive.com
Sun May 8 11:05:53 CEST 2011


Revision: 36546
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36546
Author:   jesterking
Date:     2011-05-08 09:05:52 +0000 (Sun, 08 May 2011)
Log Message:
-----------
Apply second half of [#21590] .dds textures: fix for DXT1n format + sync with upstream nvtt
submitted by Amorilia

This updates the DDS module with upstearm nvtt (r1042).

Revision Links:
--------------
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=1042

Modified Paths:
--------------
    trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.cpp
    trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.h
    trunk/blender/source/blender/imbuf/intern/dds/ColorBlock.cpp
    trunk/blender/source/blender/imbuf/intern/dds/ColorBlock.h
    trunk/blender/source/blender/imbuf/intern/dds/Common.h
    trunk/blender/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
    trunk/blender/source/blender/imbuf/intern/dds/DirectDrawSurface.h
    trunk/blender/source/blender/imbuf/intern/dds/Image.cpp
    trunk/blender/source/blender/imbuf/intern/dds/PixelFormat.h

Modified: trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.cpp
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.cpp	2011-05-08 05:41:57 UTC (rev 36545)
+++ trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.cpp	2011-05-08 09:05:52 UTC (rev 36546)
@@ -123,6 +123,53 @@
 	}
 }
 
+
+uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
+{
+	// Does bit expansion before interpolation.
+	color_array[0].b = (3 * col0.b * 22) / 8;
+	color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+	color_array[0].r = (3 * col0.r * 22) / 8;
+	color_array[0].a = 0xFF;
+
+	color_array[1].r = (3 * col1.r * 22) / 8;
+	color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+	color_array[1].b = (3 * col1.b * 22) / 8;
+	color_array[1].a = 0xFF;
+	
+    int gdiff = color_array[1].g - color_array[0].g;
+
+	if( col0.u > col1.u ) {
+		// Four-color block: derive the other two colors.
+        color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8;
+        color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256;
+        color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8;
+		color_array[2].a = 0xFF;
+		
+        color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8;
+        color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256;
+        color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8;
+		color_array[3].a = 0xFF;
+
+		return 4;
+	}
+	else {
+		// Three-color block: derive the other color.
+        color_array[2].r = ((col0.r + col1.r) * 33) / 8;
+        color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
+        color_array[2].b = ((col0.b + col1.b) * 33) / 8;
+		color_array[2].a = 0xFF;
+		
+		// Set all components to 0 to match DXT specs.
+		color_array[3].r = 0x00; // color_array[2].r;
+		color_array[3].g = 0x00; // color_array[2].g;
+		color_array[3].b = 0x00; // color_array[2].b;
+		color_array[3].a = 0x00;
+		
+		return 3;
+	}
+}
+
 // Evaluate palette assuming 3 color block.
 void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const
 {
@@ -174,6 +221,7 @@
 	color_array[3].a = 0xFF;
 }
 
+
 void BlockDXT1::decodeBlock(ColorBlock * block) const
 {
 	// Decode color block.
@@ -189,6 +237,21 @@
 	}	
 }
 
+void BlockDXT1::decodeBlockNV5x(ColorBlock * block) const
+{
+	// Decode color block.
+	Color32 color_array[4];
+	evaluatePaletteNV5x(color_array);
+
+	// Write color block.
+	for( uint j = 0; j < 4; j++ ) {
+		for( uint i = 0; i < 4; i++ ) {
+			uint idx = (row[j] >> (2 * i)) & 3;
+			block->color(i, j) = color_array[idx];
+		}
+	}
+}
+
 void BlockDXT1::setIndices(int * idx)
 {
 	indices = 0;
@@ -225,6 +288,12 @@
 	alpha.decodeBlock(block);
 }
 
+void BlockDXT3::decodeBlockNV5x(ColorBlock * block) const
+{
+	color.decodeBlockNV5x(block);
+	alpha.decodeBlock(block);
+}
+
 void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const
 {
 	block->color(0x0).a = (alpha0 << 4) | alpha0;
@@ -394,7 +463,15 @@
 	
 	// Decode alpha.
 	alpha.decodeBlock(block);
+}
 
+void BlockDXT5::decodeBlockNV5x(ColorBlock * block) const
+{
+	// Decode color.
+	color.decodeBlockNV5x(block);
+	
+	// Decode alpha.
+	alpha.decodeBlock(block);
 }
 
 /// Flip DXT5 block vertically.

Modified: trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.h
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.h	2011-05-08 05:41:57 UTC (rev 36545)
+++ trunk/blender/source/blender/imbuf/intern/dds/BlockDXT.h	2011-05-08 09:05:52 UTC (rev 36546)
@@ -78,11 +78,13 @@
 	bool isFourColorMode() const;
 
 	uint evaluatePalette(Color32 color_array[4]) const;
-	uint evaluatePaletteFast(Color32 color_array[4]) const;
+	uint evaluatePaletteNV5x(Color32 color_array[4]) const;
+
 	void evaluatePalette3(Color32 color_array[4]) const;
 	void evaluatePalette4(Color32 color_array[4]) const;
 	
 	void decodeBlock(ColorBlock * block) const;
+	void decodeBlockNV5x(ColorBlock * block) const;
 	
 	void setIndices(int * idx);
 
@@ -136,6 +138,7 @@
 	BlockDXT1 color;
 	
 	void decodeBlock(ColorBlock * block) const;
+	void decodeBlockNV5x(ColorBlock * block) const;
 	
 	void flip4();
 	void flip2();
@@ -213,6 +216,7 @@
 	BlockDXT1 color;
 	
 	void decodeBlock(ColorBlock * block) const;
+	void decodeBlockNV5x(ColorBlock * block) const;
 	
 	void flip4();
 	void flip2();

Modified: trunk/blender/source/blender/imbuf/intern/dds/ColorBlock.cpp
===================================================================
--- trunk/blender/source/blender/imbuf/intern/dds/ColorBlock.cpp	2011-05-08 05:41:57 UTC (rev 36545)
+++ trunk/blender/source/blender/imbuf/intern/dds/ColorBlock.cpp	2011-05-08 09:05:52 UTC (rev 36546)
@@ -83,65 +83,90 @@
 
 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);
+    init(img->width(), img->height(), (const uint *)img->pixels(), x, y);
+}
 
-	static int remainder[] = {
-		0, 0, 0, 0,
-		0, 1, 0, 1,
-		0, 1, 2, 0,
-		0, 1, 2, 3,
-	};
+void ColorBlock::init(uint w, uint h, const uint * data, uint x, uint y)
+{
+	const uint bw = min(w - x, 4U);
+	const uint bh = min(h - y, 4U);
 
+    // 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. :(
+    // @@ Ideally we should zero the weights of the pixels out of range.
+
+    for (uint i = 0; i < 4; i++)
+    {
+        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::init(uint w, uint h, const float * data, uint x, uint y)
+{
+    const uint bw = min(w - x, 4U);
+    const uint bh = min(h - y, 4U);
+
 	// 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. :(
+    // @@ Ideally we should zero the weights of the pixels out of range.
 
-	for(uint i = 0; i < 4; i++) {
-		//const int by = i % bh;
-		const int by = remainder[(bh - 1) * 4 + i];
-		for(uint e = 0; e < 4; e++) {
-			//const int bx = e % bw;
-			const int bx = remainder[(bw - 1) * 4 + e];
-			color(e, i) = img->pixel(x + bx, y + by);
-		}
-	}
-}
+    uint srcPlane = w * h;
 
-
-void ColorBlock::swizzleDXT5n()
-{
-	for(int i = 0; i < 16; i++)
+	for (uint i = 0; i < 4; i++)
 	{
-		Color32 c = m_color[i];
-		m_color[i] = Color32(0xFF, c.g, 0, c.r);
+		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);
+			
+			Color32 & c = color(e, i);
+            c.r = uint8(255 * clamp(data[idx + 0 * srcPlane], 0.0f, 1.0f)); // @@ Is this the right way to quantize floats to bytes?
+            c.g = uint8(255 * clamp(data[idx + 1 * srcPlane], 0.0f, 1.0f));
+            c.b = uint8(255 * clamp(data[idx + 2 * srcPlane], 0.0f, 1.0f));
+            c.a = uint8(255 * clamp(data[idx + 3 * srcPlane], 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
+bool ColorBlock::isSingleColor(Color32 mask/*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
 {
-	Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
 	uint u = m_color[0].u & mask.u;
 	
-	for(int i = 1; i < 16; i++)
+	for (int i = 1; i < 16; i++)
 	{
 		if (u != (m_color[i].u & mask.u))
 		{
@@ -152,6 +177,7 @@
 	return true;
 }
 
+/*
 /// Returns true if the block has a single color, ignoring transparent pixels.
 bool ColorBlock::isSingleColorNoAlpha() const
 {
@@ -159,7 +185,7 @@
 	int i;
 	for(i = 0; i < 16; i++)
 	{
-		if (m_color[i].a != 0) c = m_color[i];
+        if (m_color[i].a != 0) c = m_color[i];
 	}
 
 	Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
@@ -175,9 +201,10 @@
 	
 	return true;
 }
+*/
 
 /// Count number of unique colors in this color block.
-uint ColorBlock::countUniqueColors() const
+/*uint ColorBlock::countUniqueColors() const
 {
 	uint count = 0;
 
@@ -197,9 +224,9 @@
 	}
 	
 	return count;
-}
+}*/
 
-/// Get average color of the block.
+/*/// Get average color of the block.
 Color32 ColorBlock::averageColor() const
 {
 	uint r, g, b, a;
@@ -213,7 +240,7 @@
 	}
 	
 	return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16));
-}
+}*/
 
 /// Return true if the block is not fully opaque.
 bool ColorBlock::hasAlpha() const
@@ -225,6 +252,7 @@
 	return false;
 }
 
+#if 0
 
 /// Get diameter color range.
 void ColorBlock::diameterRange(Color32 * start, Color32 * end) const
@@ -345,8 +373,9 @@
 	*start = minColor;
 	*end = maxColor;
 }
+#endif
 
-/// Sort colors by abosolute value in their 16 bit representation.
+/*/// Sort colors by abosolute value in their 16 bit representation.
 void ColorBlock::sortColorsByAbsoluteValue()
 {
 	// Dummy selection sort.
@@ -364,4 +393,75 @@
 		}
 		swap( m_color[a], m_color[max] );
 	}
+}*/
+
+
+/*/// Find extreme colors in the given axis.
+void ColorBlock::computeRange(Vector3::Arg axis, Color32 * start, Color32 * end) const
+{
+	
+	int mini, maxi;
+	mini = maxi = 0;
+	
+	float min, max;	
+	min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis);
+
+	for(uint i = 1; i < 16; i++)
+	{
+		const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
+		
+		float val = dot(vec, axis);
+		if( val < min ) {
+			mini = i;
+			min = val;
+		}
+		else if( val > max ) {
+			maxi = i;
+			max = val;
+		}
+	}
+	
+	*start = m_color[mini];
+	*end = m_color[maxi];
+}*/
+
+
+/*/// Sort colors in the given axis.
+void ColorBlock::sortColors(const Vector3 & axis)
+{
+	float luma_array[16];
+	
+	for(uint i = 0; i < 16; i++) {
+		const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
+		luma_array[i] = dot(vec, axis);
+	}
+	

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list