From 10289f542319dfe689a51b581305d247eb2c77f9 Mon Sep 17 00:00:00 2001
From: Atlante45 <clement.brisset@gmail.com>
Date: Tue, 2 May 2017 19:39:07 -0700
Subject: [PATCH] Format non compressed normal maps to new format.

---
 libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp |  3 ++
 libraries/gpu/src/gpu/Format.cpp              |  2 ++
 libraries/gpu/src/gpu/Format.h                |  1 +
 libraries/gpu/src/gpu/Texture_ktx.cpp         |  2 ++
 libraries/image/src/image/Image.cpp           | 36 ++++++++++---------
 5 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp
index 7f724cce65..12bfb8e70b 100644
--- a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp
+++ b/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp
@@ -140,6 +140,7 @@ GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) {
             switch (dstFormat.getSemantic()) {
                 case gpu::RGB:
                 case gpu::RGBA:
+                case gpu::XY:
                     result = GL_RG8;
                     break;
                 default:
@@ -289,6 +290,7 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E
             switch (dstFormat.getSemantic()) {
             case gpu::RGB:
             case gpu::RGBA:
+            case gpu::XY:
                 texel.internalFormat = GL_RG8;
                 break;
             default:
@@ -516,6 +518,7 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E
             switch (dstFormat.getSemantic()) {
             case gpu::RGB:
             case gpu::RGBA:
+            case gpu::XY:
                 texel.internalFormat = GL_RG8;
                 break;
             default:
diff --git a/libraries/gpu/src/gpu/Format.cpp b/libraries/gpu/src/gpu/Format.cpp
index 19d8855bd9..a9c7d249a8 100644
--- a/libraries/gpu/src/gpu/Format.cpp
+++ b/libraries/gpu/src/gpu/Format.cpp
@@ -25,6 +25,8 @@ const Element Element::COLOR_COMPRESSED_SRGBA_MASK{ VEC4, NUINT8, COMPRESSED_BC1
 const Element Element::COLOR_COMPRESSED_SRGBA{ VEC4, NUINT8, COMPRESSED_BC3_SRGBA };
 const Element Element::COLOR_COMPRESSED_XY{ VEC4, NUINT8, COMPRESSED_BC5_XY };
 
+const Element Element::VEC2_XY{ VEC2, NUINT8, XY };
+
 const Element Element::COLOR_R11G11B10{ SCALAR, FLOAT, R11G11B10 };
 const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA };
 const Element Element::VEC2F_UV{ VEC2, FLOAT, UV };
diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h
index f69e8d9386..9fadcecb22 100644
--- a/libraries/gpu/src/gpu/Format.h
+++ b/libraries/gpu/src/gpu/Format.h
@@ -234,6 +234,7 @@ public:
     static const Element COLOR_COMPRESSED_SRGBA_MASK;
     static const Element COLOR_COMPRESSED_SRGBA;
     static const Element COLOR_COMPRESSED_XY;
+    static const Element VEC2_XY;
     static const Element VEC4F_COLOR_RGBA;
     static const Element VEC2F_UV;
     static const Element VEC2F_XY;
diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp
index d2f93c0036..4952e7a83b 100644
--- a/libraries/gpu/src/gpu/Texture_ktx.cpp
+++ b/libraries/gpu/src/gpu/Texture_ktx.cpp
@@ -423,6 +423,8 @@ bool Texture::evalKTXFormat(const Element& mipFormat, const Element& texelFormat
         header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RGBA, ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8, ktx::GLBaseInternalFormat::RGBA);
     } else if (texelFormat == Format::COLOR_R_8 && mipFormat == Format::COLOR_R_8) {
         header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RED, ktx::GLInternalFormat_Uncompressed::R8, ktx::GLBaseInternalFormat::RED);
+    } else if (texelFormat == Format::VEC2_XY && mipFormat == Format::VEC2_XY) {
+        header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RG, ktx::GLInternalFormat_Uncompressed::RG8, ktx::GLBaseInternalFormat::RG);
     } else if (texelFormat == Format::COLOR_COMPRESSED_SRGB && mipFormat == Format::COLOR_COMPRESSED_SRGB) {
         header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_SRGB_S3TC_DXT1_EXT, ktx::GLBaseInternalFormat::RGB);
     } else if (texelFormat == Format::COLOR_COMPRESSED_SRGBA_MASK && mipFormat == Format::COLOR_COMPRESSED_SRGBA_MASK) {
diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp
index 707a2e4496..63c7d0d8ab 100644
--- a/libraries/image/src/image/Image.cpp
+++ b/libraries/image/src/image/Image.cpp
@@ -290,6 +290,19 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) {
     float inputGamma = 2.2f;
     float outputGamma = 2.2f;
 
+    nvtt::InputOptions inputOptions;
+    inputOptions.setTextureLayout(textureType, width, height);
+    inputOptions.setMipmapData(data, width, height);
+
+    inputOptions.setFormat(inputFormat);
+    inputOptions.setGamma(inputGamma, outputGamma);
+    inputOptions.setAlphaMode(alphaMode);
+    inputOptions.setWrapMode(wrapMode);
+    inputOptions.setRoundMode(roundMode);
+
+    inputOptions.setMipmapGeneration(true);
+    inputOptions.setMipmapFilter(nvtt::MipmapFilter_Box);
+
     nvtt::CompressionOptions compressionOptions;
     compressionOptions.setQuality(nvtt::Quality_Production);
 
@@ -346,26 +359,17 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) {
         compressionOptions.setFormat(nvtt::Format_RGB);
         compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm);
         compressionOptions.setPixelFormat(8, 0, 0, 0);
+    } else if (mipFormat == gpu::Element::VEC2_XY) {
+        inputOptions.setNormalMap(true);
+        compressionOptions.setFormat(nvtt::Format_RGBA);
+        compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm);
+        compressionOptions.setPixelFormat(8, 8, 0, 0);
     } else {
         qCWarning(imagelogging) << "Unknown mip format";
         Q_UNREACHABLE();
         return;
     }
 
-
-    nvtt::InputOptions inputOptions;
-    inputOptions.setTextureLayout(textureType, width, height);
-    inputOptions.setMipmapData(data, width, height);
-
-    inputOptions.setFormat(inputFormat);
-    inputOptions.setGamma(inputGamma, outputGamma);
-    inputOptions.setAlphaMode(alphaMode);
-    inputOptions.setWrapMode(wrapMode);
-    inputOptions.setRoundMode(roundMode);
-
-    inputOptions.setMipmapGeneration(true);
-    inputOptions.setMipmapFilter(nvtt::MipmapFilter_Box);
-
     nvtt::OutputOptions outputOptions;
     outputOptions.setOutputHeader(false);
     MyOutputHandler outputHandler(texture, face);
@@ -548,8 +552,8 @@ gpu::TexturePointer TextureUsage::process2DTextureNormalMapFromImage(const QImag
         gpu::Element formatMip = gpu::Element::COLOR_COMPRESSED_XY;
         gpu::Element formatGPU = gpu::Element::COLOR_COMPRESSED_XY;
 #else
-        gpu::Element formatMip = gpu::Element::COLOR_RGBA_32;
-        gpu::Element formatGPU = gpu::Element::COLOR_RGBA_32;
+        gpu::Element formatMip = gpu::Element::VEC2_XY;
+        gpu::Element formatGPU = gpu::Element::VEC2_XY;
 #endif
 
         theTexture = gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR));