From 4ac0c29d9bf09579fe7e53ea99d7bede2700ec1a Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 24 Oct 2016 09:40:34 -0700 Subject: [PATCH 01/22] Adding Image utility to GPU --- libraries/gpu/src/gpu/Image.cpp | 17 ++++++ libraries/gpu/src/gpu/Image.h | 73 ++++++++++++++++++++++++ libraries/model/src/model/TextureMap.cpp | 7 ++- 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 libraries/gpu/src/gpu/Image.cpp create mode 100644 libraries/gpu/src/gpu/Image.h diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp new file mode 100644 index 0000000000..6649fc7876 --- /dev/null +++ b/libraries/gpu/src/gpu/Image.cpp @@ -0,0 +1,17 @@ +#include "TextureUtils.h" + + +int image::Pixel::cpp { 0 }; + +namespace image { +template <> void compress(const PB_RGB32& src, CB_8& dst) { + + for (auto& b : dst.bytes) { + b = 12; + } +} + +template <> void compress(const PB_RGBA32& src, CB_8& dst) { + +} +} \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h new file mode 100644 index 0000000000..a36990b215 --- /dev/null +++ b/libraries/gpu/src/gpu/Image.h @@ -0,0 +1,73 @@ +/* + Let s try compressing images + +*/ +#include "Forward.h" + + +namespace image { + + class Pixel { + public: + using Byte = uint8_t; + static const Byte BLACK { 0 }; + static const Byte WHITE { 255 }; + + struct RGB32 { + Byte r { BLACK }; + Byte g { BLACK }; + Byte b { BLACK }; + Byte x { WHITE }; + }; + + struct RGBA32 { + Byte r { BLACK }; + Byte g { BLACK }; + Byte b { BLACK }; + Byte a { WHITE }; + }; + + + static int cpp; + }; + + template class PixelBlock { + public: + static const uint32_t WIDTH { 4 }; + static const uint32_t HEIGHT { WIDTH }; + static const uint32_t SIZE { WIDTH * HEIGHT }; + constexpr uint32_t getByteSize() const { return SIZE * sizeof(P); } + + P pixels[SIZE]; + + PixelBlock() {} + + + PixelBlock(const P* srcPixels) { + setPixels(srcPixels); + } + + void setPixels(const P* srcPixels) { + memcpy(pixels, srcPixels, getByteSize()); + } + + }; + + template class CompressedBlock { + public: + uint8_t bytes[Size]; + }; + + template void compress(const PB& srcPixelBlock, CB& dstBlock) { } + + using PB_RGB32 = PixelBlock; + using PB_RGBA32 = PixelBlock; + + using CB_8 = CompressedBlock<8>; + using CB_16 = CompressedBlock<16>; + + template <> void compress(const PB_RGB32& src, CB_8& dst); + template <> void compress(const PB_RGBA32& src, CB_8& dst); + + +} \ No newline at end of file diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 30f176b5a6..a6ae3f675b 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -15,7 +15,7 @@ #include #include "ModelLogging.h" - +#include using namespace model; using namespace gpu; @@ -201,6 +201,11 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + image::PB_RGB32 pb; + image::CB_8 cb; + + image::compress(pb, cb); + if (generateMips) { ::generateMips(theTexture, image, formatMip); } From 07d1daaa9b3fc8b3a093fd5558d4040c40010549 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 24 Oct 2016 18:35:15 -0700 Subject: [PATCH 02/22] Designing IMage --- libraries/gpu/src/gpu/Image.cpp | 16 +++++++-- libraries/gpu/src/gpu/Image.h | 42 ++++++++++++++++++------ libraries/model/src/model/TextureMap.cpp | 2 +- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp index 6649fc7876..e8d1899f11 100644 --- a/libraries/gpu/src/gpu/Image.cpp +++ b/libraries/gpu/src/gpu/Image.cpp @@ -1,17 +1,29 @@ -#include "TextureUtils.h" +#include "Image.h" int image::Pixel::cpp { 0 }; namespace image { -template <> void compress(const PB_RGB32& src, CB_8& dst) { + + template <> void compress(const PB_RGB32& src, CB_8& dst) { for (auto& b : dst.bytes) { b = 12; } } +template <> void uncompress(const CB_8& src, PB_RGB32& dst) { + for (auto& b : dst.bytes) { + b = 12; + } +} + template <> void compress(const PB_RGBA32& src, CB_8& dst) { } + +template <> void uncompress(const CB_8& src, PB_RGBA32& dst) { + +} + } \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index a36990b215..37f5f2788a 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -10,9 +10,13 @@ namespace image { class Pixel { public: using Byte = uint8_t; - static const Byte BLACK { 0 }; - static const Byte WHITE { 255 }; - + using Byte2 = uint16_t; + using Byte4 = uint32_t; + + static const Byte BLACK8 { 0 }; + static const Byte WHITE8 { 255 }; + + struct RGB32 { Byte r { BLACK }; Byte g { BLACK }; @@ -26,8 +30,14 @@ namespace image { Byte b { BLACK }; Byte a { WHITE }; }; - - + + + struct RGB16_565 { + Byte2 b : 5; + Byte2 g : 6; + Byte2 r : 5; + }; + static int cpp; }; @@ -36,7 +46,7 @@ namespace image { static const uint32_t WIDTH { 4 }; static const uint32_t HEIGHT { WIDTH }; static const uint32_t SIZE { WIDTH * HEIGHT }; - constexpr uint32_t getByteSize() const { return SIZE * sizeof(P); } + uint32_t getByteSize() const { return SIZE * sizeof(P); } P pixels[SIZE]; @@ -50,7 +60,6 @@ namespace image { void setPixels(const P* srcPixels) { memcpy(pixels, srcPixels, getByteSize()); } - }; template class CompressedBlock { @@ -58,7 +67,19 @@ namespace image { uint8_t bytes[Size]; }; - template void compress(const PB& srcPixelBlock, CB& dstBlock) { } + class BC { + public: + struct BC1 { + Pixel::RGB16_565 color_0; + Pixel::RGB16_565 color_1; + Pixel::Byte4 table; + }; + }; + + + template void compress(const PB& srcBlock, CB& dstBlock) { } + template void uncompress(const CB& srcBlock, PB& dstBlock) { } + using PB_RGB32 = PixelBlock; using PB_RGBA32 = PixelBlock; @@ -68,6 +89,7 @@ namespace image { template <> void compress(const PB_RGB32& src, CB_8& dst); template <> void compress(const PB_RGBA32& src, CB_8& dst); - - + + template <> void uncompress(const CB_8& src, PB_RGB32& dst); + template <> void uncompress(const CB_8& src, PB_RGBA32& dst); } \ No newline at end of file diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index a6ae3f675b..e80a8b2502 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -15,7 +15,7 @@ #include #include "ModelLogging.h" -#include +#include using namespace model; using namespace gpu; From ce68be2a59c823eda49e993305368a5c3ad73db7 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 26 Oct 2016 23:09:41 -0700 Subject: [PATCH 03/22] a few step further --- libraries/gpu/src/gpu/Image.cpp | 31 +++++-- libraries/gpu/src/gpu/Image.h | 110 ++++++++++++++++------- libraries/model/src/model/TextureMap.cpp | 2 +- 3 files changed, 103 insertions(+), 40 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp index e8d1899f11..b3fcbe11eb 100644 --- a/libraries/gpu/src/gpu/Image.cpp +++ b/libraries/gpu/src/gpu/Image.cpp @@ -1,28 +1,45 @@ #include "Image.h" -int image::Pixel::cpp { 0 }; +int image::BC::cpp { 0 }; namespace image { - template <> void compress(const PB_RGB32& src, CB_8& dst) { + namespace pixel { + template <> const RGB16_565 mix(const RGB16_565 p0, const RGB16_565 p1, const Byte alpha) { + return RGB16_565( + mix5_4(p0.r, p1.r, alpha), + mix6_4(p0.g, p1.g, alpha), + mix5_4(p0.b, p1.b, alpha)); + } + } + +template <> void compress(const PB_RGB32& src, CB_BC1& dst) { for (auto& b : dst.bytes) { b = 12; } } -template <> void uncompress(const CB_8& src, PB_RGB32& dst) { - for (auto& b : dst.bytes) { - b = 12; +template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { + auto bc1 = src.bc; + auto c0 = bc1.color0; + auto c1 = bc1.color1; + + for (auto& p : dst.pixels) { + auto r = pixel::mix( + c0, + c1, + (pixel::Byte)bc1.table); + ///p.val = } } -template <> void compress(const PB_RGBA32& src, CB_8& dst) { +template <> void compress(const PB_RGBA32& src, CB_BC4& dst) { } -template <> void uncompress(const CB_8& src, PB_RGBA32& dst) { +template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst) { } diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index 37f5f2788a..ff106f65b6 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -7,8 +7,8 @@ namespace image { - class Pixel { - public: + namespace pixel { + using Byte = uint8_t; using Byte2 = uint16_t; using Byte4 = uint32_t; @@ -16,19 +16,22 @@ namespace image { static const Byte BLACK8 { 0 }; static const Byte WHITE8 { 255 }; - + template int bitVal() { return 1 << N; } + template int bitProduct() { return bitVal() * bitVal(); } + template T mix(const T x, const T y, const A a) { return T(((bitVal() - a) * x + a * y) / bitProduct()); } + struct RGB32 { - Byte r { BLACK }; - Byte g { BLACK }; - Byte b { BLACK }; - Byte x { WHITE }; + Byte r { BLACK8 }; + Byte g { BLACK8 }; + Byte b { BLACK8 }; + Byte x { WHITE8 }; }; struct RGBA32 { - Byte r { BLACK }; - Byte g { BLACK }; - Byte b { BLACK }; - Byte a { WHITE }; + Byte r { BLACK8 }; + Byte g { BLACK8 }; + Byte b { BLACK8 }; + Byte a { WHITE8 }; }; @@ -36,17 +39,48 @@ namespace image { Byte2 b : 5; Byte2 g : 6; Byte2 r : 5; + + RGB16_565() : b(BLACK8), g(BLACK8), r(BLACK8) {} + RGB16_565(Byte pR, Byte pG, Byte pB) : b(pB), g(pG), r(pR) {} }; + + + Byte mix5_4(const Byte x, const Byte y, const Byte a) { return mix<5, 4>(x, y, a); } + Byte mix6_4(const Byte x, const Byte y, const Byte a) { return mix<6, 4>(x, y, a); } + + + template const P mix(const P p0, const P p1, const S alpha) { return p0; } + + template <> const RGB16_565 mix(const RGB16_565 p0, const RGB16_565 p1, const Byte alpha); + - static int cpp; }; + template class Pixel { + public: + using Format = F; + using Storage = S; + + union { + Format val; + Storage raw; + }; + + Pixel() {}; + Pixel(Format v) : val(v) {} + Pixel(Storage s) : raw(s) {} + }; + + using PixRGB565 = Pixel; + using PixRGB32 = Pixel; + using PixRGBA32 = Pixel; + template class PixelBlock { public: static const uint32_t WIDTH { 4 }; static const uint32_t HEIGHT { WIDTH }; static const uint32_t SIZE { WIDTH * HEIGHT }; - uint32_t getByteSize() const { return SIZE * sizeof(P); } + uint32_t getSize() const { return SIZE * sizeof(P); } P pixels[SIZE]; @@ -58,38 +92,50 @@ namespace image { } void setPixels(const P* srcPixels) { - memcpy(pixels, srcPixels, getByteSize()); + memcpy(pixels, srcPixels, getSize()); } }; - template class CompressedBlock { - public: - uint8_t bytes[Size]; - }; - class BC { public: + static int cpp; + struct BC1 { - Pixel::RGB16_565 color_0; - Pixel::RGB16_565 color_1; - Pixel::Byte4 table; + PixRGB565 color0; + PixRGB565 color1; + pixel::Byte4 table; + }; + struct BC4 { + PixRGB565 color0; + PixRGB565 color1; + pixel::Byte4 table; }; }; - - + + template class CompressedBlock { + public: + static const uint32_t SIZE { sizeof(T) }; + union { + pixel::Byte bytes[SIZE]; + T bc; + }; + + CompressedBlock() {} + }; + template void compress(const PB& srcBlock, CB& dstBlock) { } template void uncompress(const CB& srcBlock, PB& dstBlock) { } - using PB_RGB32 = PixelBlock; - using PB_RGBA32 = PixelBlock; + using PB_RGB32 = PixelBlock; + using PB_RGBA32 = PixelBlock; - using CB_8 = CompressedBlock<8>; - using CB_16 = CompressedBlock<16>; + using CB_BC1 = CompressedBlock; + using CB_BC4 = CompressedBlock; - template <> void compress(const PB_RGB32& src, CB_8& dst); - template <> void compress(const PB_RGBA32& src, CB_8& dst); + template <> void compress(const PB_RGB32& src, CB_BC1& dst); + template <> void compress(const PB_RGBA32& src, CB_BC4& dst); - template <> void uncompress(const CB_8& src, PB_RGB32& dst); - template <> void uncompress(const CB_8& src, PB_RGBA32& dst); + template <> void uncompress(const CB_BC1& src, PB_RGB32& dst); + template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst); } \ No newline at end of file diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index e80a8b2502..b0efbf2f30 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -202,7 +202,7 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); image::PB_RGB32 pb; - image::CB_8 cb; + image::CB_BC1 cb; image::compress(pb, cb); From b38f69dc7882fd4b8e464bd22d04f58a20d1fdc2 Mon Sep 17 00:00:00 2001 From: samcake Date: Sat, 29 Oct 2016 22:43:42 -0700 Subject: [PATCH 04/22] stage 0 of fooling around with image compression.... --- libraries/gpu/src/gpu/Image.cpp | 9 +++-- libraries/gpu/src/gpu/Image.h | 49 ++++++++++++++---------- libraries/model/src/model/TextureMap.cpp | 22 +++++++++-- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp index b3fcbe11eb..eddc1d60d7 100644 --- a/libraries/gpu/src/gpu/Image.cpp +++ b/libraries/gpu/src/gpu/Image.cpp @@ -23,15 +23,16 @@ template <> void compress(const PB_RGB32& src, CB_BC1& dst) { template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { auto bc1 = src.bc; - auto c0 = bc1.color0; - auto c1 = bc1.color1; - for (auto& p : dst.pixels) { + auto c0 = bc1.color0.val; + auto c1 = bc1.color1.val; + + for (int i = 0; i < PB_RGB32::SIZE; ++i) { + //dst.pixels[i] = ; auto r = pixel::mix( c0, c1, (pixel::Byte)bc1.table); - ///p.val = } } diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index ff106f65b6..c9969b8e15 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -7,19 +7,25 @@ namespace image { + // Storage types + using Byte = uint8_t; + using Byte2 = uint16_t; + using Byte4 = uint32_t; + + static const Byte BLACK8 { 0 }; + static const Byte WHITE8 { 255 }; + + template int bitVal() { return 1 << N; } + template int bitProduct() { return bitVal() * bitVal(); } + template T mix(const T x, const T y, const A a) { return T(((bitVal() - a) * x + a * y) / bitProduct()); } + + Byte mix5_4(const Byte x, const Byte y, const Byte a) { return mix<5, 4>(x, y, a); } + Byte mix6_4(const Byte x, const Byte y, const Byte a) { return mix<6, 4>(x, y, a); } + + namespace pixel { - using Byte = uint8_t; - using Byte2 = uint16_t; - using Byte4 = uint32_t; - - static const Byte BLACK8 { 0 }; - static const Byte WHITE8 { 255 }; - - template int bitVal() { return 1 << N; } - template int bitProduct() { return bitVal() * bitVal(); } - template T mix(const T x, const T y, const A a) { return T(((bitVal() - a) * x + a * y) / bitProduct()); } - + struct RGB32 { Byte r { BLACK8 }; Byte g { BLACK8 }; @@ -43,16 +49,9 @@ namespace image { RGB16_565() : b(BLACK8), g(BLACK8), r(BLACK8) {} RGB16_565(Byte pR, Byte pG, Byte pB) : b(pB), g(pG), r(pR) {} }; - - - Byte mix5_4(const Byte x, const Byte y, const Byte a) { return mix<5, 4>(x, y, a); } - Byte mix6_4(const Byte x, const Byte y, const Byte a) { return mix<6, 4>(x, y, a); } - - + template const P mix(const P p0, const P p1, const S alpha) { return p0; } - template <> const RGB16_565 mix(const RGB16_565 p0, const RGB16_565 p1, const Byte alpha); - }; @@ -62,8 +61,8 @@ namespace image { using Storage = S; union { - Format val; Storage raw; + Format val{ Format() }; // Format last to be initialized by Format's default constructor }; Pixel() {}; @@ -75,11 +74,16 @@ namespace image { using PixRGB32 = Pixel; using PixRGBA32 = Pixel; + template class PixelBlock { public: + using Format = typename P::Format; + using Storage = typename P::Storage; + static const uint32_t WIDTH { 4 }; static const uint32_t HEIGHT { WIDTH }; static const uint32_t SIZE { WIDTH * HEIGHT }; + uint32_t getSize() const { return SIZE * sizeof(P); } P pixels[SIZE]; @@ -94,6 +98,8 @@ namespace image { void setPixels(const P* srcPixels) { memcpy(pixels, srcPixels, getSize()); } + + const Storage* getStorage() const { return static_cast (&pixels->raw); } }; class BC { @@ -104,6 +110,9 @@ namespace image { PixRGB565 color0; PixRGB565 color1; pixel::Byte4 table; + + + Byte }; struct BC4 { PixRGB565 color0; diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index bd1a4baf48..1cbff8bd21 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -248,10 +248,26 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - image::PB_RGB32 pb; - image::CB_BC1 cb; + image::PixRGB32 pix0; - image::compress(pb, cb); + image::PixRGBA32 pix1; + + image::PixRGB565 pix3; + + image::PB_RGB32 pb0; + image::CB_BC1 cb; + image::PB_RGB32 pb1; + + auto pix0_s = sizeof(pix0); + auto pix1_s = sizeof(pix1); + auto pix3_s = sizeof(pix3); + + auto pb0_s = sizeof(pb0); + auto cb_s = sizeof(cb); + + auto cb_bytes = pb0.getStorage(); + image::compress(pb0, cb); + image::uncompress(cb, pb1); if (generateMips) { ::generateMips(theTexture, image, formatMip); From 41109553ebb5c1f315a7f794a1190ba031fe65ed Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 4 Nov 2016 22:56:18 -0700 Subject: [PATCH 05/22] Saving state before merge up --- libraries/gpu/src/gpu/Image.cpp | 2 +- libraries/gpu/src/gpu/Image.h | 167 ++++++++++++++++------- libraries/model/src/model/TextureMap.cpp | 3 + 3 files changed, 118 insertions(+), 54 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp index eddc1d60d7..5de1008d8f 100644 --- a/libraries/gpu/src/gpu/Image.cpp +++ b/libraries/gpu/src/gpu/Image.cpp @@ -32,7 +32,7 @@ template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { auto r = pixel::mix( c0, c1, - (pixel::Byte)bc1.table); + (Byte)bc1.table); } } diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index c9969b8e15..f456240503 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -2,6 +2,8 @@ Let s try compressing images */ + +#include #include "Forward.h" @@ -11,6 +13,20 @@ namespace image { using Byte = uint8_t; using Byte2 = uint16_t; using Byte4 = uint32_t; + using Byte8 = uint64_t; + + // Storage type selector based on size (sizeof of a type) + template + struct storage { typedef T1 type; }; + + template + struct storage<2, T1, T2, T4, T8> { typedef T2 type; }; + + template + struct storage<4, T1, T2, T4, T8> { typedef T4 type; }; + + template + struct storage<8, T1, T2, T4, T8> { typedef T8 type; }; static const Byte BLACK8 { 0 }; static const Byte WHITE8 { 255 }; @@ -25,7 +41,6 @@ namespace image { namespace pixel { - struct RGB32 { Byte r { BLACK8 }; Byte g { BLACK8 }; @@ -40,7 +55,6 @@ namespace image { Byte a { WHITE8 }; }; - struct RGB16_565 { Byte2 b : 5; Byte2 g : 6; @@ -49,58 +63,66 @@ namespace image { RGB16_565() : b(BLACK8), g(BLACK8), r(BLACK8) {} RGB16_565(Byte pR, Byte pG, Byte pB) : b(pB), g(pG), r(pR) {} }; + + struct R8 { + Byte r { BLACK8 }; + }; + template const P mix(const P p0, const P p1, const S alpha) { return p0; } template <> const RGB16_565 mix(const RGB16_565 p0, const RGB16_565 p1, const Byte alpha); - }; - - template class Pixel { - public: - using Format = F; - using Storage = S; - - union { - Storage raw; - Format val{ Format() }; // Format last to be initialized by Format's default constructor + template ::type > class Pixel { + public: + using Format = F; + using Storage = S; + + union { + Storage raw; + Format val{ Format() }; // Format last to be initialized by Format's default constructor + }; + + Pixel() {}; + Pixel(Format v) : val(v) {} + Pixel(Storage s) : raw(s) {} }; + - Pixel() {}; - Pixel(Format v) : val(v) {} - Pixel(Storage s) : raw(s) {} + template class PixelBlock { + public: + using Format = typename P::Format; + using Storage = typename P::Storage; + + static const uint32_t WIDTH { 4 }; + static const uint32_t HEIGHT { WIDTH }; + static const uint32_t SIZE { WIDTH * HEIGHT }; + + uint32_t getSize() const { return SIZE * sizeof(P); } + + P pixels[SIZE]; + + PixelBlock() {} + + + PixelBlock(const P* srcPixels) { + setPixels(srcPixels); + } + + void setPixels(const P* srcPixels) { + memcpy(pixels, srcPixels, getSize()); + } + + const Storage* getStorage() const { return static_cast (&pixels->raw); } + }; }; - using PixRGB565 = Pixel; - using PixRGB32 = Pixel; - using PixRGBA32 = Pixel; - - - template class PixelBlock { - public: - using Format = typename P::Format; - using Storage = typename P::Storage; - static const uint32_t WIDTH { 4 }; - static const uint32_t HEIGHT { WIDTH }; - static const uint32_t SIZE { WIDTH * HEIGHT }; - - uint32_t getSize() const { return SIZE * sizeof(P); } - - P pixels[SIZE]; - - PixelBlock() {} - - - PixelBlock(const P* srcPixels) { - setPixels(srcPixels); - } - - void setPixels(const P* srcPixels) { - memcpy(pixels, srcPixels, getSize()); - } - - const Storage* getStorage() const { return static_cast (&pixels->raw); } - }; + + using PixRGB565 = pixel::Pixel; + using PixRGB32 = pixel::Pixel; + using PixRGBA32 = pixel::Pixel; + using PixR8 = pixel::Pixel; + class BC { public: @@ -109,15 +131,13 @@ namespace image { struct BC1 { PixRGB565 color0; PixRGB565 color1; - pixel::Byte4 table; - - - Byte + Byte4 table; }; + struct BC4 { PixRGB565 color0; PixRGB565 color1; - pixel::Byte4 table; + Byte4 table; }; }; @@ -125,19 +145,20 @@ namespace image { public: static const uint32_t SIZE { sizeof(T) }; union { - pixel::Byte bytes[SIZE]; + Byte bytes[SIZE]; T bc; }; CompressedBlock() {} }; + template void compress(const PB& srcBlock, CB& dstBlock) { } template void uncompress(const CB& srcBlock, PB& dstBlock) { } - using PB_RGB32 = PixelBlock; - using PB_RGBA32 = PixelBlock; + using PB_RGB32 = pixel::PixelBlock; + using PB_RGBA32 = pixel::PixelBlock; using CB_BC1 = CompressedBlock; using CB_BC4 = CompressedBlock; @@ -147,4 +168,44 @@ namespace image { template <> void uncompress(const CB_BC1& src, PB_RGB32& dst); template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst); + + + template + class PixelBlockArray { + public: + using Pixel = P; + using Block = pixel::PixelBlock; + + using Blocks = std::vector; + + }; + + class Grid { + public: + using Coord = uint16_t; + using Coord2 = glm::u16vec2; + using Size = uint32_t; + + Coord2 _block { 1, 1 }; + Coord2 _surface { 1, 1 }; + + Coord width() const { return _surface.x; } + Coord height() const { return _surface.y; } + Size size() const { return width() * height(); } + + Coord blockWidth() const { return _block.x; } + Coord blockHeight() const { return _block.y; } + Size blockSize() const { return blockWidth() * blockHeight(); } + + Coord pixelWidth() const { return _surface.x * _block.x; } + Coordisd pixelHeight() const { return _surface.y * _block.y; } + Size pixelSize() const { return pixelWidth() * pixelHeight(); } + + Coord2 pixelToBlock(const Coord2& coord) const { + auto blockX = coord.x / blockWidth(); + auto blockY = coord.y / blockHeight(); + return Coord2(blockX, blockY); + } + + }; } \ No newline at end of file diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 1cbff8bd21..1b51d16883 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -252,6 +252,8 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag image::PixRGBA32 pix1; + image::PixR8 pix2; + image::PixRGB565 pix3; image::PB_RGB32 pb0; @@ -260,6 +262,7 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag auto pix0_s = sizeof(pix0); auto pix1_s = sizeof(pix1); + auto pix2_s = sizeof(pix2); auto pix3_s = sizeof(pix3); auto pb0_s = sizeof(pb0); From 1c61664ca01c3d8d295eb8dc4dc34eaa15a53901 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 13 Nov 2016 23:20:39 -0800 Subject: [PATCH 06/22] Still refining th edesign of th eiMage classes --- libraries/gpu/src/gpu/Image.h | 106 +++++++++++++++++------ libraries/model/src/model/TextureMap.cpp | 3 + 2 files changed, 82 insertions(+), 27 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index f456240503..bda16910c4 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -55,6 +55,12 @@ namespace image { Byte a { WHITE8 }; }; + struct R10G10B12 { + Byte4 r : 10; + Byte4 g : 10; + Byte4 b : 12; + }; + struct RGB16_565 { Byte2 b : 5; Byte2 g : 6; @@ -88,18 +94,15 @@ namespace image { }; - template class PixelBlock { + template class PixelBlock { public: using Format = typename P::Format; using Storage = typename P::Storage; - static const uint32_t WIDTH { 4 }; - static const uint32_t HEIGHT { WIDTH }; - static const uint32_t SIZE { WIDTH * HEIGHT }; + constexpr uint16_t getLength() const { return length; } + uint32_t getSize() const { return length * sizeof(P); } - uint32_t getSize() const { return SIZE * sizeof(P); } - - P pixels[SIZE]; + P pixels[length]; PixelBlock() {} @@ -114,6 +117,23 @@ namespace image { const Storage* getStorage() const { return static_cast (&pixels->raw); } }; + + template class Tile { + public: + using Format = typename P::Format; + using Storage = typename P::Storage; + using Block = typename PixelBlock; + + constexpr uint16_t getWidth() const { return tileW; } + constexpr uint16_t getHeight() const { return tileH; } + + Block _block; + + Tile() {} + Tile(const P* srcPixels) : _block(srcPixels) {} + + + }; }; @@ -121,6 +141,7 @@ namespace image { using PixRGB565 = pixel::Pixel; using PixRGB32 = pixel::Pixel; using PixRGBA32 = pixel::Pixel; + using PixR10G10B12 = pixel::Pixel; using PixR8 = pixel::Pixel; @@ -157,8 +178,8 @@ namespace image { template void uncompress(const CB& srcBlock, PB& dstBlock) { } - using PB_RGB32 = pixel::PixelBlock; - using PB_RGBA32 = pixel::PixelBlock; + using PB_RGB32 = pixel::PixelBlock; + using PB_RGBA32 = pixel::PixelBlock; using CB_BC1 = CompressedBlock; using CB_BC4 = CompressedBlock; @@ -170,14 +191,14 @@ namespace image { template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst); - template + template class PixelBlockArray { public: - using Pixel = P; - using Block = pixel::PixelBlock; + using Block = B; using Blocks = std::vector; + Blocks _blocks; }; class Grid { @@ -186,26 +207,57 @@ namespace image { using Coord2 = glm::u16vec2; using Size = uint32_t; - Coord2 _block { 1, 1 }; + static const Coord2 TILE_PIXEL; + static const Coord2 TILE_QUAD; + static const Coord2 TILE_DEFAULT; + + Grid(const Coord2& surface, const Coord2& tile = TILE_DEFAULT) : _surface(surface), _tile(tile) {} + Grid(Coord width, Coord height, const Coord2& tile = TILE_DEFAULT) : _surface(width, height), _tile(tile) {} + Coord2 _surface { 1, 1 }; + Coord2 _tile { TILE_DEFAULT }; Coord width() const { return _surface.x; } Coord height() const { return _surface.y; } - Size size() const { return width() * height(); } - - Coord blockWidth() const { return _block.x; } - Coord blockHeight() const { return _block.y; } - Size blockSize() const { return blockWidth() * blockHeight(); } - - Coord pixelWidth() const { return _surface.x * _block.x; } - Coordisd pixelHeight() const { return _surface.y * _block.y; } - Size pixelSize() const { return pixelWidth() * pixelHeight(); } - - Coord2 pixelToBlock(const Coord2& coord) const { - auto blockX = coord.x / blockWidth(); - auto blockY = coord.y / blockHeight(); - return Coord2(blockX, blockY); + const Coord2& size() const { return _surface; } + + Coord tileWidth() const { return evalNumTiles(_surface.x, _tile.x); } + Coord tileHeight() const { return evalNumTiles(_surface.y, _tile.y); } + Coord2 tileSize() const { return Coord2(tileWidth(), tileHeight()); } + + + Coord2 toTile(const Coord2& pixel) const { return pixel / _tile; } + Coord2 toTileSubpix(const Coord2& pixel) const { return pixel % _tile; } + Coord2 toTile(const Coord2& pixel, Coord2& subpix) const { + subpix = toTileSubpix(pixel); + return toTile(pixel); } + Coord2 toPixel(const Coord2& tile) const { return tile * _tile; } + Coord2 toPixel(const Coord2& tile, const Coord2& subpix) const { return tile * _tile + subpix; } + + + static Coord evalNumTiles(Coord pixelLength, Coord tileLength) { + auto tilePos = pixelLength / tileLength; + if (tilePos * tileLength < pixelLength) { + tilePos++; + } + return tilePos; + } + }; + + template + class Pixmap { + public: + using Tile = T; + + Grid _grid; + PixelBlockArray _blocks; + + void resize(const Grid::Coord2& widthHeight) { + _grid = Grid(widthHeight, Coord2(Tile::getWidth(), Tile::getHeight())); + + } + }; } \ No newline at end of file diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 1b51d16883..83a9e008cc 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -272,6 +272,9 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag image::compress(pb0, cb); image::uncompress(cb, pb1); + image::Grid grid; + grid. + if (generateMips) { ::generateMips(theTexture, image, formatMip); } From f34f1312ab0117d20bd6136e4842d223527effd8 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 1 Feb 2017 15:53:49 -0800 Subject: [PATCH 07/22] Few fixes --- libraries/gpu/src/gpu/Image.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index bda16910c4..67d2071c4a 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -122,7 +122,7 @@ namespace image { public: using Format = typename P::Format; using Storage = typename P::Storage; - using Block = typename PixelBlock; + using Block = PixelBlock; constexpr uint16_t getWidth() const { return tileW; } constexpr uint16_t getHeight() const { return tileH; } @@ -250,9 +250,10 @@ namespace image { class Pixmap { public: using Tile = T; + using Block = typename Tile::Block; Grid _grid; - PixelBlockArray _blocks; + PixelBlockArray _blocks; void resize(const Grid::Coord2& widthHeight) { _grid = Grid(widthHeight, Coord2(Tile::getWidth(), Tile::getHeight())); @@ -260,4 +261,4 @@ namespace image { } }; -} \ No newline at end of file +} From 569378bdeba31f3ee23770c243d49ce1b2811b1c Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 2 Feb 2017 01:57:43 -0800 Subject: [PATCH 08/22] REcompiling for windows... --- libraries/gpu/src/gpu/Image.cpp | 6 +-- libraries/gpu/src/gpu/Image.h | 67 ++++++++++++------------ libraries/model/src/model/TextureMap.cpp | 15 ++---- 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp index 5de1008d8f..46486d9436 100644 --- a/libraries/gpu/src/gpu/Image.cpp +++ b/libraries/gpu/src/gpu/Image.cpp @@ -15,10 +15,6 @@ namespace image { } template <> void compress(const PB_RGB32& src, CB_BC1& dst) { - - for (auto& b : dst.bytes) { - b = 12; - } } template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { @@ -27,7 +23,7 @@ template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { auto c0 = bc1.color0.val; auto c1 = bc1.color1.val; - for (int i = 0; i < PB_RGB32::SIZE; ++i) { + for (int i = 0; i < PB_RGB32::LENGTH; ++i) { //dst.pixels[i] = ; auto r = pixel::mix( c0, diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index bda16910c4..4457730594 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -82,40 +82,37 @@ namespace image { public: using Format = F; using Storage = S; - - union { - Storage raw; - Format val{ Format() }; // Format last to be initialized by Format's default constructor - }; - - Pixel() {}; + + Format val { Format() }; + + Pixel() : val(Format()) {}; Pixel(Format v) : val(v) {} - Pixel(Storage s) : raw(s) {} + Pixel(Storage s) : val(*static_cast (&s)) {} + + const Storage* storage() const { return static_cast (&val); } }; - template class PixelBlock { public: using Format = typename P::Format; using Storage = typename P::Storage; - - constexpr uint16_t getLength() const { return length; } - uint32_t getSize() const { return length * sizeof(P); } - + + static const uint16_t LENGTH { length }; + static const uint32_t SIZE { length * sizeof(P) }; + P pixels[length]; - + PixelBlock() {} - - + PixelBlock(const P* srcPixels) { setPixels(srcPixels); } - + void setPixels(const P* srcPixels) { memcpy(pixels, srcPixels, getSize()); } - - const Storage* getStorage() const { return static_cast (&pixels->raw); } + + const Storage* storage() const { return pixels->storage(); } }; template class Tile { @@ -123,12 +120,12 @@ namespace image { using Format = typename P::Format; using Storage = typename P::Storage; using Block = typename PixelBlock; - - constexpr uint16_t getWidth() const { return tileW; } - constexpr uint16_t getHeight() const { return tileH; } - + + uint16_t getWidth() const { return tileW; } + uint16_t getHeight() const { return tileH; } + Block _block; - + Tile() {} Tile(const P* srcPixels) : _block(srcPixels) {} @@ -162,15 +159,18 @@ namespace image { }; }; - template class CompressedBlock { + template ::type> class CompressedBlock { public: - static const uint32_t SIZE { sizeof(T) }; - union { - Byte bytes[SIZE]; - T bc; - }; - + using Format = F; + using Storage = S; + + static const uint32_t SIZE { sizeof(F) }; + + Format bc; + CompressedBlock() {} + + const Storage* storage() const { return static_cast (&bc); } }; @@ -250,9 +250,10 @@ namespace image { class Pixmap { public: using Tile = T; - + using Block = typename T::Block; + Grid _grid; - PixelBlockArray _blocks; + PixelBlockArray _blocks; void resize(const Grid::Coord2& widthHeight) { _grid = Grid(widthHeight, Coord2(Tile::getWidth(), Tile::getHeight())); diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 215ee367e4..3e2263ffc8 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -265,7 +265,6 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag image::PixRGB565 pix3; image::PB_RGB32 pb0; - image::CB_BC1 cb; image::PB_RGB32 pb1; auto pix0_s = sizeof(pix0); @@ -274,15 +273,11 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag auto pix3_s = sizeof(pix3); auto pb0_s = sizeof(pb0); - auto cb_s = sizeof(cb); - - auto cb_bytes = pb0.getStorage(); - image::compress(pb0, cb); - image::uncompress(cb, pb1); - - image::Grid grid; - grid. - + + image::Pixmap theMap(); + + // theMap(image.width(), image.height(), image.byteCount(), image.constBits()); + if (generateMips) { ::generateMips(theTexture, image, formatMip); } From 6dc2cee95dd5323c8bb9483cef99e0e0fa3499eb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 2 Feb 2017 13:34:22 -0800 Subject: [PATCH 09/22] use type definition --- libraries/model-networking/src/model-networking/ModelCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index bcca846625..adef3ce2b5 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -159,7 +159,7 @@ protected: class Texture { public: QString name; - QSharedPointer texture; + NetworkTexturePointer texture; }; using Textures = std::vector; From b4cef787d99b90bd82489b75cc22751695a19191 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 2 Feb 2017 13:34:44 -0800 Subject: [PATCH 10/22] cleanup whitespace --- libraries/fbx/src/FBXReader_Material.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index 8c0f4b34ac..f3d0c30a41 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -47,10 +47,10 @@ FBXTexture FBXReader::getTexture(const QString& textureID) { texture.texcoordSet = 0; if (_textureParams.contains(textureID)) { auto p = _textureParams.value(textureID); - + texture.transform.setTranslation(p.translation); texture.transform.setRotation(glm::quat(glm::radians(p.rotation))); - + auto scaling = p.scaling; // Protect from bad scaling which should never happen if (scaling.x == 0.0f) { @@ -63,7 +63,7 @@ FBXTexture FBXReader::getTexture(const QString& textureID) { scaling.z = 1.0f; } texture.transform.setScale(scaling); - + if ((p.UVSet != "map1") && (p.UVSet != "UVSet0")) { texture.texcoordSet = 1; } @@ -78,11 +78,10 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { QJsonDocument materialMapDocument = QJsonDocument::fromJson(materialMapString.toUtf8()); QJsonObject materialMap = materialMapDocument.object(); - // foreach (const QString& materialID, materials) { for (QHash::iterator it = _fbxMaterials.begin(); it != _fbxMaterials.end(); it++) { FBXMaterial& material = (*it); - // Maya is the exporting the shading model and we aretrying to use it + // Maya is the exporting the shading model and we are trying to use it bool isMaterialLambert = (material.shadingModel.toLower() == "lambert"); // the pure material associated with this part @@ -127,21 +126,19 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { detectDifferentUVs |= (transparentTexture.texcoordSet != 0) || (!transparentTexture.transform.isIdentity()); } - - FBXTexture normalTexture; QString bumpTextureID = bumpTextures.value(material.materialID); QString normalTextureID = normalTextures.value(material.materialID); if (!normalTextureID.isNull()) { normalTexture = getTexture(normalTextureID); normalTexture.isBumpmap = false; - + material.normalTexture = normalTexture; detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity()); } else if (!bumpTextureID.isNull()) { normalTexture = getTexture(bumpTextureID); normalTexture.isBumpmap = true; - + material.normalTexture = normalTexture; detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity()); } @@ -151,7 +148,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { if (!specularTextureID.isNull()) { specularTexture = getTexture(specularTextureID); detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity()); - material.specularTexture = specularTexture; + material.specularTexture = specularTexture; } FBXTexture metallicTexture; @@ -222,7 +219,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { ambientTextureID = ambientFactorTextures.value(material.materialID); } } - + if (_loadLightmaps && !ambientTextureID.isNull()) { ambientTexture = getTexture(ambientTextureID); detectDifferentUVs |= (ambientTexture.texcoordSet != 0) || (!ambientTexture.transform.isIdentity()); From 64dbfd08194e9a61b253327657d0c0ea4e1a9fdb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 2 Feb 2017 13:35:40 -0800 Subject: [PATCH 11/22] cap size of textures from FBX files --- libraries/fbx/src/FBXReader.h | 9 ++-- .../src/model-networking/ModelCache.cpp | 2 +- .../src/model-networking/TextureCache.cpp | 53 +++++++++++++------ .../src/model-networking/TextureCache.h | 13 +++-- libraries/networking/src/ResourceCache.h | 4 +- 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index cd1dbc5c4f..8b58ad62d1 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -100,22 +100,25 @@ public: /// A single binding to a joint in an FBX document. class FBXCluster { public: - + int jointIndex; glm::mat4 inverseBindMatrix; }; +const int MAX_FBX_TEXTURE_SIZE = 1024 * 1024; + /// A texture map in an FBX document. class FBXTexture { public: QString name; QByteArray filename; QByteArray content; - + Transform transform; + int maxSize { MAX_FBX_TEXTURE_SIZE }; int texcoordSet; QString texcoordSetName; - + bool isBumpmap{ false }; bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); } diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 2a02540821..946e507d98 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -472,7 +472,7 @@ QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& textu model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, TextureType type, MapChannel channel) { const auto url = getTextureUrl(baseUrl, fbxTexture); - const auto texture = DependencyManager::get()->getTexture(url, type, fbxTexture.content); + const auto texture = DependencyManager::get()->getTexture(url, type, fbxTexture.content, fbxTexture.maxSize); _textures[channel] = Texture { fbxTexture.name, texture }; auto map = std::make_shared(); diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 6a4edd60ed..e108e69aa1 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -167,16 +167,17 @@ class TextureExtra { public: NetworkTexture::Type type; const QByteArray& content; + int maxSize; }; -ScriptableResource* TextureCache::prefetch(const QUrl& url, int type) { +ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxSize) { auto byteArray = QByteArray(); - TextureExtra extra = { (Type)type, byteArray }; + TextureExtra extra = { (Type)type, byteArray, maxSize }; return ResourceCache::prefetch(url, &extra); } -NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const QByteArray& content) { - TextureExtra extra = { type, content }; +NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const QByteArray& content, int maxSize) { + TextureExtra extra = { type, content, maxSize }; return ResourceCache::getResource(url, QUrl(), &extra).staticCast(); } @@ -251,13 +252,15 @@ QSharedPointer TextureCache::createResource(const QUrl& url, const QSh const TextureExtra* textureExtra = static_cast(extra); auto type = textureExtra ? textureExtra->type : Type::DEFAULT_TEXTURE; auto content = textureExtra ? textureExtra->content : QByteArray(); - return QSharedPointer(new NetworkTexture(url, type, content), + auto maxSize = textureExtra ? textureExtra->maxSize : ABSOLUTE_MAX_TEXTURE_SIZE; + return QSharedPointer(new NetworkTexture(url, type, content, maxSize), &Resource::deleter); } -NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& content) : +NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& content, int maxSize) : Resource(url), - _type(type) + _type(type), + _maxSize(maxSize) { _textureSource = std::make_shared(); @@ -274,7 +277,7 @@ NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& con } NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content) : - NetworkTexture(url, CUSTOM_TEXTURE, content) + NetworkTexture(url, CUSTOM_TEXTURE, content, ABSOLUTE_MAX_TEXTURE_SIZE) { _textureLoader = textureLoader; } @@ -290,7 +293,8 @@ NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const { class ImageReader : public QRunnable { public: - ImageReader(const QWeakPointer& resource, const QByteArray& data, const QUrl& url = QUrl()); + ImageReader(const QWeakPointer& resource, const QByteArray& data, + const QUrl& url = QUrl(), int maxSize = ABSOLUTE_MAX_TEXTURE_SIZE); virtual void run() override; @@ -300,6 +304,7 @@ private: QWeakPointer _resource; QUrl _url; QByteArray _content; + int _maxSize; }; void NetworkTexture::downloadFinished(const QByteArray& data) { @@ -308,14 +313,15 @@ void NetworkTexture::downloadFinished(const QByteArray& data) { } void NetworkTexture::loadContent(const QByteArray& content) { - QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url)); + QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url, _maxSize)); } ImageReader::ImageReader(const QWeakPointer& resource, const QByteArray& data, - const QUrl& url) : + const QUrl& url, int maxSize) : _resource(resource), _url(url), - _content(data) + _content(data), + _maxSize(maxSize) { #if DEBUG_DUMP_TEXTURE_LOADS static auto start = usecTimestampNow() / USECS_PER_MSEC; @@ -375,10 +381,10 @@ void ImageReader::run() { // Note that QImage.format is the pixel format which is different from the "format" of the image file... auto imageFormat = image.format(); - int originalWidth = image.width(); - int originalHeight = image.height(); + int imageWidth = image.width(); + int imageHeight = image.height(); - if (originalWidth == 0 || originalHeight == 0 || imageFormat == QImage::Format_Invalid) { + if (imageWidth == 0 || imageHeight == 0 || imageFormat == QImage::Format_Invalid) { if (filenameExtension.empty()) { qCDebug(modelnetworking) << "QImage failed to create from content, no file extension:" << _url; } else { @@ -386,6 +392,21 @@ void ImageReader::run() { } return; } + + if (imageWidth * imageHeight > _maxSize) { + float scaleFactor = sqrtf(_maxSize / (float)(imageWidth * imageHeight)); + int originalWidth = imageWidth; + int originalHeight = imageHeight; + imageWidth = (int)(scaleFactor * (float)imageWidth + 0.5f); + imageHeight = (int)(scaleFactor * (float)imageHeight + 0.5f); + //QSize newSize(imageWidth, imageHeight); + QImage newImage = image.scaled(QSize(imageWidth, imageHeight), Qt::IgnoreAspectRatio); + image.swap(newImage); + qCDebug(modelnetworking) << "Downscale image" << _url + << "from" << originalWidth << "x" << originalHeight + << "to" << imageWidth << "x" << imageHeight; + } + gpu::TexturePointer texture = nullptr; { // Double-check the resource still exists between long operations. @@ -408,7 +429,7 @@ void ImageReader::run() { } else { QMetaObject::invokeMethod(resource.data(), "setImage", Q_ARG(gpu::TexturePointer, texture), - Q_ARG(int, originalWidth), Q_ARG(int, originalHeight)); + Q_ARG(int, imageWidth), Q_ARG(int, imageHeight)); } } diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 8ccfe5364c..9ad06eddfb 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -23,6 +23,8 @@ #include #include +const int ABSOLUTE_MAX_TEXTURE_SIZE = 8192 * 8192; + namespace gpu { class Batch; } @@ -60,7 +62,7 @@ public: typedef gpu::Texture* TextureLoader(const QImage& image, const std::string& srcImageName); using TextureLoaderFunc = std::function; - NetworkTexture(const QUrl& url, Type type, const QByteArray& content); + NetworkTexture(const QUrl& url, Type type, const QByteArray& content, int maxSize); NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content); QString getType() const override { return "NetworkTexture"; } @@ -70,7 +72,7 @@ public: int getWidth() const { return _width; } int getHeight() const { return _height; } Type getTextureType() const { return _type; } - + TextureLoaderFunc getTextureLoader() const; signals: @@ -81,7 +83,7 @@ protected: virtual bool isCacheable() const override { return _loaded; } virtual void downloadFinished(const QByteArray& data) override; - + Q_INVOKABLE void loadContent(const QByteArray& content); Q_INVOKABLE void setImage(gpu::TexturePointer texture, int originalWidth, int originalHeight); @@ -92,6 +94,7 @@ private: int _originalHeight { 0 }; int _width { 0 }; int _height { 0 }; + int _maxSize { ABSOLUTE_MAX_TEXTURE_SIZE }; }; using NetworkTexturePointer = QSharedPointer; @@ -129,11 +132,11 @@ public: /// Loads a texture from the specified URL. NetworkTexturePointer getTexture(const QUrl& url, Type type = Type::DEFAULT_TEXTURE, - const QByteArray& content = QByteArray()); + const QByteArray& content = QByteArray(), int maxSize = ABSOLUTE_MAX_TEXTURE_SIZE); protected: // Overload ResourceCache::prefetch to allow specifying texture type for loads - Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type); + Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxSize = ABSOLUTE_MAX_TEXTURE_SIZE); virtual QSharedPointer createResource(const QUrl& url, const QSharedPointer& fallback, const void* extra) override; diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 03d37bc9ac..a369416ebe 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -86,7 +86,7 @@ private: /// Wrapper to expose resources to JS/QML class ScriptableResource : public QObject { Q_OBJECT - Q_PROPERTY(QUrl url READ getUrl) + Q_PROPERTY(QUrl url READ getURL) Q_PROPERTY(int state READ getState NOTIFY stateChanged) /**jsdoc @@ -125,7 +125,7 @@ public: */ Q_INVOKABLE void release(); - const QUrl& getUrl() const { return _url; } + const QUrl& getURL() const { return _url; } int getState() const { return (int)_state; } const QSharedPointer& getResource() const { return _resource; } From 2f8823d10384af30a0cd8c452db557acbf583558 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 2 Feb 2017 14:09:47 -0800 Subject: [PATCH 12/22] name change: maxSize to maxNumPixels --- libraries/fbx/src/FBXReader.h | 4 +-- .../src/model-networking/ModelCache.cpp | 2 +- .../src/model-networking/TextureCache.cpp | 35 +++++++++---------- .../src/model-networking/TextureCache.h | 10 +++--- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 8b58ad62d1..5b4d3ec3bf 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -105,7 +105,7 @@ public: glm::mat4 inverseBindMatrix; }; -const int MAX_FBX_TEXTURE_SIZE = 1024 * 1024; +const int MAX_FBX_TEXTURE_NUM_PIXELS = 1024 * 1024; /// A texture map in an FBX document. class FBXTexture { @@ -115,7 +115,7 @@ public: QByteArray content; Transform transform; - int maxSize { MAX_FBX_TEXTURE_SIZE }; + int maxNumPixels { MAX_FBX_TEXTURE_NUM_PIXELS }; int texcoordSet; QString texcoordSetName; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 946e507d98..dd3193073d 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -472,7 +472,7 @@ QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& textu model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, TextureType type, MapChannel channel) { const auto url = getTextureUrl(baseUrl, fbxTexture); - const auto texture = DependencyManager::get()->getTexture(url, type, fbxTexture.content, fbxTexture.maxSize); + const auto texture = DependencyManager::get()->getTexture(url, type, fbxTexture.content, fbxTexture.maxNumPixels); _textures[channel] = Texture { fbxTexture.name, texture }; auto map = std::make_shared(); diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index e108e69aa1..447a1b93c8 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -167,17 +167,17 @@ class TextureExtra { public: NetworkTexture::Type type; const QByteArray& content; - int maxSize; + int maxNumPixels; }; -ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxSize) { +ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxNumPixels) { auto byteArray = QByteArray(); - TextureExtra extra = { (Type)type, byteArray, maxSize }; + TextureExtra extra = { (Type)type, byteArray, maxNumPixels }; return ResourceCache::prefetch(url, &extra); } -NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const QByteArray& content, int maxSize) { - TextureExtra extra = { type, content, maxSize }; +NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const QByteArray& content, int maxNumPixels) { + TextureExtra extra = { type, content, maxNumPixels }; return ResourceCache::getResource(url, QUrl(), &extra).staticCast(); } @@ -252,15 +252,15 @@ QSharedPointer TextureCache::createResource(const QUrl& url, const QSh const TextureExtra* textureExtra = static_cast(extra); auto type = textureExtra ? textureExtra->type : Type::DEFAULT_TEXTURE; auto content = textureExtra ? textureExtra->content : QByteArray(); - auto maxSize = textureExtra ? textureExtra->maxSize : ABSOLUTE_MAX_TEXTURE_SIZE; - return QSharedPointer(new NetworkTexture(url, type, content, maxSize), + auto maxNumPixels = textureExtra ? textureExtra->maxNumPixels : ABSOLUTE_MAX_TEXTURE_NUM_PIXELS; + return QSharedPointer(new NetworkTexture(url, type, content, maxNumPixels), &Resource::deleter); } -NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& content, int maxSize) : +NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& content, int maxNumPixels) : Resource(url), _type(type), - _maxSize(maxSize) + _maxNumPixels(maxNumPixels) { _textureSource = std::make_shared(); @@ -277,7 +277,7 @@ NetworkTexture::NetworkTexture(const QUrl& url, Type type, const QByteArray& con } NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content) : - NetworkTexture(url, CUSTOM_TEXTURE, content, ABSOLUTE_MAX_TEXTURE_SIZE) + NetworkTexture(url, CUSTOM_TEXTURE, content, ABSOLUTE_MAX_TEXTURE_NUM_PIXELS) { _textureLoader = textureLoader; } @@ -294,7 +294,7 @@ class ImageReader : public QRunnable { public: ImageReader(const QWeakPointer& resource, const QByteArray& data, - const QUrl& url = QUrl(), int maxSize = ABSOLUTE_MAX_TEXTURE_SIZE); + const QUrl& url = QUrl(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS); virtual void run() override; @@ -304,7 +304,7 @@ private: QWeakPointer _resource; QUrl _url; QByteArray _content; - int _maxSize; + int _maxNumPixels; }; void NetworkTexture::downloadFinished(const QByteArray& data) { @@ -313,15 +313,15 @@ void NetworkTexture::downloadFinished(const QByteArray& data) { } void NetworkTexture::loadContent(const QByteArray& content) { - QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url, _maxSize)); + QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url, _maxNumPixels)); } ImageReader::ImageReader(const QWeakPointer& resource, const QByteArray& data, - const QUrl& url, int maxSize) : + const QUrl& url, int maxNumPixels) : _resource(resource), _url(url), _content(data), - _maxSize(maxSize) + _maxNumPixels(maxNumPixels) { #if DEBUG_DUMP_TEXTURE_LOADS static auto start = usecTimestampNow() / USECS_PER_MSEC; @@ -393,13 +393,12 @@ void ImageReader::run() { return; } - if (imageWidth * imageHeight > _maxSize) { - float scaleFactor = sqrtf(_maxSize / (float)(imageWidth * imageHeight)); + if (imageWidth * imageHeight > _maxNumPixels) { + float scaleFactor = sqrtf(_maxNumPixels / (float)(imageWidth * imageHeight)); int originalWidth = imageWidth; int originalHeight = imageHeight; imageWidth = (int)(scaleFactor * (float)imageWidth + 0.5f); imageHeight = (int)(scaleFactor * (float)imageHeight + 0.5f); - //QSize newSize(imageWidth, imageHeight); QImage newImage = image.scaled(QSize(imageWidth, imageHeight), Qt::IgnoreAspectRatio); image.swap(newImage); qCDebug(modelnetworking) << "Downscale image" << _url diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 9ad06eddfb..cb509490c6 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -23,7 +23,7 @@ #include #include -const int ABSOLUTE_MAX_TEXTURE_SIZE = 8192 * 8192; +const int ABSOLUTE_MAX_TEXTURE_NUM_PIXELS = 8192 * 8192; namespace gpu { class Batch; @@ -62,7 +62,7 @@ public: typedef gpu::Texture* TextureLoader(const QImage& image, const std::string& srcImageName); using TextureLoaderFunc = std::function; - NetworkTexture(const QUrl& url, Type type, const QByteArray& content, int maxSize); + NetworkTexture(const QUrl& url, Type type, const QByteArray& content, int maxNumPixels); NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content); QString getType() const override { return "NetworkTexture"; } @@ -94,7 +94,7 @@ private: int _originalHeight { 0 }; int _width { 0 }; int _height { 0 }; - int _maxSize { ABSOLUTE_MAX_TEXTURE_SIZE }; + int _maxNumPixels { ABSOLUTE_MAX_TEXTURE_NUM_PIXELS }; }; using NetworkTexturePointer = QSharedPointer; @@ -132,11 +132,11 @@ public: /// Loads a texture from the specified URL. NetworkTexturePointer getTexture(const QUrl& url, Type type = Type::DEFAULT_TEXTURE, - const QByteArray& content = QByteArray(), int maxSize = ABSOLUTE_MAX_TEXTURE_SIZE); + const QByteArray& content = QByteArray(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS); protected: // Overload ResourceCache::prefetch to allow specifying texture type for loads - Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxSize = ABSOLUTE_MAX_TEXTURE_SIZE); + Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS); virtual QSharedPointer createResource(const QUrl& url, const QSharedPointer& fallback, const void* extra) override; From b440ccad280b445fa17660b449eae4c1a3a3c444 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 2 Feb 2017 17:53:48 -0800 Subject: [PATCH 13/22] Improving the IMage class --- libraries/gpu/src/gpu/Image.h | 135 ++++++++++++++++++++++- libraries/model/src/model/TextureMap.cpp | 5 +- 2 files changed, 134 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index 4457730594..6af763e6bd 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -37,8 +37,20 @@ namespace image { Byte mix5_4(const Byte x, const Byte y, const Byte a) { return mix<5, 4>(x, y, a); } Byte mix6_4(const Byte x, const Byte y, const Byte a) { return mix<6, 4>(x, y, a); } - - + + + + // Coordinate and count types + using Coord = uint16_t; + using Coord2 = glm::u16vec2; + using Count = uint32_t; + + // Maximum pixel along one direction coord is 32768 + static const Coord MAX_COORD { 32768 }; + // Maximum number of pixels + static const Count MAX_COUNT { MAX_COORD * MAX_COORD }; + + namespace pixel { struct RGB32 { @@ -83,6 +95,8 @@ namespace image { using Format = F; using Storage = S; + static const uint32_t SIZE { sizeof(S) }; + Format val { Format() }; Pixel() : val(Format()) {}; @@ -191,14 +205,75 @@ namespace image { template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst); + template + class PixelArray { + public: + using Pixel = P; + using Storage = typename P::Storage; + using Storages = std::vector; + + static int evalNumPixels(size_t byteSize) { + size_t numPixels = byteSize / Pixel::SIZE; + if (byteSize > numPixels * Pixel::SIZE) { + numPixels++; + } + return (int)numPixels; + }; + static size_t evalByteSize(int numPixels) { + return numPixels * Pixel::SIZE; + }; + + PixelArray(size_t byteSize, const void* bytes) { + setBytes(byteSize, bytes); + } + + int numPixels() const { return _storages.size(); } + size_t byteSize() const { return evalByteSize(_storages.size()); } + + Storages _storages; + + private: + void setBytes(size_t byteSize, const void* bytes) { + _storages = Storages(evalNumPixels(byteSize)); + if (bytes) { + memcpy(_storages.data(), bytes, byteSize); + } + } + }; + template class PixelBlockArray { public: using Block = B; - using Blocks = std::vector; - + + static int evalNumBlocks(size_t byteSize) { + size_t numBlocks = byteSize / Block::SIZE; + if (byteSize > numBlocks * Block::SIZE) { + numBlocks++; + } + return (int) numBlocks; + }; + static size_t evalByteSize(int numBlocks) { + return numBlocks * Block::SIZE; + }; + + PixelBlockArray(size_t byteSize, const void* bytes) { + setBytes(byteSize, bytes); + } + + int numBlocks() const { return evalByteSize(_blocks.size()); } + size_t byteSize() const { return evalByteSize(_blocks.size()); } + Blocks _blocks; + + private: + void setBytes(size_t byteSize, const void* bytes) { + _blocks = Blocks(evalNumBlocks(byteSize)); + if (bytes) { + memcpy(_blocks.data(), bytes, byteSize); + } + } }; class Grid { @@ -247,7 +322,7 @@ namespace image { }; template - class Pixmap { + class Tilemap { public: using Tile = T; using Block = typename T::Block; @@ -261,4 +336,54 @@ namespace image { } }; + + class Dim { + public: + + Coord2 _dims { 0 }; + + static Coord cap(Coord c) { return (c < MAX_COORD ? c : MAX_COORD); } + static Coord2 cap(const Coord2& dims) { return Coord2(cap(dims.x), cap(dims.y)); } + + static Count numPixels(const Coord2& dims) { return Count(cap(dims.x)) * Count(cap(dims.y)); } + + + static Coord nextMip(Coord c) { return (c > 1 ? (c >> 1) : c); } + static Coord2 nextMip(const Coord2& dims) { return Coord2(nextMip(dims.x), nextMip(dims.y)); } + + Dim(Coord w, Coord h) : _dims(w, h) {} + Dim(const Coord2& dims) : _dims(dims) {} + + Count numPixels() const { return Dim::numPixels(_dims); } + Dim nextMip() const { return Dim(nextMip(_dims)); } + }; + + template < typename P > class Surface { + public: + using Pixel = P; + using Format = typename P::Format; + using Pixels = pixel::Pixels

; + + Dim _dims { 0, 0 }; + Pixels _pixels; + + Surface(Coord width, Coord height, size_t byteSize, const void* bytes) : + _dims(width, height), + _pixels(byteSize, bytes) + {} + + void downsample() { + Dim subDim = _dims.nextMip(); + + Surface next() + + + for (int y = 0; y < _dims.y; y++) { + for (int x = 0; x < _dims.x; x++) { + + } + } + } + + }; } \ No newline at end of file diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 3e2263ffc8..bef0f0c92c 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -274,7 +274,10 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag auto pb0_s = sizeof(pb0); - image::Pixmap theMap(); + image::Surface surface(image.width(), image.height(), image.byteCount(), image.constBits()); + + auto sub = surface.downsample(); + // theMap(image.width(), image.height(), image.byteCount(), image.constBits()); From 56911bdf1becc2a368e087f9c775252cade1187e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 3 Feb 2017 11:14:40 -0800 Subject: [PATCH 14/22] sliding texture caps for models --- libraries/fbx/src/FBXReader.cpp | 27 +++++++++++++ libraries/fbx/src/FBXReader.h | 8 +++- libraries/fbx/src/FBXReader_Material.cpp | 50 ++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 42922ce226..917009956e 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1465,6 +1465,33 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS // Create the Material Library consolidateFBXMaterials(mapping); + + // HACK: until we get proper LOD management we're going to cap model textures + // according to how many unique textures the model uses: + // 1 - 7 textures --> 2048 + // 8 - 31 textures --> 1024 + // 32 - 127 textures --> 512 + // etc... + QSet uniqueTextures; + for (auto& material : _fbxMaterials) { + material.getTextureNames(uniqueTextures); + } + int numTextures = uniqueTextures.size(); + const int MAX_NUM_TEXTURES_AT_MAX_RESOLUTION = 7; + if (numTextures > MAX_NUM_TEXTURES_AT_MAX_RESOLUTION) { + int maxWidth = sqrt(MAX_NUM_PIXELS_FOR_FBX_TEXTURE + 1); + int t = numTextures; + t /= MAX_NUM_TEXTURES_AT_MAX_RESOLUTION; + while (t > 0) { + maxWidth /= 2; + t /= 4; + } + qCDebug(modelformat) << "max square texture width =" << maxWidth << " for model" << url; + for (auto& material : _fbxMaterials) { + material.setMaxNumPixelsPerTexture(maxWidth * maxWidth); + } + } + geometry.materials = _fbxMaterials; // see if any materials have texture children diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 5b4d3ec3bf..b0e34dd674 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -13,6 +13,7 @@ #define hifi_FBXReader_h #include +#include #include #include #include @@ -105,7 +106,7 @@ public: glm::mat4 inverseBindMatrix; }; -const int MAX_FBX_TEXTURE_NUM_PIXELS = 1024 * 1024; +const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048; /// A texture map in an FBX document. class FBXTexture { @@ -115,7 +116,7 @@ public: QByteArray content; Transform transform; - int maxNumPixels { MAX_FBX_TEXTURE_NUM_PIXELS }; + int maxNumPixels { MAX_NUM_PIXELS_FOR_FBX_TEXTURE }; int texcoordSet; QString texcoordSetName; @@ -146,6 +147,9 @@ public: shininess(shininess), opacity(opacity) {} + void getTextureNames(QSet& textureList) const; + void setMaxNumPixelsPerTexture(int maxNumPixels); + glm::vec3 diffuseColor{ 1.0f }; float diffuseFactor{ 1.0f }; glm::vec3 specularColor{ 0.02f }; diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index f3d0c30a41..ca2ec557b4 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -27,6 +27,56 @@ #include "ModelFormatLogging.h" +void FBXMaterial::getTextureNames(QSet& textureList) const { + if (!normalTexture.isNull()) { + textureList.insert(normalTexture.name); + } + if (!albedoTexture.isNull()) { + textureList.insert(albedoTexture.name); + } + if (!opacityTexture.isNull()) { + textureList.insert(opacityTexture.name); + } + if (!glossTexture.isNull()) { + textureList.insert(glossTexture.name); + } + if (!roughnessTexture.isNull()) { + textureList.insert(roughnessTexture.name); + } + if (!specularTexture.isNull()) { + textureList.insert(specularTexture.name); + } + if (!metallicTexture.isNull()) { + textureList.insert(metallicTexture.name); + } + if (!emissiveTexture.isNull()) { + textureList.insert(emissiveTexture.name); + } + if (!occlusionTexture.isNull()) { + textureList.insert(occlusionTexture.name); + } + if (!scatteringTexture.isNull()) { + textureList.insert(scatteringTexture.name); + } + if (!lightmapTexture.isNull()) { + textureList.insert(lightmapTexture.name); + } +} + +void FBXMaterial::setMaxNumPixelsPerTexture(int maxNumPixels) { + normalTexture.maxNumPixels = maxNumPixels; + albedoTexture.maxNumPixels = maxNumPixels; + opacityTexture.maxNumPixels = maxNumPixels; + glossTexture.maxNumPixels = maxNumPixels; + roughnessTexture.maxNumPixels = maxNumPixels; + specularTexture.maxNumPixels = maxNumPixels; + metallicTexture.maxNumPixels = maxNumPixels; + emissiveTexture.maxNumPixels = maxNumPixels; + occlusionTexture.maxNumPixels = maxNumPixels; + scatteringTexture.maxNumPixels = maxNumPixels; + lightmapTexture.maxNumPixels = maxNumPixels; +} + bool FBXMaterial::needTangentSpace() const { return !normalTexture.isNull(); } From 27dab5c4baabcfae54a79e90f0b00747d2a9e68c Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 3 Feb 2017 12:03:59 -0800 Subject: [PATCH 15/22] COmbining more intrumentation, mip generation on cpu and an improved blit for the derez case --- .../gpu-gl/src/gpu/gl/GLTextureTransfer.cpp | 2 + .../src/gpu/gl45/GL45BackendTexture.cpp | 65 +++++++++++++------ libraries/model/src/model/TextureMap.cpp | 2 +- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp index df9153d43e..179297069f 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp @@ -113,6 +113,7 @@ void GLTextureTransferHelper::queueExecution(VoidLambda lambda) { #define MAX_TRANSFERS_PER_PASS 2 bool GLTextureTransferHelper::process() { + PROFILE_RANGE(render_gpu_gl, __FUNCTION__) // Take any new textures or commands off the queue VoidLambdaList pendingCommands; TextureList newTransferTextures; @@ -151,6 +152,7 @@ bool GLTextureTransferHelper::process() { #endif return true; } + PROFILE_COUNTER_IF_CHANGED(render_gpu_gl, "transferringTextures", size_t, _transferringTextures.size()) static auto lastReport = usecTimestampNow(); auto now = usecTimestampNow(); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index b540a403c7..37d238f95c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -297,6 +297,7 @@ void GL45Texture::startTransfer() { } bool GL45Texture::continueTransfer() { + PROFILE_RANGE(render_gpu_gl, "continueTransfer") size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1; for (uint8_t face = 0; face < maxFace; ++face) { for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) { @@ -306,6 +307,8 @@ bool GL45Texture::continueTransfer() { _sparseInfo.allocatedPages += _sparseInfo.getPageCount(size); } if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) { + PROFILE_RANGE_EX(render_gpu_gl, "texSubImage", 0x0000ffff, (size.x * size.y * maxFace / 1024)); + auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); if (GL_TEXTURE_2D == _target) { @@ -379,6 +382,8 @@ void GL45Texture::stripToMip(uint16_t newMinMip) { return; } + PROFILE_RANGE(render_gpu_gl, "GL45Texture::stripToMip"); + auto mipLevels = usedMipLevels(); { Lock lock(texturesByMipCountsMutex); @@ -420,29 +425,51 @@ void GL45Texture::stripToMip(uint16_t newMinMip) { auto newLevels = usedMipLevels(); // Create and setup the new texture (allocate) - glCreateTextures(_target, 1, &const_cast(_id)); - glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); - glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip); - Vec3u newDimensions = _gpuObject.evalMipDimensions(_mipOffset); - glTextureStorage2D(_id, newLevels, _internalFormat, newDimensions.x, newDimensions.y); + { + Vec3u newDimensions = _gpuObject.evalMipDimensions(_mipOffset); + PROFILE_RANGE_EX(render_gpu_gl, "Re-Allocate", 0xff0000ff, (newDimensions.x * newDimensions.y)); + + glCreateTextures(_target, 1, &const_cast(_id)); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); + glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip); + glTextureStorage2D(_id, newLevels, _internalFormat, newDimensions.x, newDimensions.y); + } // Copy the contents of the old texture to the new - GLuint fbo { 0 }; - glCreateFramebuffers(1, &fbo); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); - for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { - uint16 sourceMip = targetMip + mipDelta; - Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); - for (GLenum target : getFaceTargets(_target)) { - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip); - (void)CHECK_GL_ERROR(); - glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y); - (void)CHECK_GL_ERROR(); + { + PROFILE_RANGE(render_gpu_gl, "Blit"); + /* + GLuint fbo { 0 }; + glCreateFramebuffers(1, &fbo); + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { + uint16 sourceMip = targetMip + mipDelta; + Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); + for (GLenum target : getFaceTargets(_target)) { + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip); + (void)CHECK_GL_ERROR(); + glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y); + (void)CHECK_GL_ERROR(); + } } + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &fbo); + */ + for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { + uint16 sourceMip = targetMip + mipDelta; + Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); + for (GLenum target : getFaceTargets(_target)) { + glCopyImageSubData( + oldId, target, sourceMip, 0, 0, 0, + _id, target, targetMip, 0, 0, 0, + mipDimensions.x, mipDimensions.y, 1 + ); + (void)CHECK_GL_ERROR(); + } + } + + glDeleteTextures(1, &oldId); } - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glDeleteFramebuffers(1, &fbo); - glDeleteTextures(1, &oldId); } // Re-sync the sampler to force access to the new mip level diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 5903be11d3..e4fc8420da 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -200,7 +200,7 @@ const QImage& image, bool isLinear, bool doCompress) { } } -#define CPU_MIPMAPS 0 +#define CPU_MIPMAPS 1 void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip) { #if CPU_MIPMAPS From e8cdee71ed5eef4b0e9106d38d27f0467a1dc4d7 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 3 Feb 2017 22:49:41 -0800 Subject: [PATCH 16/22] avoid assertion on mac --- interface/src/avatar/CauterizedModel.cpp | 4 ++-- libraries/fbx/src/FBXReader_Node.cpp | 4 +++- libraries/gpu/src/gpu/Image.cpp | 4 ++-- libraries/gpu/src/gpu/Image.h | 6 +++--- libraries/model/src/model/TextureMap.cpp | 4 ++-- libraries/render-utils/src/Model.cpp | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/CauterizedModel.cpp b/interface/src/avatar/CauterizedModel.cpp index 02107e9d24..f6b470f024 100644 --- a/interface/src/avatar/CauterizedModel.cpp +++ b/interface/src/avatar/CauterizedModel.cpp @@ -116,7 +116,7 @@ void CauterizedModel::updateClusterMatrices() { for (int j = 0; j < mesh.clusters.size(); j++) { const FBXCluster& cluster = mesh.clusters.at(j); auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); -#if GLM_ARCH & GLM_ARCH_SSE2 +#if (GLM_ARCH & GLM_ARCH_SSE2) && !(defined Q_OS_MACOS) glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix; glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); state.clusterMatrices[j] = out; @@ -155,7 +155,7 @@ void CauterizedModel::updateClusterMatrices() { if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) { jointMatrix = cauterizeMatrix; } -#if GLM_ARCH & GLM_ARCH_SSE2 +#if (GLM_ARCH & GLM_ARCH_SSE2) && !(defined Q_OS_MACOS) glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix; glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); state.clusterMatrices[j] = out; diff --git a/libraries/fbx/src/FBXReader_Node.cpp b/libraries/fbx/src/FBXReader_Node.cpp index 435c4d830b..61bd3321cb 100644 --- a/libraries/fbx/src/FBXReader_Node.cpp +++ b/libraries/fbx/src/FBXReader_Node.cpp @@ -62,7 +62,9 @@ template QVariant readBinaryArray(QDataStream& in, int& position) { position += sizeof(T) * arrayLength; in.readRawData(arrayData.data(), arrayData.size()); } - memcpy(&values[0], arrayData.constData(), arrayData.size()); + if (!arrayData.isEmpty()) { + memcpy(&values[0], arrayData.constData(), arrayData.size()); + } } else { values.reserve(arrayLength); const unsigned int DEFLATE_ENCODING = 1; diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp index 5de1008d8f..4d08307fbb 100644 --- a/libraries/gpu/src/gpu/Image.cpp +++ b/libraries/gpu/src/gpu/Image.cpp @@ -27,7 +27,7 @@ template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { auto c0 = bc1.color0.val; auto c1 = bc1.color1.val; - for (int i = 0; i < PB_RGB32::SIZE; ++i) { + for (int i = 0; i < PB_RGB32::LENGTH; ++i) { //dst.pixels[i] = ; auto r = pixel::mix( c0, @@ -44,4 +44,4 @@ template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst) { } -} \ No newline at end of file +} diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h index 67d2071c4a..e6dc944b3b 100644 --- a/libraries/gpu/src/gpu/Image.h +++ b/libraries/gpu/src/gpu/Image.h @@ -99,8 +99,8 @@ namespace image { using Format = typename P::Format; using Storage = typename P::Storage; - constexpr uint16_t getLength() const { return length; } - uint32_t getSize() const { return length * sizeof(P); } + static const uint32_t LENGTH { length }; + static const uint32_t SIZE { length * sizeof(P) }; P pixels[length]; @@ -112,7 +112,7 @@ namespace image { } void setPixels(const P* srcPixels) { - memcpy(pixels, srcPixels, getSize()); + memcpy(pixels, srcPixels, SIZE); } const Storage* getStorage() const { return static_cast (&pixels->raw); } diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 9f62c9abbc..7436306f3c 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -255,7 +255,7 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - image::PixRGB32 pix0; + /* image::PixRGB32 pix0; image::PixRGBA32 pix1; @@ -280,7 +280,7 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag image::uncompress(cb, pb1); image::Grid grid; - grid. + grid.*/ if (generateMips) { ::generateMips(theTexture, image, formatMip); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 018a7e6954..5da21f0487 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1183,7 +1183,7 @@ void Model::updateClusterMatrices() { for (int j = 0; j < mesh.clusters.size(); j++) { const FBXCluster& cluster = mesh.clusters.at(j); auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); -#if GLM_ARCH & GLM_ARCH_SSE2 +#if (GLM_ARCH & GLM_ARCH_SSE2) && !(defined Q_OS_MACOS) glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix; glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); state.clusterMatrices[j] = out; From 7b49f548ed191ab2a878fe80a0adfc2b3ad5f22e Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 7 Feb 2017 18:06:49 -0800 Subject: [PATCH 17/22] trying to remove the 24bits formats --- .../gpu-gl/src/gpu/gl/GLTextureTransfer.cpp | 1 - libraries/model/src/model/TextureMap.cpp | 29 ++++++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp index 179297069f..14c0a3923a 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp @@ -113,7 +113,6 @@ void GLTextureTransferHelper::queueExecution(VoidLambda lambda) { #define MAX_TRANSFERS_PER_PASS 2 bool GLTextureTransferHelper::process() { - PROFILE_RANGE(render_gpu_gl, __FUNCTION__) // Take any new textures or commands off the queue VoidLambdaList pendingCommands; TextureList newTransferTextures; diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index feca360531..e71616ebf7 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -334,15 +334,20 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src PROFILE_RANGE(resource_parse, "createNormalTextureFromNormalImage"); QImage image = processSourceImage(srcImage, false); - if (image.format() != QImage::Format_RGB888) { + /* if (image.format() != QImage::Format_RGB888) { image = image.convertToFormat(QImage::Format_RGB888); + }*/ + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); } gpu::Texture* theTexture = nullptr; if ((image.width() > 0) && (image.height() > 0)) { - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + // gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + // gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); @@ -378,7 +383,8 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm const double pStrength = 2.0; int width = image.width(); int height = image.height(); - QImage result(width, height, QImage::Format_RGB888); + //QImage result(width, height, QImage::Format_RGB888); + QImage result(width, height, QImage::Format_ARGB32); for (int i = 0; i < width; i++) { const int iNextClamped = clampPixelCoordinate(i + 1, width - 1); @@ -426,8 +432,11 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm gpu::Texture* theTexture = nullptr; if ((image.width() > 0) && (image.height() > 0)) { - gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); - gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + + // gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + // gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); @@ -810,10 +819,14 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm gpu::Texture* theTexture = nullptr; if ((srcImage.width() > 0) && (srcImage.height() > 0)) { QImage image = processSourceImage(srcImage, true); - if (image.format() != QImage::Format_RGB888) { - image = image.convertToFormat(QImage::Format_RGB888); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); } + /* if (image.format() != QImage::Format_RGB888) { + image = image.convertToFormat(QImage::Format_RGB888); + }*/ + gpu::Element formatGPU; gpu::Element formatMip; defineColorTexelFormats(formatGPU, formatMip, image, isLinear, doCompress); From a137659a35f0d94bbcb255b72ad7d8e795f288ad Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 8 Feb 2017 11:13:55 -0800 Subject: [PATCH 18/22] Cleaning up pr for simpler merge --- libraries/gpu/src/gpu/Image.cpp | 43 -- libraries/gpu/src/gpu/Image.h | 492 ----------------------- libraries/model/src/model/TextureMap.cpp | 54 +-- 3 files changed, 3 insertions(+), 586 deletions(-) delete mode 100644 libraries/gpu/src/gpu/Image.cpp delete mode 100644 libraries/gpu/src/gpu/Image.h diff --git a/libraries/gpu/src/gpu/Image.cpp b/libraries/gpu/src/gpu/Image.cpp deleted file mode 100644 index 825803a7d9..0000000000 --- a/libraries/gpu/src/gpu/Image.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "Image.h" - - -int image::BC::cpp { 0 }; - -namespace image { - - namespace pixel { - template <> const RGB16_565 mix(const RGB16_565 p0, const RGB16_565 p1, const Byte alpha) { - return RGB16_565( - mix5_4(p0.r, p1.r, alpha), - mix6_4(p0.g, p1.g, alpha), - mix5_4(p0.b, p1.b, alpha)); - } - } - -template <> void compress(const PB_RGB32& src, CB_BC1& dst) { -} - -template <> void uncompress(const CB_BC1& src, PB_RGB32& dst) { - auto bc1 = src.bc; - - auto c0 = bc1.color0.val; - auto c1 = bc1.color1.val; - - for (int i = 0; i < PB_RGB32::LENGTH; ++i) { - //dst.pixels[i] = ; - auto r = pixel::mix( - c0, - c1, - (Byte)bc1.table); - } -} - -template <> void compress(const PB_RGBA32& src, CB_BC4& dst) { - -} - -template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst) { - -} - -} diff --git a/libraries/gpu/src/gpu/Image.h b/libraries/gpu/src/gpu/Image.h deleted file mode 100644 index fd59406975..0000000000 --- a/libraries/gpu/src/gpu/Image.h +++ /dev/null @@ -1,492 +0,0 @@ -/* - Let s try compressing images - -*/ - -#include -#include "Forward.h" - - -namespace image { - - // Storage types - using Byte = uint8_t; - using Byte2 = uint16_t; - using Byte4 = uint32_t; - using Byte8 = uint64_t; - - // Storage type selector based on size (sizeof of a type) - template - struct storage { typedef T1 type; }; - - template - struct storage<2, T1, T2, T4, T8> { typedef T2 type; }; - - template - struct storage<4, T1, T2, T4, T8> { typedef T4 type; }; - - template - struct storage<8, T1, T2, T4, T8> { typedef T8 type; }; - - static const Byte BLACK8 { 0 }; - static const Byte WHITE8 { 255 }; - - template int bitVal() { return 1 << N; } - template int bitProduct() { return bitVal() * bitVal(); } - template T mix(const T x, const T y, const A a) { return T(((bitVal() - a) * x + a * y) / bitProduct()); } - - Byte mix5_4(const Byte x, const Byte y, const Byte a) { return mix<5, 4>(x, y, a); } - Byte mix6_4(const Byte x, const Byte y, const Byte a) { return mix<6, 4>(x, y, a); } - - - - // Coordinate and count types - using Coord = uint16_t; - using Coord2 = glm::u16vec2; - using Count = uint32_t; - using Index = uint32_t; - - // Maximum pixel along one direction coord is 32768 - static const Coord MAX_COORD { 32768 }; - // Maximum number of pixels in an image - static const Count MAX_COUNT { MAX_COORD * MAX_COORD }; - static const Index MAX_INDEX { MAX_COUNT }; - - - namespace pixel { - - struct RGB32 { - Byte r { BLACK8 }; - Byte g { BLACK8 }; - Byte b { BLACK8 }; - Byte x { WHITE8 }; - }; - - struct RGBA32 { - Byte r { BLACK8 }; - Byte g { BLACK8 }; - Byte b { BLACK8 }; - Byte a { WHITE8 }; - }; - - struct R10G10B12 { - Byte4 r : 10; - Byte4 g : 10; - Byte4 b : 12; - }; - - struct RGB16_565 { - Byte2 b : 5; - Byte2 g : 6; - Byte2 r : 5; - - RGB16_565() : b(BLACK8), g(BLACK8), r(BLACK8) {} - RGB16_565(Byte pR, Byte pG, Byte pB) : b(pB), g(pG), r(pR) {} - }; - - struct R8 { - Byte r { BLACK8 }; - }; - - - template const P mix(const P p0, const P p1, const S alpha) { return p0; } - template <> const RGB16_565 mix(const RGB16_565 p0, const RGB16_565 p1, const Byte alpha); - - template ::type > class Pixel { - public: - using This = Pixel; - using Format = F; - using Storage = S; - - static const uint32_t SIZE { sizeof(S) }; - - Format val { Format() }; - - Pixel() : val(Format()) {}; - Pixel(Format v) : val(v) {} - Pixel(Storage s) : val(*static_cast (&s)) {} - - const Storage* storage() const { return static_cast (&val); } - - static This* cast(Storage* s) { return reinterpret_cast(s); } - static const This* cast(const Storage* s) { return reinterpret_cast(s); } - }; - - template class PixelBlock { - public: - using Format = typename P::Format; - using Storage = typename P::Storage; - - static const uint16_t LENGTH { length }; - static const uint32_t SIZE { length * sizeof(P) }; - - P pixels[length]; - - PixelBlock() {} - - PixelBlock(const P* srcPixels) { - setPixels(srcPixels); - } - - void setPixels(const P* srcPixels) { - memcpy(pixels, srcPixels, SIZE); - } - - const Storage* storage() const { return pixels->storage(); } - }; - - template class Tile { - public: - using Format = typename P::Format; - using Storage = typename P::Storage; - - using Block = PixelBlock; - - uint16_t getWidth() const { return tileW; } - uint16_t getHeight() const { return tileH; } - - Block _block; - - Tile() {} - Tile(const P* srcPixels) : _block(srcPixels) {} - - - }; - }; - - - - using PixRGB565 = pixel::Pixel; - using PixRGB32 = pixel::Pixel; - using PixRGBA32 = pixel::Pixel; - using PixR10G10B12 = pixel::Pixel; - using PixR8 = pixel::Pixel; - - - class BC { - public: - static int cpp; - - struct BC1 { - PixRGB565 color0; - PixRGB565 color1; - Byte4 table; - }; - - struct BC4 { - PixRGB565 color0; - PixRGB565 color1; - Byte4 table; - }; - }; - - template ::type> class CompressedBlock { - public: - using Format = F; - using Storage = S; - - static const uint32_t SIZE { sizeof(F) }; - - Format bc; - - CompressedBlock() {} - - const Storage* storage() const { return static_cast (&bc); } - }; - - - template void compress(const PB& srcBlock, CB& dstBlock) { } - template void uncompress(const CB& srcBlock, PB& dstBlock) { } - - - using PB_RGB32 = pixel::PixelBlock; - using PB_RGBA32 = pixel::PixelBlock; - - using CB_BC1 = CompressedBlock; - using CB_BC4 = CompressedBlock; - - template <> void compress(const PB_RGB32& src, CB_BC1& dst); - template <> void compress(const PB_RGBA32& src, CB_BC4& dst); - - template <> void uncompress(const CB_BC1& src, PB_RGB32& dst); - template <> void uncompress(const CB_BC4& src, PB_RGBA32& dst); - - - template - class PixelArray { - public: - using This = PixelArray

; - using Pixel = P; - using Storage = typename P::Storage; - - static int evalNumPixels(size_t byteSize) { - size_t numPixels = byteSize / Pixel::SIZE; - if (byteSize > numPixels * Pixel::SIZE) { - numPixels++; - } - return (int)numPixels; - }; - static size_t evalByteSize(int numPixels) { - return numPixels * Pixel::SIZE; - }; - - struct Storages { - Storage* _bytes {nullptr}; - Count _count {0}; - - Storage* data() { - return _bytes; - } - const Storage* data() const { - return _bytes; - } - - Count count() const { return _count; } - - ~Storages() { if (_bytes) { delete _bytes; } } - Storages() {} - Storages(Count c) : _count(c) { if (_count) { _bytes = new Storage[_count]; } - - } - }; - - - - PixelArray() { - resetBytes(0, nullptr); - } - PixelArray(size_t byteSize, const void* bytes) { - resetBytes(byteSize, bytes); - } - PixelArray(const PixelArray& src) { - resetBytes(src.byteSize(), src.readBytes(0)); - } - PixelArray(PixelArray&& src) { - _buffer.reset(src._buffer.release()); - } - This& operator = (This&& src) { - _buffer.reset(src._buffer.release()); - } - - int numPixels() const { return _buffer->count(); } - size_t byteSize() const { return evalByteSize(_buffer->count()); } - - //access storage or pixel types at index in the buffer - const Storage* readBytes(const Index index) const { return _buffer->data() + index; } - const Pixel* readPixel(const Index index) const { return Pixel::cast(readBytes(index)); } - - Storage* editBytes(const Index index) { return _buffer->data() + index; } - Pixel* editPixel(const Index index) { return Pixel::cast(editBytes(index)); } - - private: - std::unique_ptr _buffer; - - void resetBytes(size_t byteSize, const void* bytes) { - _buffer.reset(new Storages(evalNumPixels(byteSize))); - if (bytes) { - memcpy(_buffer->data(), bytes, byteSize); - } - } - }; - - template - class PixelBlockArray { - public: - using Block = B; - using Blocks = std::vector; - - static int evalNumBlocks(size_t byteSize) { - size_t numBlocks = byteSize / Block::SIZE; - if (byteSize > numBlocks * Block::SIZE) { - numBlocks++; - } - return (int) numBlocks; - }; - static size_t evalByteSize(int numBlocks) { - return numBlocks * Block::SIZE; - }; - - PixelBlockArray(size_t byteSize, const void* bytes) { - setBytes(byteSize, bytes); - } - - int numBlocks() const { return evalByteSize(_blocks.size()); } - size_t byteSize() const { return evalByteSize(_blocks.size()); } - - Blocks _blocks; - - private: - void setBytes(size_t byteSize, const void* bytes) { - _blocks = Blocks(evalNumBlocks(byteSize)); - if (bytes) { - memcpy(_blocks.data(), bytes, byteSize); - } - } - }; - - class Grid { - public: - using Coord = uint16_t; - using Coord2 = glm::u16vec2; - using Size = uint32_t; - - static const Coord2 TILE_PIXEL; - static const Coord2 TILE_QUAD; - static const Coord2 TILE_DEFAULT; - - Grid(const Coord2& surface, const Coord2& tile = TILE_DEFAULT) : _surface(surface), _tile(tile) {} - Grid(Coord width, Coord height, const Coord2& tile = TILE_DEFAULT) : _surface(width, height), _tile(tile) {} - - Coord2 _surface { 1, 1 }; - Coord2 _tile { TILE_DEFAULT }; - - Coord width() const { return _surface.x; } - Coord height() const { return _surface.y; } - const Coord2& size() const { return _surface; } - - Coord tileWidth() const { return evalNumTiles(_surface.x, _tile.x); } - Coord tileHeight() const { return evalNumTiles(_surface.y, _tile.y); } - Coord2 tileSize() const { return Coord2(tileWidth(), tileHeight()); } - - - Coord2 toTile(const Coord2& pixel) const { return pixel / _tile; } - Coord2 toTileSubpix(const Coord2& pixel) const { return pixel % _tile; } - Coord2 toTile(const Coord2& pixel, Coord2& subpix) const { - subpix = toTileSubpix(pixel); - return toTile(pixel); - } - - Coord2 toPixel(const Coord2& tile) const { return tile * _tile; } - Coord2 toPixel(const Coord2& tile, const Coord2& subpix) const { return tile * _tile + subpix; } - - - static Coord evalNumTiles(Coord pixelLength, Coord tileLength) { - auto tilePos = pixelLength / tileLength; - if (tilePos * tileLength < pixelLength) { - tilePos++; - } - return tilePos; - } - }; - - template - class Tilemap { - public: - using Tile = T; - using Block = typename T::Block; - - Grid _grid; - PixelBlockArray _blocks; - - void resize(const Grid::Coord2& widthHeight) { - _grid = Grid(widthHeight, Coord2(Tile::getWidth(), Tile::getHeight())); - - } - - }; - - class Dim { - public: - - Coord2 _dims { 0 }; - - static Coord cap(Coord c) { return (c < MAX_COORD ? c : MAX_COORD); } - static Coord2 cap(const Coord2& dims) { return Coord2(cap(dims.x), cap(dims.y)); } - - static Count numPixels(const Coord2& dims) { return Count(cap(dims.x)) * Count(cap(dims.y)); } - - - static Coord nextMip(Coord c) { return (c > 1 ? (c >> 1) : c); } - static Coord2 nextMip(const Coord2& dims) { return Coord2(nextMip(dims.x), nextMip(dims.y)); } - - Dim(Coord w, Coord h) : _dims(w, h) {} - Dim(const Coord2& dims) : _dims(dims) {} - - Count numPixels() const { return Dim::numPixels(_dims); } - Dim nextMip() const { return Dim(nextMip(_dims)); } - - int maxLevel() const { - int level = 0; - auto dim = (*this); - while (dim._dims.x > 1 || dim._dims.y > 1) { - level++; - dim = dim.nextMip(); - } - return level; - } - - Index indexAt(Coord x, Coord y) const { return (Index) y * (Index) _dims.x + (Index) x; } - }; - - template < typename P > class Surface { - public: - using This = Surface

; - using Pixel = P; - using Format = typename P::Format; - using Pixels = PixelArray

; - - Dim _dim { 0, 0 }; - Pixels _pixels; - - /* Surface(This&& src) { - _dim = src._dim; - _pixels = src._pixels; - - }*/ - Surface(Coord width, Coord height, size_t byteSize = 0, const void* bytes = nullptr) : - _dim(width, height), - _pixels((byteSize ? byteSize : Pixels::evalByteSize(width * height)), bytes) - {} - - This nextMip() const { - Dim subDim = _dim.nextMip(); - auto sub = Surface

(subDim._dims.x, subDim._dims.y); - - for (int y = 0; y < subDim._dims.y; y++) { - for (int x = 0; x < subDim._dims.x; x++) { - - // get pixels from source at 2x, 2x +1 2y, 2y +1 - auto srcIndex0 = _dim.indexAt(2 * x, 2 * y); - auto srcIndex1 = _dim.indexAt(2 * x, 2 * y + 1); - - auto srcP0 = (*_pixels.readPixel(srcIndex0)); - auto srcP01 = (*_pixels.readPixel(srcIndex0 + 1)); - auto srcP1 = (*_pixels.readPixel(srcIndex1)); - auto srcP11 = (*_pixels.readPixel(srcIndex1 + 1)); - - // and filter - auto destIndex = subDim.indexAt(x, y); - auto destP = sub._pixels.editPixel(destIndex); - - // assign to dest - *destP = srcP0; - } - } - return sub; - } - - void downsample(std::vector& mips, int num) const { - if (num == 0) { - return; - } - auto maxLevel = _dim.maxLevel(); - - if (num == -1 || num > maxLevel) { - num = maxLevel; - } - else if (num < -1) { - return; - } - - - mips.emplace_back(nextMip()); - - for (int i = 1; i < num; i++) { - mips.emplace_back(mips.back().nextMip()); - } - - } - - }; -} - diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index e71616ebf7..97005b2b01 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -17,7 +17,6 @@ #include #include "ModelLogging.h" -#include using namespace model; using namespace gpu; @@ -142,7 +141,7 @@ const QImage TextureUsage::process2DImageColor(const QImage& srcImage, bool& val validAlpha = (numOpaques != NUM_PIXELS); } - //if (!validAlpha && image.format() != QImage::Format_RGB888) { + // Force all the color images to be rgba32bits if (image.format() != QImage::Format_ARGB32) { image = image.convertToFormat(QImage::Format_ARGB32); } @@ -255,57 +254,10 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag } theTexture->setUsage(usage.build()); - - /* image::PixRGB32 pix0; - - image::PixRGBA32 pix1; - - image::PixR8 pix2; - - image::PixRGB565 pix3; - - image::PB_RGB32 pb0; - image::PB_RGB32 pb1; - - auto pix0_s = sizeof(pix0); - auto pix1_s = sizeof(pix1); - auto pix2_s = sizeof(pix2); - auto pix3_s = sizeof(pix3); - - auto pb0_s = sizeof(pb0); - -*/ - - bool check = false; - if (image.width() == 2048) { - check = true; - } - image::Surface surface(image.width(), image.height(), image.byteCount(), image.constBits()); - - - theTexture->assignStoredMip(0, formatMip, surface._pixels.byteSize(), (const Byte *) surface._pixels.readBytes(0)); - - - // theMap(image.width(), image.height(), image.byteCount(), image.constBits()); + theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); if (generateMips) { - - { - - PROFILE_RANGE(resource_parse, "generateMipsSAM"); - auto numMips = theTexture->evalNumMips(); - - std::vector> mips; - - surface.downsample(mips, numMips); - - for (uint16 level = 1; level < numMips && (mips.size() <= level); ++level) { - - const auto& m = mips[level - 1]; - theTexture->assignStoredMip(level, formatMip, m._pixels.byteSize(), (const Byte *) m._pixels.readBytes(0)); - } - } - // ::generateMips(theTexture, image, formatMip); + ::generateMips(theTexture, image, formatMip); } } From 8a40e951ac21dc7cd2f349ae5db0f2866d015096 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 8 Feb 2017 11:35:50 -0800 Subject: [PATCH 19/22] clean the usage of glCopyImageSubData and provide a fall back for 4.2) --- .../src/gpu/gl45/GL45BackendTexture.cpp | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 37d238f95c..8ba90f447e 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -438,34 +438,36 @@ void GL45Texture::stripToMip(uint16_t newMinMip) { // Copy the contents of the old texture to the new { PROFILE_RANGE(render_gpu_gl, "Blit"); - /* - GLuint fbo { 0 }; - glCreateFramebuffers(1, &fbo); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); - for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { - uint16 sourceMip = targetMip + mipDelta; - Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); - for (GLenum target : getFaceTargets(_target)) { - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip); - (void)CHECK_GL_ERROR(); - glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y); - (void)CHECK_GL_ERROR(); + // Preferred path only available in 4.3 + if (GLEW_VERSION_4_3) { + for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { + uint16 sourceMip = targetMip + mipDelta; + Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); + for (GLenum target : getFaceTargets(_target)) { + glCopyImageSubData( + oldId, target, sourceMip, 0, 0, 0, + _id, target, targetMip, 0, 0, 0, + mipDimensions.x, mipDimensions.y, 1 + ); + (void)CHECK_GL_ERROR(); + } } - } - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glDeleteFramebuffers(1, &fbo); - */ - for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { - uint16 sourceMip = targetMip + mipDelta; - Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); - for (GLenum target : getFaceTargets(_target)) { - glCopyImageSubData( - oldId, target, sourceMip, 0, 0, 0, - _id, target, targetMip, 0, 0, 0, - mipDimensions.x, mipDimensions.y, 1 - ); - (void)CHECK_GL_ERROR(); + } else { + GLuint fbo { 0 }; + glCreateFramebuffers(1, &fbo); + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { + uint16 sourceMip = targetMip + mipDelta; + Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); + for (GLenum target : getFaceTargets(_target)) { + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip); + (void)CHECK_GL_ERROR(); + glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y); + (void)CHECK_GL_ERROR(); + } } + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &fbo); } glDeleteTextures(1, &oldId); From 9e959441954412746af577a3d57f9d2e174402dd Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 8 Feb 2017 11:36:34 -0800 Subject: [PATCH 20/22] clean the usage of glCopyImageSubData and provide a fall back for 4.2) --- .../src/gpu/gl45/GL45BackendTexture.cpp | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 8ba90f447e..6948a045a2 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -439,35 +439,17 @@ void GL45Texture::stripToMip(uint16_t newMinMip) { { PROFILE_RANGE(render_gpu_gl, "Blit"); // Preferred path only available in 4.3 - if (GLEW_VERSION_4_3) { - for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { - uint16 sourceMip = targetMip + mipDelta; - Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); - for (GLenum target : getFaceTargets(_target)) { - glCopyImageSubData( - oldId, target, sourceMip, 0, 0, 0, - _id, target, targetMip, 0, 0, 0, - mipDimensions.x, mipDimensions.y, 1 - ); - (void)CHECK_GL_ERROR(); - } + for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { + uint16 sourceMip = targetMip + mipDelta; + Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); + for (GLenum target : getFaceTargets(_target)) { + glCopyImageSubData( + oldId, target, sourceMip, 0, 0, 0, + _id, target, targetMip, 0, 0, 0, + mipDimensions.x, mipDimensions.y, 1 + ); + (void)CHECK_GL_ERROR(); } - } else { - GLuint fbo { 0 }; - glCreateFramebuffers(1, &fbo); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); - for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { - uint16 sourceMip = targetMip + mipDelta; - Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); - for (GLenum target : getFaceTargets(_target)) { - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip); - (void)CHECK_GL_ERROR(); - glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y); - (void)CHECK_GL_ERROR(); - } - } - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glDeleteFramebuffers(1, &fbo); } glDeleteTextures(1, &oldId); From 267d553c2639c190f3a123d7bab2441d3ea4cfb5 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 8 Feb 2017 11:42:23 -0800 Subject: [PATCH 21/22] Cleaning comments and pixel format assignments --- libraries/model/src/model/TextureMap.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 97005b2b01..839a704e54 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -286,18 +286,14 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src PROFILE_RANGE(resource_parse, "createNormalTextureFromNormalImage"); QImage image = processSourceImage(srcImage, false); - /* if (image.format() != QImage::Format_RGB888) { - image = image.convertToFormat(QImage::Format_RGB888); - }*/ + // Make sure the normal map source image is RGBA32 if (image.format() != QImage::Format_ARGB32) { image = image.convertToFormat(QImage::Format_ARGB32); } gpu::Texture* theTexture = nullptr; if ((image.width() > 0) && (image.height() > 0)) { - - // gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); - // gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); + gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); @@ -335,7 +331,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm const double pStrength = 2.0; int width = image.width(); int height = image.height(); - //QImage result(width, height, QImage::Format_RGB888); + // THe end result image for normal map is RGBA32 even though the A is not used QImage result(width, height, QImage::Format_ARGB32); for (int i = 0; i < width; i++) { @@ -384,9 +380,6 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm gpu::Texture* theTexture = nullptr; if ((image.width() > 0) && (image.height() > 0)) { - - // gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); - // gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); @@ -775,10 +768,6 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm image = image.convertToFormat(QImage::Format_ARGB32); } - /* if (image.format() != QImage::Format_RGB888) { - image = image.convertToFormat(QImage::Format_RGB888); - }*/ - gpu::Element formatGPU; gpu::Element formatMip; defineColorTexelFormats(formatGPU, formatMip, image, isLinear, doCompress); From e11d10f5d4bdf8219fe3dde27ba17c13ff31946e Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 8 Feb 2017 16:56:59 -0800 Subject: [PATCH 22/22] Reparing broken normals and also fixing the ambient lighting bug --- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 4 ++-- .../gpu-gl/src/gpu/gl/GLBackendPipeline.cpp | 2 +- .../gpu-gl/src/gpu/gl/GLBackendState.cpp | 24 +++++++++++++++---- .../gpu-gl/src/gpu/gl/GLTextureTransfer.cpp | 2 +- libraries/model/src/model/TextureMap.cpp | 20 ++++++++-------- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index dbfe8fe730..c51f468908 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -328,12 +328,12 @@ void GLBackend::render(const Batch& batch) { void GLBackend::syncCache() { + PROFILE_RANGE(render_gpu_gl_detail, __FUNCTION__); + syncTransformStateCache(); syncPipelineStateCache(); syncInputStateCache(); syncOutputStateCache(); - - glEnable(GL_LINE_SMOOTH); } #ifdef GPU_STEREO_DRAWCALL_DOUBLED diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp index 81d38c3339..8aab6abaa9 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp @@ -1,4 +1,4 @@ -// +// // GLBackendPipeline.cpp // libraries/gpu/src/gpu // diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp index 6f8c229184..a7d4a7ff7c 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp @@ -28,11 +28,8 @@ void GLBackend::resetPipelineState(State::Signature nextSignature) { } } } -} - -void GLBackend::syncPipelineStateCache() { - State::Data state; + // force a few states regardless glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Point size is always on @@ -43,6 +40,25 @@ void GLBackend::syncPipelineStateCache() { // Default line width accross the board glLineWidth(1.0f); + glEnable(GL_LINE_SMOOTH); + +} + +void GLBackend::syncPipelineStateCache() { + State::Data state; + + // force a few states regardless + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + + // Point size is always on + // FIXME CORE + //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + glEnable(GL_PROGRAM_POINT_SIZE_EXT); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + + // Default line width accross the board + glLineWidth(1.0f); + glEnable(GL_LINE_SMOOTH); getCurrentGLState(state); State::Signature signature = State::evalSignature(state); diff --git a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp index 14c0a3923a..9dac2986e3 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp @@ -151,7 +151,7 @@ bool GLTextureTransferHelper::process() { #endif return true; } - PROFILE_COUNTER_IF_CHANGED(render_gpu_gl, "transferringTextures", size_t, _transferringTextures.size()) + PROFILE_COUNTER_IF_CHANGED(render_gpu_gl, "transferringTextures", int, (int) _transferringTextures.size()) static auto lastReport = usecTimestampNow(); auto now = usecTimestampNow(); diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 839a704e54..db87950e5a 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -143,7 +143,7 @@ const QImage TextureUsage::process2DImageColor(const QImage& srcImage, bool& val // Force all the color images to be rgba32bits if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); + image = image.convertToFormat(QImage::Format_ARGB32); } return image; @@ -287,8 +287,8 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src QImage image = processSourceImage(srcImage, false); // Make sure the normal map source image is RGBA32 - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); + if (image.format() != QImage::Format_RGBA8888) { + image = image.convertToFormat(QImage::Format_RGBA8888); } gpu::Texture* theTexture = nullptr; @@ -332,7 +332,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm int width = image.width(); int height = image.height(); // THe end result image for normal map is RGBA32 even though the A is not used - QImage result(width, height, QImage::Format_ARGB32); + QImage result(width, height, QImage::Format_RGBA8888); for (int i = 0; i < width; i++) { const int iNextClamped = clampPixelCoordinate(i + 1, width - 1); @@ -400,8 +400,8 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma image = image.convertToFormat(QImage::Format_RGB888); } } else { - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); + if (image.format() != QImage::Format_RGBA8888) { + image = image.convertToFormat(QImage::Format_RGBA8888); } } @@ -435,8 +435,8 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s image = image.convertToFormat(QImage::Format_RGB888); } } else { - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); + if (image.format() != QImage::Format_RGBA8888) { + image = image.convertToFormat(QImage::Format_RGBA8888); } } @@ -474,8 +474,8 @@ gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImag image = image.convertToFormat(QImage::Format_RGB888); } } else { - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); + if (image.format() != QImage::Format_RGBA8888) { + image = image.convertToFormat(QImage::Format_RGBA8888); } }