Преглед на файлове

texturec: Added mip-map gen.

Branimir Karadžić преди 10 години
родител
ревизия
026a2563f1
променени са 3 файла, в които са добавени 63 реда и са изтрити 6 реда
  1. 31 0
      src/image.cpp
  2. 3 0
      src/image.h
  3. 29 6
      tools/texturec/texturec.cpp

+ 31 - 0
src/image.cpp

@@ -238,6 +238,37 @@ namespace bgfx
 		return TextureFormat::Unknown;
 	}
 
+	uint8_t imageGetNumMips(TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth)
+	{
+		const ImageBlockInfo& blockInfo = getBlockInfo(_format);
+		const uint8_t  bpp         = blockInfo.bitsPerPixel;
+		const uint16_t blockWidth  = blockInfo.blockWidth;
+		const uint16_t blockHeight = blockInfo.blockHeight;
+		const uint16_t minBlockX   = blockInfo.minBlockX;
+		const uint16_t minBlockY   = blockInfo.minBlockY;
+
+		_width   = bx::uint16_max(blockWidth  * minBlockX, ( (_width  + blockWidth  - 1) / blockWidth)*blockWidth);
+		_height  = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
+		_depth   = bx::uint16_max(1, _depth);
+
+		uint8_t numMips = 0;
+
+		for (uint32_t width = _width, height = _height, depth = _depth
+			; blockWidth < width && blockHeight < height && 1 < depth
+			; ++numMips)
+		{
+			width  = bx::uint32_max(blockWidth  * minBlockX, ( (width  + blockWidth  - 1) / blockWidth )*blockWidth);
+			height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
+			depth  = bx::uint32_max(1, depth);
+
+			width  >>= 1;
+			height >>= 1;
+			depth  >>= 1;
+		}
+
+		return numMips;
+	}
+
 	uint32_t imageGetSize(TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, uint8_t _numMips)
 	{
 		const ImageBlockInfo& blockInfo = getBlockInfo(_format);

+ 3 - 0
src/image.h

@@ -90,6 +90,9 @@ namespace bgfx
 	/// Converts string to format.
 	TextureFormat::Enum getFormat(const char* _name);
 
+	/// Returns number of mip-maps required for complete mip-map chain.
+	uint8_t imageGetNumMips(TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth = 0);
+
 	/// Returns image size.
 	uint32_t imageGetSize(TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth = 0, bool _cubeMap = false, uint8_t _numMips = 0);
 

+ 29 - 6
tools/texturec/texturec.cpp

@@ -123,6 +123,10 @@ namespace bgfx
 		case TextureFormat::PTC24:
 			break;
 
+		case TextureFormat::BGRA8:
+			imageSwizzleBgra8(_width, _height, _width*4, _src, _dst);
+			break;
+
 		case TextureFormat::RGBA8:
 			memcpy(_dst, _src, _width*_height*4);
 			break;
@@ -259,7 +263,6 @@ int main(int _argc, const char* _argv[])
 			}
 		}
 
-		BX_UNUSED(mips);
 		if (loaded)
 		{
 			bx::CrtAllocator allocator;
@@ -271,16 +274,36 @@ int main(int _argc, const char* _argv[])
 				uint32_t size = imageGetSize(TextureFormat::RGBA8, mip.m_width, mip.m_height);
 				uint8_t* rgba = (uint8_t*)BX_ALLOC(&allocator, size);
 
-				imageDecodeToRgba8(rgba, mip.m_data, mip.m_width, mip.m_height, mip.m_width*mip.m_bpp/8, mip.m_format);
-
-				imageContainer.m_size   = imageGetSize(format, mip.m_width, mip.m_height);
+				imageDecodeToRgba8(rgba
+					, mip.m_data
+					, mip.m_width
+					, mip.m_height
+					, mip.m_width*mip.m_bpp/8
+					, mip.m_format
+					);
+
+				uint8_t numMips = mips
+					? imageGetNumMips(format, mip.m_width, mip.m_height)
+					: 1
+					;
+				imageContainer.m_size   = imageGetSize(format, mip.m_width, mip.m_height, 0, false, numMips);
 				imageContainer.m_format = format;
 				output = alloc(imageContainer.m_size);
 
-	//			bgfx::imageRgba8Downsample2x2(width, height, pitch, data, data);
-
 				imageEncodeFromRgba8(output->data, rgba, mip.m_width, mip.m_height, format);
 
+				for (uint8_t lod = 1; lod < numMips; ++lod)
+				{
+					ImageMip mip1;
+					imageGetRawData(imageContainer, 0, lod, output->data, output->size, mip1);
+					uint8_t* data = const_cast<uint8_t*>(mip1.m_data);
+
+					uint32_t width  = bx::uint32_max(1, mip.m_width >>lod);
+					uint32_t height = bx::uint32_max(1, mip.m_height>>lod);
+					imageRgba8Downsample2x2(width, height, width*4, rgba, rgba);
+					imageEncodeFromRgba8(data, rgba, mip.m_width, mip.m_height, format);
+				}
+
 				BX_FREE(&allocator, rgba);
 			}