Explorar el Código

More work on the image importer

Panagiotis Christopoulos Charitos hace 4 años
padre
commit
22c9655d15

+ 95 - 22
AnKi/Importer/ImageImporter.cpp

@@ -19,9 +19,11 @@ class SurfaceOrVolumeData
 {
 {
 public:
 public:
 	DynamicArrayAuto<U8, PtrSize> m_pixels;
 	DynamicArrayAuto<U8, PtrSize> m_pixels;
+	DynamicArrayAuto<U8, PtrSize> m_s3tcPixels;
 
 
 	SurfaceOrVolumeData(GenericMemoryPoolAllocator<U8> alloc)
 	SurfaceOrVolumeData(GenericMemoryPoolAllocator<U8> alloc)
 		: m_pixels(alloc)
 		: m_pixels(alloc)
+		, m_s3tcPixels(alloc)
 	{
 	{
 	}
 	}
 };
 };
@@ -241,14 +243,16 @@ static ANKI_USE_RESULT Error loadFirstMipmap(const ImageImporterConfig& config,
 }
 }
 
 
 template<U32 TCHANNEL_COUNT>
 template<U32 TCHANNEL_COUNT>
-static void generateSurfaceMipmap(const void* input, PtrSize inputBufferSize, U32 inWidth, U32 inHeight,
-								  PtrSize outputBufferSize, void* output)
+static void generateSurfaceMipmap(ConstWeakArray<U8, PtrSize> inBuffer, U32 inWidth, U32 inHeight,
+								  WeakArray<U8, PtrSize> outBuffer)
 {
 {
 	using UVecType = typename std::conditional_t<TCHANNEL_COUNT == 3, U8Vec3, U8Vec4>;
 	using UVecType = typename std::conditional_t<TCHANNEL_COUNT == 3, U8Vec3, U8Vec4>;
 	using FVecType = typename std::conditional_t<TCHANNEL_COUNT == 3, Vec3, Vec4>;
 	using FVecType = typename std::conditional_t<TCHANNEL_COUNT == 3, Vec3, Vec4>;
 
 
-	const UVecType* inPixels = static_cast<const UVecType*>(input);
-	UVecType* outPixels = static_cast<UVecType*>(output);
+	const ConstWeakArray<UVecType, PtrSize> inPixels(reinterpret_cast<const UVecType*>(&inBuffer[0]),
+													 inBuffer.getSizeInBytes() / sizeof(UVecType));
+	WeakArray<UVecType, PtrSize> outPixels(reinterpret_cast<UVecType*>(&outBuffer[0]),
+										   outBuffer.getSizeInBytes() / sizeof(UVecType));
 
 
 	const U32 outWidth = inWidth >> 1;
 	const U32 outWidth = inWidth >> 1;
 	const U32 outHeight = inHeight >> 1;
 	const U32 outHeight = inHeight >> 1;
@@ -264,7 +268,6 @@ static void generateSurfaceMipmap(const void* input, PtrSize inputBufferSize, U3
 				for(U32 x = 0; x < 2; ++x)
 				for(U32 x = 0; x < 2; ++x)
 				{
 				{
 					const U32 idx = (h * 2 + y) * inWidth + (w * 2 + x);
 					const U32 idx = (h * 2 + y) * inWidth + (w * 2 + x);
-					ANKI_ASSERT((idx + 1) * sizeof(UVecType) < inputBufferSize);
 					const UVecType inPixel = inPixels[idx];
 					const UVecType inPixel = inPixels[idx];
 					for(U32 c = 0; c < TCHANNEL_COUNT; ++c)
 					for(U32 c = 0; c < TCHANNEL_COUNT; ++c)
 					{
 					{
@@ -281,20 +284,18 @@ static void generateSurfaceMipmap(const void* input, PtrSize inputBufferSize, U3
 
 
 			// Store
 			// Store
 			const U32 idx = h * outWidth + w;
 			const U32 idx = h * outWidth + w;
-			ANKI_ASSERT((idx + 1) * sizeof(UVecType) < outputBufferSize);
 			outPixels[idx] = uaverage;
 			outPixels[idx] = uaverage;
 		}
 		}
 	}
 	}
 }
 }
 
 
 static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc, CString tempDirectory,
 static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc, CString tempDirectory,
-										  const void* inPixels, U32 inWidth, U32 inHeight, U32 componentCount,
-										  void* outPixels, PtrSize outPixelsBufferSize)
+										  ConstWeakArray<U8, PtrSize> inPixels, U32 inWidth, U32 inHeight,
+										  U32 channelCount, WeakArray<U8, PtrSize> outPixels)
 {
 {
-	ANKI_ASSERT(inPixels);
+	ANKI_ASSERT(inPixels.getSizeInBytes() == PtrSize(inWidth) * inHeight * channelCount);
 	ANKI_ASSERT(inWidth > 0 && isPowerOfTwo(inWidth) && inHeight > 0 && isPowerOfTwo(inHeight));
 	ANKI_ASSERT(inWidth > 0 && isPowerOfTwo(inWidth) && inHeight > 0 && isPowerOfTwo(inHeight));
-	ANKI_ASSERT(outPixels);
-	ANKI_ASSERT(outPixelsBufferSize > 0);
+	ANKI_ASSERT(outPixels.getSizeInBytes() == PtrSize((channelCount == 3) ? 8 : 16) * (inWidth / 4) * (inHeight / 4));
 
 
 	class CleanupFile
 	class CleanupFile
 	{
 	{
@@ -322,7 +323,7 @@ static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc,
 	// Create a BMP image to feed to the compressor
 	// Create a BMP image to feed to the compressor
 	StringAuto bmpFilename(alloc);
 	StringAuto bmpFilename(alloc);
 	bmpFilename.sprintf("%s/%u_.bmp", tempDirectory.cstr(), U32(std::rand()));
 	bmpFilename.sprintf("%s/%u_.bmp", tempDirectory.cstr(), U32(std::rand()));
-	if(!stbi_write_bmp(bmpFilename.cstr(), inWidth, inHeight, componentCount, inPixels))
+	if(!stbi_write_bmp(bmpFilename.cstr(), inWidth, inHeight, channelCount, inPixels.getBegin()))
 	{
 	{
 		ANKI_IMPORTER_LOGE("STB failed to create: %s", bmpFilename.cstr());
 		ANKI_IMPORTER_LOGE("STB failed to create: %s", bmpFilename.cstr());
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
@@ -337,7 +338,7 @@ static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc,
 	U32 argCount = 0;
 	U32 argCount = 0;
 	args[argCount++] = "-nomipmap";
 	args[argCount++] = "-nomipmap";
 	args[argCount++] = "-fd";
 	args[argCount++] = "-fd";
-	args[argCount++] = (componentCount == 3) ? "BC1" : "BC3";
+	args[argCount++] = (channelCount == 3) ? "BC1" : "BC3";
 	args[argCount++] = bmpFilename;
 	args[argCount++] = bmpFilename;
 	args[argCount++] = ddsFilename;
 	args[argCount++] = ddsFilename;
 
 
@@ -359,13 +360,13 @@ static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc,
 	DdsHeader ddsHeader;
 	DdsHeader ddsHeader;
 	ANKI_CHECK(ddsFile.read(&ddsHeader, sizeof(DdsHeader)));
 	ANKI_CHECK(ddsFile.read(&ddsHeader, sizeof(DdsHeader)));
 
 
-	if(componentCount == 3 && memcmp(&ddsHeader.m_ddspf.m_dwFourCC[0], "DXT1", 4) != 0)
+	if(channelCount == 3 && memcmp(&ddsHeader.m_ddspf.m_dwFourCC[0], "DXT1", 4) != 0)
 	{
 	{
 		ANKI_IMPORTER_LOGE("Incorrect format. Expecting DXT1");
 		ANKI_IMPORTER_LOGE("Incorrect format. Expecting DXT1");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 
 
-	if(componentCount == 4 && memcmp(&ddsHeader.m_ddspf.m_dwFourCC[0], "DXT5", 4) != 0)
+	if(channelCount == 4 && memcmp(&ddsHeader.m_ddspf.m_dwFourCC[0], "DXT5", 4) != 0)
 	{
 	{
 		ANKI_IMPORTER_LOGE("Incorrect format. Expecting DXT5");
 		ANKI_IMPORTER_LOGE("Incorrect format. Expecting DXT5");
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
@@ -377,7 +378,62 @@ static ANKI_USE_RESULT Error compressS3tc(GenericMemoryPoolAllocator<U8> alloc,
 		return Error::FUNCTION_FAILED;
 		return Error::FUNCTION_FAILED;
 	}
 	}
 
 
-	ANKI_CHECK(ddsFile.read(outPixels, outPixelsBufferSize));
+	ANKI_CHECK(ddsFile.read(outPixels.getBegin(), outPixels.getSizeInBytes()));
+
+	return Error::NONE;
+}
+
+static ANKI_USE_RESULT Error storeAnkiImage(const ImageImporterConfig& config, const ImageImporterContext& ctx)
+{
+	File outFile;
+	ANKI_CHECK(outFile.open(config.m_outFilename, FileOpenFlag::BINARY | FileOpenFlag::WRITE));
+
+	// Header
+	ImageBinaryHeader header = {};
+	memcpy(&header.m_magic[0], &IMAGE_MAGIC[0], sizeof(header.m_magic));
+	header.m_width = ctx.m_width;
+	header.m_height = ctx.m_height;
+	header.m_depthOrLayerCount = max(ctx.m_layerCount, ctx.m_depth);
+	header.m_type = config.m_type;
+	header.m_colorFormat = (ctx.m_channelCount == 3) ? ImageBinaryColorFormat::RGB8 : ImageBinaryColorFormat::RGBA8;
+	header.m_compressionMask = config.m_compressions;
+	header.m_isNormal = false;
+	header.m_mipmapCount = ctx.m_mipmaps.getSize();
+	ANKI_CHECK(outFile.write(&header, sizeof(header)));
+
+	// Write RAW
+	if(!!(config.m_compressions & ImageBinaryDataCompression::RAW))
+	{
+		for(I32 mip = I32(ctx.m_mipmaps.getSize()) - 1; mip >= 0; --mip)
+		{
+			for(U32 l = 0; l < ctx.m_layerCount; ++l)
+			{
+				for(U32 f = 0; f < ctx.m_faceCount; ++f)
+				{
+					const U32 idx = l * ctx.m_faceCount + f;
+					const ConstWeakArray<U8, PtrSize> pixels = ctx.m_mipmaps[mip].m_surfacesOrVolume[idx].m_pixels;
+					ANKI_CHECK(outFile.write(&pixels[0], pixels.getSizeInBytes()));
+				}
+			}
+		}
+	}
+
+	// Write S3TC
+	if(!!(config.m_compressions & ImageBinaryDataCompression::S3TC))
+	{
+		for(I32 mip = I32(ctx.m_mipmaps.getSize()) - 1; mip >= 0; --mip)
+		{
+			for(U32 l = 0; l < ctx.m_layerCount; ++l)
+			{
+				for(U32 f = 0; f < ctx.m_faceCount; ++f)
+				{
+					const U32 idx = l * ctx.m_faceCount + f;
+					const ConstWeakArray<U8, PtrSize> pixels = ctx.m_mipmaps[mip].m_surfacesOrVolume[idx].m_s3tcPixels;
+					ANKI_CHECK(outFile.write(&pixels[0], pixels.getSizeInBytes()));
+				}
+			}
+		}
+	}
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
@@ -443,16 +499,16 @@ static ANKI_USE_RESULT Error importImageInternal(const ImageImporterConfig& conf
 
 
 					if(ctx.m_channelCount == 3)
 					if(ctx.m_channelCount == 3)
 					{
 					{
-						generateSurfaceMipmap<3>(inSurface.m_pixels.getBegin(), inSurface.m_pixels.getSizeInBytes(),
+						generateSurfaceMipmap<3>(ConstWeakArray<U8, PtrSize>(inSurface.m_pixels),
 												 ctx.m_width >> (mip - 1), ctx.m_height >> (mip - 1),
 												 ctx.m_width >> (mip - 1), ctx.m_height >> (mip - 1),
-												 outSurface.m_pixels.getSizeInBytes(), outSurface.m_pixels.getBegin());
+												 WeakArray<U8, PtrSize>(outSurface.m_pixels));
 					}
 					}
 					else
 					else
 					{
 					{
 						ANKI_ASSERT(ctx.m_channelCount == 4);
 						ANKI_ASSERT(ctx.m_channelCount == 4);
-						generateSurfaceMipmap<4>(inSurface.m_pixels.getBegin(), inSurface.m_pixels.getSizeInBytes(),
+						generateSurfaceMipmap<4>(ConstWeakArray<U8, PtrSize>(inSurface.m_pixels),
 												 ctx.m_width >> (mip - 1), ctx.m_height >> (mip - 1),
 												 ctx.m_width >> (mip - 1), ctx.m_height >> (mip - 1),
-												 outSurface.m_pixels.getSizeInBytes(), outSurface.m_pixels.getBegin());
+												 WeakArray<U8, PtrSize>(outSurface.m_pixels));
 					}
 					}
 				}
 				}
 			}
 			}
@@ -474,13 +530,30 @@ static ANKI_USE_RESULT Error importImageInternal(const ImageImporterConfig& conf
 				{
 				{
 					const U32 idx = l * ctx.m_faceCount + f;
 					const U32 idx = l * ctx.m_faceCount + f;
 					SurfaceOrVolumeData& surface = ctx.m_mipmaps[mip].m_surfacesOrVolume[idx];
 					SurfaceOrVolumeData& surface = ctx.m_mipmaps[mip].m_surfacesOrVolume[idx];
-					// ANKI_CHECK(compressS3tc(config, ctx, surface.m_pixels.getBegin(), ctx.m_width >> mip,
-					//						ctx.m_height >> mip));
+
+					const U32 width = ctx.m_width >> mip;
+					const U32 height = ctx.m_height >> mip;
+					const PtrSize blockSize = (ctx.m_channelCount == 3) ? 8 : 16;
+					const PtrSize s3tcImageSize = blockSize * (width / 4) * (height / 4);
+
+					surface.m_s3tcPixels.create(s3tcImageSize);
+
+					ANKI_CHECK(compressS3tc(alloc, config.m_tempDirectory,
+											ConstWeakArray<U8, PtrSize>(surface.m_pixels), width, height,
+											ctx.m_channelCount, WeakArray<U8, PtrSize>(surface.m_s3tcPixels)));
 				}
 				}
 			}
 			}
 		}
 		}
 	}
 	}
 
 
+	if(!!(config.m_compressions & ImageBinaryDataCompression::ETC))
+	{
+		ANKI_ASSERT(!"TODO");
+	}
+
+	// Store the image
+	ANKI_CHECK(storeAnkiImage(config, ctx));
+
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 

+ 2 - 2
AnKi/Resource/ImageBinary.h

@@ -59,7 +59,7 @@ public:
 	U32 m_depthOrLayerCount;
 	U32 m_depthOrLayerCount;
 	ImageBinaryType m_type;
 	ImageBinaryType m_type;
 	ImageBinaryColorFormat m_colorFormat;
 	ImageBinaryColorFormat m_colorFormat;
-	ImageBinaryDataCompression m_compressionFormats;
+	ImageBinaryDataCompression m_compressionMask;
 	U32 m_isNormal;
 	U32 m_isNormal;
 	U32 m_mipmapCount;
 	U32 m_mipmapCount;
 	Array<U8, 88> m_padding;
 	Array<U8, 88> m_padding;
@@ -73,7 +73,7 @@ public:
 		s.doValue("m_depthOrLayerCount", offsetof(ImageBinaryHeader, m_depthOrLayerCount), self.m_depthOrLayerCount);
 		s.doValue("m_depthOrLayerCount", offsetof(ImageBinaryHeader, m_depthOrLayerCount), self.m_depthOrLayerCount);
 		s.doValue("m_type", offsetof(ImageBinaryHeader, m_type), self.m_type);
 		s.doValue("m_type", offsetof(ImageBinaryHeader, m_type), self.m_type);
 		s.doValue("m_colorFormat", offsetof(ImageBinaryHeader, m_colorFormat), self.m_colorFormat);
 		s.doValue("m_colorFormat", offsetof(ImageBinaryHeader, m_colorFormat), self.m_colorFormat);
-		s.doValue("m_compressionFormats", offsetof(ImageBinaryHeader, m_compressionFormats), self.m_compressionFormats);
+		s.doValue("m_compressionMask", offsetof(ImageBinaryHeader, m_compressionMask), self.m_compressionMask);
 		s.doValue("m_isNormal", offsetof(ImageBinaryHeader, m_isNormal), self.m_isNormal);
 		s.doValue("m_isNormal", offsetof(ImageBinaryHeader, m_isNormal), self.m_isNormal);
 		s.doValue("m_mipmapCount", offsetof(ImageBinaryHeader, m_mipmapCount), self.m_mipmapCount);
 		s.doValue("m_mipmapCount", offsetof(ImageBinaryHeader, m_mipmapCount), self.m_mipmapCount);
 		s.doArray("m_padding", offsetof(ImageBinaryHeader, m_padding), &self.m_padding[0], self.m_padding.getSize());
 		s.doArray("m_padding", offsetof(ImageBinaryHeader, m_padding), &self.m_padding[0], self.m_padding.getSize());

+ 1 - 1
AnKi/Resource/ImageBinary.xml

@@ -50,7 +50,7 @@ ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ImageBinaryDataCompression)
 				<member name="m_depthOrLayerCount" type="U32"/>
 				<member name="m_depthOrLayerCount" type="U32"/>
 				<member name="m_type" type="ImageBinaryType"/>
 				<member name="m_type" type="ImageBinaryType"/>
 				<member name="m_colorFormat" type="ImageBinaryColorFormat"/>
 				<member name="m_colorFormat" type="ImageBinaryColorFormat"/>
-				<member name="m_compressionFormats" type="ImageBinaryDataCompression"/>
+				<member name="m_compressionMask" type="ImageBinaryDataCompression"/>
 				<member name="m_isNormal" type="U32"/>
 				<member name="m_isNormal" type="U32"/>
 				<member name="m_mipmapCount" type="U32"/>
 				<member name="m_mipmapCount" type="U32"/>
 				<member name="m_padding" type="U8" array_size="88"/>
 				<member name="m_padding" type="U8" array_size="88"/>

+ 5 - 5
AnKi/Resource/ImageLoader.cpp

@@ -375,12 +375,12 @@ Error ImageLoader::loadAnkiTexture(FileInterface& file, U32 maxTextureSize,
 		return Error::USER_DATA;
 		return Error::USER_DATA;
 	}
 	}
 
 
-	if((header.m_compressionFormats & preferredCompression) == ImageBinaryDataCompression::NONE)
+	if((header.m_compressionMask & preferredCompression) == ImageBinaryDataCompression::NONE)
 	{
 	{
 		// Fallback
 		// Fallback
 		preferredCompression = ImageBinaryDataCompression::RAW;
 		preferredCompression = ImageBinaryDataCompression::RAW;
 
 
-		if((header.m_compressionFormats & preferredCompression) == ImageBinaryDataCompression::NONE)
+		if((header.m_compressionMask & preferredCompression) == ImageBinaryDataCompression::NONE)
 		{
 		{
 			ANKI_RESOURCE_LOGE("File does not contain raw compression");
 			ANKI_RESOURCE_LOGE("File does not contain raw compression");
 			return Error::USER_DATA;
 			return Error::USER_DATA;
@@ -431,7 +431,7 @@ Error ImageLoader::loadAnkiTexture(FileInterface& file, U32 maxTextureSize,
 	}
 	}
 	else if(preferredCompression == ImageBinaryDataCompression::S3TC)
 	else if(preferredCompression == ImageBinaryDataCompression::S3TC)
 	{
 	{
-		if((header.m_compressionFormats & ImageBinaryDataCompression::RAW) != ImageBinaryDataCompression::NONE)
+		if((header.m_compressionMask & ImageBinaryDataCompression::RAW) != ImageBinaryDataCompression::NONE)
 		{
 		{
 			// If raw compression is present then skip it
 			// If raw compression is present then skip it
 			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageBinaryDataCompression::RAW), FileSeekOrigin::CURRENT));
 			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageBinaryDataCompression::RAW), FileSeekOrigin::CURRENT));
@@ -439,13 +439,13 @@ Error ImageLoader::loadAnkiTexture(FileInterface& file, U32 maxTextureSize,
 	}
 	}
 	else if(preferredCompression == ImageBinaryDataCompression::ETC)
 	else if(preferredCompression == ImageBinaryDataCompression::ETC)
 	{
 	{
-		if((header.m_compressionFormats & ImageBinaryDataCompression::RAW) != ImageBinaryDataCompression::NONE)
+		if((header.m_compressionMask & ImageBinaryDataCompression::RAW) != ImageBinaryDataCompression::NONE)
 		{
 		{
 			// If raw compression is present then skip it
 			// If raw compression is present then skip it
 			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageBinaryDataCompression::RAW), FileSeekOrigin::CURRENT));
 			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageBinaryDataCompression::RAW), FileSeekOrigin::CURRENT));
 		}
 		}
 
 
-		if((header.m_compressionFormats & ImageBinaryDataCompression::S3TC) != ImageBinaryDataCompression::NONE)
+		if((header.m_compressionMask & ImageBinaryDataCompression::S3TC) != ImageBinaryDataCompression::NONE)
 		{
 		{
 			// If s3tc compression is present then skip it
 			// If s3tc compression is present then skip it
 			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageBinaryDataCompression::S3TC), FileSeekOrigin::CURRENT));
 			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageBinaryDataCompression::S3TC), FileSeekOrigin::CURRENT));

+ 8 - 8
AnKi/Util/WeakArray.h

@@ -47,7 +47,7 @@ public:
 	{
 	{
 	}
 	}
 
 
-	explicit WeakArray(DynamicArray<T>& arr)
+	explicit WeakArray(DynamicArray<T, TSize>& arr)
 		: WeakArray()
 		: WeakArray()
 	{
 	{
 		if(arr.getSize())
 		if(arr.getSize())
@@ -57,7 +57,7 @@ public:
 		}
 		}
 	}
 	}
 
 
-	explicit WeakArray(DynamicArrayAuto<T>& arr)
+	explicit WeakArray(DynamicArrayAuto<T, TSize>& arr)
 		: WeakArray()
 		: WeakArray()
 	{
 	{
 		if(arr.getSize())
 		if(arr.getSize())
@@ -106,14 +106,14 @@ public:
 		return *this;
 		return *this;
 	}
 	}
 
 
-	WeakArray& operator=(DynamicArray<T>& arr)
+	WeakArray& operator=(DynamicArray<T, TSize>& arr)
 	{
 	{
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_size = arr.getSize();
 		m_size = arr.getSize();
 		return *this;
 		return *this;
 	}
 	}
 
 
-	WeakArray& operator=(DynamicArrayAuto<T>& arr)
+	WeakArray& operator=(DynamicArrayAuto<T, TSize>& arr)
 	{
 	{
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_size = arr.getSize();
 		m_size = arr.getSize();
@@ -271,7 +271,7 @@ public:
 	}
 	}
 
 
 	/// Construct from DynamicArray.
 	/// Construct from DynamicArray.
-	ConstWeakArray(const DynamicArray<T>& arr)
+	ConstWeakArray(const DynamicArray<T, TSize>& arr)
 		: ConstWeakArray()
 		: ConstWeakArray()
 	{
 	{
 		if(arr.getSize())
 		if(arr.getSize())
@@ -282,7 +282,7 @@ public:
 	}
 	}
 
 
 	/// Construct from DynamicArrayAuto.
 	/// Construct from DynamicArrayAuto.
-	ConstWeakArray(const DynamicArrayAuto<T>& arr)
+	ConstWeakArray(const DynamicArrayAuto<T, TSize>& arr)
 		: ConstWeakArray()
 		: ConstWeakArray()
 	{
 	{
 		if(arr.getSize())
 		if(arr.getSize())
@@ -340,14 +340,14 @@ public:
 		return *this;
 		return *this;
 	}
 	}
 
 
-	ConstWeakArray& operator=(const DynamicArray<T>& arr)
+	ConstWeakArray& operator=(const DynamicArray<T, TSize>& arr)
 	{
 	{
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_size = arr.getSize();
 		m_size = arr.getSize();
 		return *this;
 		return *this;
 	}
 	}
 
 
-	ConstWeakArray& operator=(const DynamicArrayAuto<T>& arr)
+	ConstWeakArray& operator=(const DynamicArrayAuto<T, TSize>& arr)
 	{
 	{
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_data = (arr.getSize()) ? &arr[0] : nullptr;
 		m_size = arr.getSize();
 		m_size = arr.getSize();

+ 4 - 0
Tools/Texture/CMakeLists.txt

@@ -1,3 +1,7 @@
 add_executable(TextureViewer TextureViewerMain.cpp)
 add_executable(TextureViewer TextureViewerMain.cpp)
 target_link_libraries(TextureViewer AnKi)
 target_link_libraries(TextureViewer AnKi)
 installExecutable(TextureViewer)
 installExecutable(TextureViewer)
+
+add_executable(TextureImporter TextureImporterMain.cpp)
+target_link_libraries(TextureImporter AnKi)
+installExecutable(TextureImporter)

+ 13 - 0
Tools/Texture/TextureImporterMain.cpp

@@ -0,0 +1,13 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Importer/ImageImporter.h>
+
+using namespace anki;
+
+int main(int argc, char** argv)
+{
+	return 0;
+}