فهرست منبع

texturec: Added premultiplied alpha option.

Branimir Karadžić 7 سال پیش
والد
کامیت
6bd4ba8fdd
1فایلهای تغییر یافته به همراه87 افزوده شده و 3 حذف شده
  1. 87 3
      tools/texturec/texturec.cpp

+ 87 - 3
tools/texturec/texturec.cpp

@@ -39,6 +39,7 @@ struct Options
 		, normalMap(false)
 		, normalMap(false)
 		, equirect(false)
 		, equirect(false)
 		, iqa(false)
 		, iqa(false)
+		, pma(false)
 		, sdf(false)
 		, sdf(false)
 		, alphaTest(false)
 		, alphaTest(false)
 	{
 	{
@@ -53,6 +54,7 @@ struct Options
 			"\t     mips: %s\n"
 			"\t     mips: %s\n"
 			"\tnormalMap: %s\n"
 			"\tnormalMap: %s\n"
 			"\t      iqa: %s\n"
 			"\t      iqa: %s\n"
+			"\t      pma: %s\n"
 			"\t      sdf: %s\n"
 			"\t      sdf: %s\n"
 			, maxSize
 			, maxSize
 			, edge
 			, edge
@@ -60,6 +62,7 @@ struct Options
 			, mips      ? "true" : "false"
 			, mips      ? "true" : "false"
 			, normalMap ? "true" : "false"
 			, normalMap ? "true" : "false"
 			, iqa       ? "true" : "false"
 			, iqa       ? "true" : "false"
+			, pma       ? "true" : "false"
 			, sdf       ? "true" : "false"
 			, sdf       ? "true" : "false"
 			);
 			);
 	}
 	}
@@ -72,6 +75,7 @@ struct Options
 	bool normalMap;
 	bool normalMap;
 	bool equirect;
 	bool equirect;
 	bool iqa;
 	bool iqa;
+	bool pma;
 	bool sdf;
 	bool sdf;
 	bool alphaTest;
 	bool alphaTest;
 };
 };
@@ -88,14 +92,42 @@ void imageRgba32fNormalize(void* _dst, uint32_t _width, uint32_t _height, uint32
 		{
 		{
 			float xyz[3];
 			float xyz[3];
 
 
-			xyz[0]  = rgba[0];
-			xyz[1]  = rgba[1];
-			xyz[2]  = rgba[2];
+			xyz[0] = rgba[0];
+			xyz[1] = rgba[1];
+			xyz[2] = rgba[2];
 			bx::vec3Norm( (float*)dst, xyz);
 			bx::vec3Norm( (float*)dst, xyz);
 		}
 		}
 	}
 	}
 }
 }
 
 
+void imagePremultiplyAlpha(void* _inOut, uint32_t _width, uint32_t _height, uint32_t _depth, bimg::TextureFormat::Enum _format)
+{
+	uint8_t* inOut = (uint8_t*)_inOut;
+	uint32_t bpp = bimg::getBitsPerPixel(_format);
+	uint32_t pitch = _width*bpp/8;
+
+	bimg::PackFn   pack   = bimg::getPack(_format);
+	bimg::UnpackFn unpack = bimg::getUnpack(_format);
+
+	for (uint32_t zz = 0; zz < _depth; ++zz)
+	{
+		for (uint32_t yy = 0; yy < _height; ++yy)
+		{
+			for (uint32_t xx = 0; xx < _width; ++xx)
+			{
+				const uint32_t offset = yy*pitch + xx*bpp/8;
+
+				float rgba[4];
+				unpack(rgba, &inOut[offset]);
+				rgba[0] *= rgba[3];
+				rgba[1] *= rgba[3];
+				rgba[2] *= rgba[3];
+				pack(&inOut[offset], rgba);
+			}
+		}
+	}
+}
+
 bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData, uint32_t _inputSize, const Options& _options, bx::Error* _err)
 bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData, uint32_t _inputSize, const Options& _options, bx::Error* _err)
 {
 {
 	BX_ERROR_SCOPE(_err);
 	BX_ERROR_SCOPE(_err);
@@ -173,6 +205,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 			&& !_options.normalMap
 			&& !_options.normalMap
 			&& !_options.equirect
 			&& !_options.equirect
 			&& !_options.iqa
 			&& !_options.iqa
+			&& !_options.pma
 			;
 			;
 
 
 		if (needResize)
 		if (needResize)
@@ -257,6 +290,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 
 
 				void* temp = NULL;
 				void* temp = NULL;
 
 
+				// Normal map.
 				if (_options.normalMap)
 				if (_options.normalMap)
 				{
 				{
 					uint32_t size = bimg::imageGetSize(
 					uint32_t size = bimg::imageGetSize(
@@ -360,6 +394,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 
 
 					BX_FREE(_allocator, rgbaDst);
 					BX_FREE(_allocator, rgbaDst);
 				}
 				}
+				// HDR
 				else if ( (!bimg::isCompressed(input->m_format) && 8 != inputBlockInfo.rBits)
 				else if ( (!bimg::isCompressed(input->m_format) && 8 != inputBlockInfo.rBits)
 					 || outputFormat == bimg::TextureFormat::BC6H
 					 || outputFormat == bimg::TextureFormat::BC6H
 					 || outputFormat == bimg::TextureFormat::BC7
 					 || outputFormat == bimg::TextureFormat::BC7
@@ -389,6 +424,17 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 						, mip.m_format
 						, mip.m_format
 						);
 						);
 
 
+					if (_options.pma)
+					{
+						imagePremultiplyAlpha(
+							  rgba32f
+							, dstMip.m_width
+							, dstMip.m_height
+							, dstMip.m_depth
+							, bimg::TextureFormat::RGBA32F
+							);
+					}
+
 					bimg::imageEncodeFromRgba32f(_allocator
 					bimg::imageEncodeFromRgba32f(_allocator
 						, dstData
 						, dstData
 						, rgba32f
 						, rgba32f
@@ -421,6 +467,17 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 								, rgba32f
 								, rgba32f
 								);
 								);
 
 
+							if (_options.pma)
+							{
+								imagePremultiplyAlpha(
+									  rgba32f
+									, dstMip.m_width
+									, dstMip.m_height
+									, dstMip.m_depth
+									, bimg::TextureFormat::RGBA32F
+									);
+							}
+
 							bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
 							bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
 							dstData = const_cast<uint8_t*>(dstMip.m_data);
 							dstData = const_cast<uint8_t*>(dstMip.m_data);
 
 
@@ -447,6 +504,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 
 
 					BX_FREE(_allocator, rgbaDst);
 					BX_FREE(_allocator, rgbaDst);
 				}
 				}
+				// SDF
 				else if (_options.sdf)
 				else if (_options.sdf)
 				{
 				{
 					uint32_t size = bimg::imageGetSize(
 					uint32_t size = bimg::imageGetSize(
@@ -484,6 +542,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 						, rgba
 						, rgba
 						);
 						);
 				}
 				}
+				// RGBA8
 				else
 				else
 				{
 				{
 					uint32_t size = bimg::imageGetSize(
 					uint32_t size = bimg::imageGetSize(
@@ -526,8 +585,20 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 						bx::memCopy(ref, rgba, size);
 						bx::memCopy(ref, rgba, size);
 					}
 					}
 
 
+					if (_options.pma)
+					{
+						imagePremultiplyAlpha(
+							  rgba
+							, dstMip.m_width
+							, dstMip.m_height
+							, dstMip.m_depth
+							, bimg::TextureFormat::RGBA8
+							);
+					}
+
 					bimg::imageGetRawData(*output, side, 0, output->m_data, output->m_size, dstMip);
 					bimg::imageGetRawData(*output, side, 0, output->m_data, output->m_size, dstMip);
 					dstData = const_cast<uint8_t*>(dstMip.m_data);
 					dstData = const_cast<uint8_t*>(dstMip.m_data);
+
 					bimg::imageEncodeFromRgba8(dstData
 					bimg::imageEncodeFromRgba8(dstData
 						, rgba
 						, rgba
 						, dstMip.m_width
 						, dstMip.m_width
@@ -561,6 +632,17 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 								);
 								);
 						}
 						}
 
 
+						if (_options.pma)
+						{
+							imagePremultiplyAlpha(
+								  rgba
+								, dstMip.m_width
+								, dstMip.m_height
+								, dstMip.m_depth
+								, bimg::TextureFormat::RGBA8
+								);
+						}
+
 						bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
 						bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
 						dstData = const_cast<uint8_t*>(dstMip.m_data);
 						dstData = const_cast<uint8_t*>(dstMip.m_data);
 
 
@@ -667,6 +749,7 @@ void help(const char* _error = NULL, bool _showHelp = true)
 		  "      --sdf <edge>         Compute SDF texture.\n"
 		  "      --sdf <edge>         Compute SDF texture.\n"
 		  "      --ref <alpha>        Alpha reference value.\n"
 		  "      --ref <alpha>        Alpha reference value.\n"
 		  "      --iqa                Image Quality Assessment\n"
 		  "      --iqa                Image Quality Assessment\n"
+		  "      --pma                Premultiply alpha into RGB channel.\n"
 		  "      --max <max size>     Maximum width/height (image will be scaled down and\n"
 		  "      --max <max size>     Maximum width/height (image will be scaled down and\n"
 		  "                           aspect ratio will be preserved.\n"
 		  "                           aspect ratio will be preserved.\n"
 		  "      --as <extension>     Save as.\n"
 		  "      --as <extension>     Save as.\n"
@@ -765,6 +848,7 @@ int main(int _argc, const char* _argv[])
 	options.normalMap = cmdLine.hasArg('n',  "normalmap");
 	options.normalMap = cmdLine.hasArg('n',  "normalmap");
 	options.equirect  = cmdLine.hasArg("equirect");
 	options.equirect  = cmdLine.hasArg("equirect");
 	options.iqa       = cmdLine.hasArg("iqa");
 	options.iqa       = cmdLine.hasArg("iqa");
+	options.pma       = cmdLine.hasArg("pma");
 
 
 	const char* maxSize = cmdLine.findOption("max");
 	const char* maxSize = cmdLine.findOption("max");
 	if (NULL != maxSize)
 	if (NULL != maxSize)