diff --git a/Source/Engine/Platform/StringUtils.h b/Source/Engine/Platform/StringUtils.h index 7b2b0572a..af9267e16 100644 --- a/Source/Engine/Platform/StringUtils.h +++ b/Source/Engine/Platform/StringUtils.h @@ -196,12 +196,12 @@ public: static int32 HexDigit(Char c); // Parses text to unsigned integer value. Returns true if failed to convert the value. - template - static bool ParseHex(const CharType* str, int32 length, uint32* result) + template + static bool ParseHex(const T* str, int32 length, uint32* result) { uint32 sum = 0; - const CharType* p = str; - const CharType* end = str + length; + const T* p = str; + const T* end = str + length; if (*p == '0' && *(p + 1) == 'x') p += 2; while (*p && p < end) @@ -221,10 +221,10 @@ public: } // Parses text to unsigned integer value. Returns true if failed to convert the value. - template - static bool ParseHex(const CharType* str, uint32* result) + template + static bool ParseHex(const T* str, uint32* result) { - return StringUtils::ParseHex(str, StringUtils::Length(str), result); + return StringUtils::ParseHex(str, StringUtils::Length((const T*)str), result); } // Parses text to the unsigned integer value. Returns true if failed to convert the value. @@ -321,7 +321,7 @@ public: template static bool Parse(const T* str, U* result) { - return StringUtils::Parse(str, StringUtils::Length(str), result); + return StringUtils::Parse((const T*)str, StringUtils::Length((const T*)str), (U*)result); } // Parses text to the scalar value. Returns true if failed to convert the value. diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index e62d32842..dc2b20778 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -661,7 +661,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path if (sourceWidth != width || sourceHeight != height) { // During resizing we need to keep texture aspect ratio - const bool keepAspectRatio = false; // TODO: expose as import option + const bool keepAspectRatio = options.KeepAspectRatio; if (keepAspectRatio) { const float aspectRatio = static_cast(sourceWidth) / sourceHeight; @@ -727,8 +727,10 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path } bool keepAsIs = false; - if (!options.FlipY && - !options.InvertGreenChannel && + if (!options.FlipY && + !options.FlipX && + !options.InvertGreenChannel && + !options.ReconstructZChannel && options.Compress && type == ImageType::DDS && mipLevels == sourceMipLevels && @@ -787,7 +789,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path SET_CURRENT_IMG(tmpImg); } - // Check flip/rotate source image + // Check flip/rotate Y source image if (!keepAsIs && options.FlipY) { auto& tmpImg = GET_TMP_IMG(); @@ -801,6 +803,20 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path SET_CURRENT_IMG(tmpImg); } + // Check flip/rotate X source image + if (!keepAsIs && options.FlipX) + { + auto& tmpImg = GET_TMP_IMG(); + DirectX::TEX_FR_FLAGS flags = DirectX::TEX_FR_FLIP_HORIZONTAL; + result = FlipRotate(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), flags, tmpImg); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot rotate/flip texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(tmpImg); + } + // Check if invert green channel if (!keepAsIs && options.InvertGreenChannel) { @@ -833,7 +849,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path if (!keepAsIs & options.ReconstructZChannel) { auto& timage = GET_TMP_IMG(); - bool isunorm = (DirectX::FormatDataType(currentImage->GetMetadata().format) == DirectX::FORMAT_TYPE_UNORM) != 0; + bool isunorm = (DirectX::FormatDataType(sourceDxgiFormat) == DirectX::FORMAT_TYPE_UNORM) != 0; result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { @@ -855,7 +871,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path { z = DirectX::XMVectorSqrt(DirectX::XMVectorSubtract(DirectX::g_XMOne, DirectX::XMVector2Dot(value, value))); } - outPixels[j] = XMVectorSelect(value, z, s_selectz); + outPixels[j] = DirectX::XMVectorSelect(value, z, s_selectz); } }, timage); if (FAILED(result)) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.cpp b/Source/Engine/Tools/TextureTool/TextureTool.cpp index 48df4cb31..550e26699 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.cpp @@ -73,6 +73,9 @@ void TextureTool::Options::Serialize(SerializeStream& stream, const void* otherO stream.JKEY("FlipY"); stream.Bool(FlipY); + stream.JKEY("FlipX"); + stream.Bool(FlipX); + stream.JKEY("InvertGreenChannel"); stream.Bool(InvertGreenChannel); @@ -82,6 +85,9 @@ void TextureTool::Options::Serialize(SerializeStream& stream, const void* otherO stream.JKEY("Resize"); stream.Bool(Resize); + stream.JKEY("KeepAspectRatio"); + stream.Bool(KeepAspectRatio); + stream.JKEY("PreserveAlphaCoverage"); stream.Bool(PreserveAlphaCoverage); @@ -136,9 +142,11 @@ void TextureTool::Options::Deserialize(DeserializeStream& stream, ISerializeModi sRGB = JsonTools::GetBool(stream, "sRGB", sRGB); GenerateMipMaps = JsonTools::GetBool(stream, "GenerateMipMaps", GenerateMipMaps); FlipY = JsonTools::GetBool(stream, "FlipY", FlipY); + FlipX = JsonTools::GetBool(stream, "FlipX", FlipX); InvertGreenChannel = JsonTools::GetBool(stream, "InvertGreenChannel", InvertGreenChannel); ReconstructZChannel = JsonTools::GetBool(stream, "ReconstructZChannel", ReconstructZChannel); Resize = JsonTools::GetBool(stream, "Resize", Resize); + KeepAspectRatio = JsonTools::GetBool(stream, "KeepAspectRatio", KeepAspectRatio); PreserveAlphaCoverage = JsonTools::GetBool(stream, "PreserveAlphaCoverage", PreserveAlphaCoverage); PreserveAlphaCoverageReference = JsonTools::GetFloat(stream, "PreserveAlphaCoverageReference", PreserveAlphaCoverageReference); TextureGroup = JsonTools::GetInt(stream, "TextureGroup", TextureGroup); diff --git a/Source/Engine/Tools/TextureTool/TextureTool.h b/Source/Engine/Tools/TextureTool/TextureTool.h index 3acf41eb9..13bac0dc5 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.h +++ b/Source/Engine/Tools/TextureTool/TextureTool.h @@ -53,16 +53,20 @@ API_CLASS(Namespace="FlaxEngine.Tools", Static) class FLAXENGINE_API TextureTool API_FIELD(Attributes="EditorOrder(60)") bool GenerateMipMaps = true; - // True if flip Y coordinate of the texture. + // True if flip Y coordinate of the texture (Flips over X axis). API_FIELD(Attributes="EditorOrder(70)") bool FlipY = false; + // True if flip X coordinate of the texture (Flips over Y axis). + API_FIELD(Attributes="EditorOrder(71)") + bool FlipX = false; + // True if to invert the green channel on a normal map. Good for OpenGL to DirectX conversion. - API_FIELD(Attributes = "EditorOrder(71)") + API_FIELD(Attributes = "EditorOrder(72)") bool InvertGreenChannel = false; // Rebuild Z (blue) channel assuming X/Y are normals. - API_FIELD(Attributes = "EditorOrder(72)") + API_FIELD(Attributes = "EditorOrder(73)") bool ReconstructZChannel = false; // Texture size scale. Allows increasing or decreasing the imported texture resolution. Default is 1. @@ -77,6 +81,10 @@ API_CLASS(Namespace="FlaxEngine.Tools", Static) class FLAXENGINE_API TextureTool API_FIELD(Attributes="EditorOrder(100)") bool Resize = false; + // Keeps the aspect ratio when resizing. + API_FIELD(Attributes="EditorOrder(101), VisibleIf(nameof(Resize))") + bool KeepAspectRatio = false; + // The width of the imported texture. If Resize property is set to true then texture will be resized during the import to this value during the import, otherwise it will be ignored. API_FIELD(Attributes="HideInEditor") int32 SizeX = 1024; diff --git a/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp b/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp index 1301327ef..15058752d 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp @@ -458,7 +458,7 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu { if (!options.InternalLoad.IsBinded() || options.InternalLoad(textureData)) return true; - if (options.FlipY) + if (options.FlipY || options.FlipX) { // TODO: impl this errorMsg = TEXT("Flipping images imported from Internal source is not supported by stb."); @@ -489,7 +489,7 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu if (sourceWidth != width || sourceHeight != height) { // During resizing we need to keep texture aspect ratio - const bool keepAspectRatio = false; // TODO: expose as import option + const bool keepAspectRatio = options.KeepAspectRatio; // TODO: expose as import option if (keepAspectRatio) { const float aspectRatio = static_cast(sourceWidth) / sourceHeight; @@ -536,6 +536,22 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu return true; } + if (options.FlipX) + { + // TODO: impl this + LOG(Warning "Option 'Flip X' is not supported"); + } + if (options.InvertGreenChannel) + { + // TODO: impl this + LOG(Warning "Option 'Invert Green Channel' is not supported"); + } + if (options.ReconstructZChannel) + { + // TODO: impl this + LOG(Warning "Option 'Reconstruct Z Channel' is not supported"); + } + // Generate mip maps chain if (useMipLevels && options.GenerateMipMaps) {