summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2016-05-19 17:15:51 +0200
committerPaul Lemire <paul.lemire@kdab.com>2016-05-20 12:16:34 +0000
commit2fc9cba25793170faa81c10c531c7d2ec1b3a382 (patch)
tree9deaa20c6db4a5e24875df88ecaab75770557c88 /src
parenta2999182a07a94ee6124de8e970596002e5e9078 (diff)
QTexture: cleanup
Load compressed files in QFromSourceTextureGenerator and remove related code from QTextureImageData. Unify loading code paths for texture generator and image. Change-Id: Iebeb67bf1e542f55af06880b1d725c2de70b8ccb Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/render/jobs/loadtexturedatajob.cpp2
-rw-r--r--src/render/texture/qtexture.cpp676
-rw-r--r--src/render/texture/qtexture_p.h6
-rw-r--r--src/render/texture/qtextureimage.cpp20
-rw-r--r--src/render/texture/qtextureimage_p.h41
-rw-r--r--src/render/texture/qtextureimagedata.cpp645
-rw-r--r--src/render/texture/qtextureimagedata.h30
-rw-r--r--src/render/texture/qtextureimagedata_p.h3
-rw-r--r--src/render/texture/texture.cpp3
9 files changed, 756 insertions, 670 deletions
diff --git a/src/render/jobs/loadtexturedatajob.cpp b/src/render/jobs/loadtexturedatajob.cpp
index 65bcd70bc..d8243f1d0 100644
--- a/src/render/jobs/loadtexturedatajob.cpp
+++ b/src/render/jobs/loadtexturedatajob.cpp
@@ -103,11 +103,9 @@ void createTextureFromGenerator(TextureDataManager *textureDataManager,
qWarning() << "When a texture provides a generator, it's target is expected to be TargetAutomatic";
texture->setTarget(static_cast<QAbstractTexture::Target>(generatedData->target()));
-
texture->setSize(generatedData->width(), generatedData->height(), generatedData->depth());
texture->setLayers(generatedData->layers());
texture->setFormat(generatedData->format());
- texture->setFormat(static_cast<QAbstractTexture::TextureFormat>(generatedData->format()));
// Note: These texture data handles aren't associated with a QTextureImageDataGenerator
// and will therefore be destroyed when the Texture element is destroyed or cleaned up
diff --git a/src/render/texture/qtexture.cpp b/src/render/texture/qtexture.cpp
index c2f243f57..9ffb10a88 100644
--- a/src/render/texture/qtexture.cpp
+++ b/src/render/texture/qtexture.cpp
@@ -43,11 +43,637 @@
#include "qtexturedata.h"
#include "qtexture.h"
#include "qtexture_p.h"
+#include <QFileInfo>
+#include <qendian.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+namespace {
+
+struct DdsPixelFormat
+{
+ quint32 size;
+ quint32 flags;
+ quint32 fourCC;
+ quint32 rgbBitCount;
+ quint32 redMask;
+ quint32 greenMask;
+ quint32 blueMask;
+ quint32 alphaMask;
+};
+
+struct DdsHeader
+{
+ char magic[4];
+ quint32 size;
+ quint32 flags;
+ quint32 height;
+ quint32 width;
+ quint32 pitchOrLinearSize;
+ quint32 depth;
+ quint32 mipmapCount;
+ quint32 reserved[11];
+ DdsPixelFormat pixelFormat;
+ quint32 caps;
+ quint32 caps2;
+ quint32 caps3;
+ quint32 caps4;
+ quint32 reserved2;
+};
+
+struct DdsDX10Header
+{
+ quint32 format;
+ quint32 dimension;
+ quint32 miscFlag;
+ quint32 arraySize;
+ quint32 miscFlags2;
+};
+
+enum DdsFlags
+{
+ MipmapCountFlag = 0x20000,
+};
+
+enum PixelFormatFlag
+{
+ AlphaFlag = 0x1,
+ FourCCFlag = 0x4,
+ RGBFlag = 0x40,
+ RGBAFlag = RGBFlag | AlphaFlag,
+ YUVFlag = 0x200,
+ LuminanceFlag = 0x20000
+};
+
+enum Caps2Flags
+{
+ CubemapFlag = 0x200,
+ CubemapPositiveXFlag = 0x400,
+ CubemapNegativeXFlag = 0x800,
+ CubemapPositiveYFlag = 0x1000,
+ CubemapNegativeYFlag = 0x2000,
+ CubemapPositiveZFlag = 0x4000,
+ CubemapNegativeZFlag = 0x8000,
+ AllCubemapFaceFlags = CubemapPositiveXFlag |
+ CubemapNegativeXFlag |
+ CubemapPositiveYFlag |
+ CubemapNegativeYFlag |
+ CubemapPositiveZFlag |
+ CubemapNegativeZFlag,
+ VolumeFlag = 0x200000
+};
+
+enum DXGIFormat
+{
+ DXGI_FORMAT_UNKNOWN = 0,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
+ DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
+ DXGI_FORMAT_R32G32B32A32_UINT = 3,
+ DXGI_FORMAT_R32G32B32A32_SINT = 4,
+ DXGI_FORMAT_R32G32B32_TYPELESS = 5,
+ DXGI_FORMAT_R32G32B32_FLOAT = 6,
+ DXGI_FORMAT_R32G32B32_UINT = 7,
+ DXGI_FORMAT_R32G32B32_SINT = 8,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
+ DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
+ DXGI_FORMAT_R16G16B16A16_UNORM = 11,
+ DXGI_FORMAT_R16G16B16A16_UINT = 12,
+ DXGI_FORMAT_R16G16B16A16_SNORM = 13,
+ DXGI_FORMAT_R16G16B16A16_SINT = 14,
+ DXGI_FORMAT_R32G32_TYPELESS = 15,
+ DXGI_FORMAT_R32G32_FLOAT = 16,
+ DXGI_FORMAT_R32G32_UINT = 17,
+ DXGI_FORMAT_R32G32_SINT = 18,
+ DXGI_FORMAT_R32G8X24_TYPELESS = 19,
+ DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
+ DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
+ DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
+ DXGI_FORMAT_R10G10B10A2_UNORM = 24,
+ DXGI_FORMAT_R10G10B10A2_UINT = 25,
+ DXGI_FORMAT_R11G11B10_FLOAT = 26,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
+ DXGI_FORMAT_R8G8B8A8_UNORM = 28,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
+ DXGI_FORMAT_R8G8B8A8_UINT = 30,
+ DXGI_FORMAT_R8G8B8A8_SNORM = 31,
+ DXGI_FORMAT_R8G8B8A8_SINT = 32,
+ DXGI_FORMAT_R16G16_TYPELESS = 33,
+ DXGI_FORMAT_R16G16_FLOAT = 34,
+ DXGI_FORMAT_R16G16_UNORM = 35,
+ DXGI_FORMAT_R16G16_UINT = 36,
+ DXGI_FORMAT_R16G16_SNORM = 37,
+ DXGI_FORMAT_R16G16_SINT = 38,
+ DXGI_FORMAT_R32_TYPELESS = 39,
+ DXGI_FORMAT_D32_FLOAT = 40,
+ DXGI_FORMAT_R32_FLOAT = 41,
+ DXGI_FORMAT_R32_UINT = 42,
+ DXGI_FORMAT_R32_SINT = 43,
+ DXGI_FORMAT_R24G8_TYPELESS = 44,
+ DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
+ DXGI_FORMAT_R8G8_TYPELESS = 48,
+ DXGI_FORMAT_R8G8_UNORM = 49,
+ DXGI_FORMAT_R8G8_UINT = 50,
+ DXGI_FORMAT_R8G8_SNORM = 51,
+ DXGI_FORMAT_R8G8_SINT = 52,
+ DXGI_FORMAT_R16_TYPELESS = 53,
+ DXGI_FORMAT_R16_FLOAT = 54,
+ DXGI_FORMAT_D16_UNORM = 55,
+ DXGI_FORMAT_R16_UNORM = 56,
+ DXGI_FORMAT_R16_UINT = 57,
+ DXGI_FORMAT_R16_SNORM = 58,
+ DXGI_FORMAT_R16_SINT = 59,
+ DXGI_FORMAT_R8_TYPELESS = 60,
+ DXGI_FORMAT_R8_UNORM = 61,
+ DXGI_FORMAT_R8_UINT = 62,
+ DXGI_FORMAT_R8_SNORM = 63,
+ DXGI_FORMAT_R8_SINT = 64,
+ DXGI_FORMAT_A8_UNORM = 65,
+ DXGI_FORMAT_R1_UNORM = 66,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
+ DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
+ DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
+ DXGI_FORMAT_BC1_TYPELESS = 70,
+ DXGI_FORMAT_BC1_UNORM = 71,
+ DXGI_FORMAT_BC1_UNORM_SRGB = 72,
+ DXGI_FORMAT_BC2_TYPELESS = 73,
+ DXGI_FORMAT_BC2_UNORM = 74,
+ DXGI_FORMAT_BC2_UNORM_SRGB = 75,
+ DXGI_FORMAT_BC3_TYPELESS = 76,
+ DXGI_FORMAT_BC3_UNORM = 77,
+ DXGI_FORMAT_BC3_UNORM_SRGB = 78,
+ DXGI_FORMAT_BC4_TYPELESS = 79,
+ DXGI_FORMAT_BC4_UNORM = 80,
+ DXGI_FORMAT_BC4_SNORM = 81,
+ DXGI_FORMAT_BC5_TYPELESS = 82,
+ DXGI_FORMAT_BC5_UNORM = 83,
+ DXGI_FORMAT_BC5_SNORM = 84,
+ DXGI_FORMAT_B5G6R5_UNORM = 85,
+ DXGI_FORMAT_B5G5R5A1_UNORM = 86,
+ DXGI_FORMAT_B8G8R8A8_UNORM = 87,
+ DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+ DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+ DXGI_FORMAT_BC6H_TYPELESS = 94,
+ DXGI_FORMAT_BC6H_UF16 = 95,
+ DXGI_FORMAT_BC6H_SF16 = 96,
+ DXGI_FORMAT_BC7_TYPELESS = 97,
+ DXGI_FORMAT_BC7_UNORM = 98,
+ DXGI_FORMAT_BC7_UNORM_SRGB = 99,
+ DXGI_FORMAT_AYUV = 100,
+ DXGI_FORMAT_Y410 = 101,
+ DXGI_FORMAT_Y416 = 102,
+ DXGI_FORMAT_NV12 = 103,
+ DXGI_FORMAT_P010 = 104,
+ DXGI_FORMAT_P016 = 105,
+ DXGI_FORMAT_420_OPAQUE = 106,
+ DXGI_FORMAT_YUY2 = 107,
+ DXGI_FORMAT_Y210 = 108,
+ DXGI_FORMAT_Y216 = 109,
+ DXGI_FORMAT_NV11 = 110,
+ DXGI_FORMAT_AI44 = 111,
+ DXGI_FORMAT_IA44 = 112,
+ DXGI_FORMAT_P8 = 113,
+ DXGI_FORMAT_A8P8 = 114,
+ DXGI_FORMAT_B4G4R4A4_UNORM = 115,
+ DXGI_FORMAT_P208 = 130,
+ DXGI_FORMAT_V208 = 131,
+ DXGI_FORMAT_V408 = 132,
+};
+
+template <int a, int b, int c, int d>
+struct DdsFourCC
+{
+ static const quint32 value = a | (b << 8) | (c << 16) | (d << 24);
+};
+
+struct FormatInfo
+{
+ QOpenGLTexture::PixelFormat pixelFormat;
+ QOpenGLTexture::TextureFormat textureFormat;
+ QOpenGLTexture::PixelType pixelType;
+ int components;
+ bool compressed;
+};
+
+const struct RGBAFormat
+{
+ quint32 redMask;
+ quint32 greenMask;
+ quint32 blueMask;
+ quint32 alphaMask;
+ FormatInfo formatInfo;
+
+} rgbaFormats[] = {
+ // unorm formats
+{ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+{ 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, { QOpenGLTexture::BGRA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+{ 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+{ 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, { QOpenGLTexture::BGRA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+{ 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, { QOpenGLTexture::RGB, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, 3, false } },
+{ 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, { QOpenGLTexture::BGR, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, 3, false } },
+
+// packed formats
+{ 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000, { QOpenGLTexture::RGB, QOpenGLTexture::R5G6B5, QOpenGLTexture::UInt16_R5G6B5, 2, false } },
+{ 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGB5A1, QOpenGLTexture::UInt16_RGB5A1, 2, false } },
+{ 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA4, QOpenGLTexture::UInt16_RGBA4, 2, false } },
+{ 0x000000e0, 0x0000001c, 0x00000003, 0x00000000, { QOpenGLTexture::RGB, QOpenGLTexture::RG3B2, QOpenGLTexture::UInt8_RG3B2, 1, false } },
+{ 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGB10A2, QOpenGLTexture::UInt32_RGB10A2, 4, false } },
+
+// luminance alpha
+{ 0x000000ff, 0x000000ff, 0x000000ff, 0x00000000, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
+{ 0x000000ff, 0x00000000, 0x00000000, 0x00000000, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
+{ 0x000000ff, 0x000000ff, 0x000000ff, 0x0000ff00, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
+{ 0x000000ff, 0x00000000, 0x00000000, 0x0000ff00, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
+};
+
+const struct FourCCFormat
+{
+ quint32 fourCC;
+ FormatInfo formatInfo;
+} fourCCFormats[] = {
+{ DdsFourCC<'D','X','T','1'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
+{ DdsFourCC<'D','X','T','3'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT3, QOpenGLTexture::NoPixelType, 16, true } },
+{ DdsFourCC<'D','X','T','5'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT5, QOpenGLTexture::NoPixelType, 16, true } },
+{ DdsFourCC<'A','T','I','1'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::R_ATI1N_UNorm, QOpenGLTexture::NoPixelType, 8, true } },
+{ DdsFourCC<'A','T','I','2'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RG_ATI2N_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
+};
+
+const struct DX10Format
+{
+ DXGIFormat dxgiFormat;
+ FormatInfo formatInfo;
+} dx10Formats[] = {
+ // unorm formats
+{ DXGI_FORMAT_R8_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
+{ DXGI_FORMAT_R8G8_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
+{ DXGI_FORMAT_R8G8B8A8_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+
+{ DXGI_FORMAT_R16_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R16_UNorm, QOpenGLTexture::UInt16, 2, false } },
+{ DXGI_FORMAT_R16G16_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG16_UNorm, QOpenGLTexture::UInt16, 4, false } },
+{ DXGI_FORMAT_R16G16B16A16_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA16_UNorm, QOpenGLTexture::UInt16, 8, false } },
+
+// snorm formats
+{ DXGI_FORMAT_R8_SNORM, { QOpenGLTexture::Red, QOpenGLTexture::R8_SNorm, QOpenGLTexture::Int8, 1, false } },
+{ DXGI_FORMAT_R8G8_SNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG8_SNorm, QOpenGLTexture::Int8, 2, false } },
+{ DXGI_FORMAT_R8G8B8A8_SNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_SNorm, QOpenGLTexture::Int8, 4, false } },
+
+{ DXGI_FORMAT_R16_SNORM, { QOpenGLTexture::Red, QOpenGLTexture::R16_SNorm, QOpenGLTexture::Int16, 2, false } },
+{ DXGI_FORMAT_R16G16_SNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG16_SNorm, QOpenGLTexture::Int16, 4, false } },
+{ DXGI_FORMAT_R16G16B16A16_SNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA16_SNorm, QOpenGLTexture::Int16, 8, false } },
+
+// unsigned integer formats
+{ DXGI_FORMAT_R8_UINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R8U, QOpenGLTexture::UInt8, 1, false } },
+{ DXGI_FORMAT_R8G8_UINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG8U, QOpenGLTexture::UInt8, 2, false } },
+{ DXGI_FORMAT_R8G8B8A8_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA8U, QOpenGLTexture::UInt8, 4, false } },
+
+{ DXGI_FORMAT_R16_UINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R16U, QOpenGLTexture::UInt16, 2, false } },
+{ DXGI_FORMAT_R16G16_UINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG16U, QOpenGLTexture::UInt16, 4, false } },
+{ DXGI_FORMAT_R16G16B16A16_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA16U, QOpenGLTexture::UInt16, 8, false } },
+
+{ DXGI_FORMAT_R32_UINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R32U, QOpenGLTexture::UInt32, 4, false } },
+{ DXGI_FORMAT_R32G32_UINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG32U, QOpenGLTexture::UInt32, 8, false } },
+{ DXGI_FORMAT_R32G32B32_UINT, { QOpenGLTexture::RGB_Integer, QOpenGLTexture::RGB32U, QOpenGLTexture::UInt32, 12, false } },
+{ DXGI_FORMAT_R32G32B32A32_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA32U, QOpenGLTexture::UInt32, 16, false } },
+
+// signed integer formats
+{ DXGI_FORMAT_R8_SINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R8I, QOpenGLTexture::Int8, 1, false } },
+{ DXGI_FORMAT_R8G8_SINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG8I, QOpenGLTexture::Int8, 2, false } },
+{ DXGI_FORMAT_R8G8B8A8_SINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA8I, QOpenGLTexture::Int8, 4, false } },
+
+{ DXGI_FORMAT_R16_SINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R16I, QOpenGLTexture::Int16, 2, false } },
+{ DXGI_FORMAT_R16G16_SINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG16I, QOpenGLTexture::Int16, 4, false } },
+{ DXGI_FORMAT_R16G16B16A16_SINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA16I, QOpenGLTexture::Int16, 8, false } },
+
+{ DXGI_FORMAT_R32_SINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R32I, QOpenGLTexture::Int32, 4, false } },
+{ DXGI_FORMAT_R32G32_SINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG32I, QOpenGLTexture::Int32, 8, false } },
+{ DXGI_FORMAT_R32G32B32_SINT, { QOpenGLTexture::RGB_Integer, QOpenGLTexture::RGB32I, QOpenGLTexture::Int32, 12, false } },
+{ DXGI_FORMAT_R32G32B32A32_SINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA32I, QOpenGLTexture::Int32, 16, false } },
+
+// floating formats
+{ DXGI_FORMAT_R16_FLOAT, { QOpenGLTexture::Red, QOpenGLTexture::R16F, QOpenGLTexture::Float16, 2, false } },
+{ DXGI_FORMAT_R16G16_FLOAT, { QOpenGLTexture::RG, QOpenGLTexture::RG16F, QOpenGLTexture::Float16, 4, false } },
+{ DXGI_FORMAT_R16G16B16A16_FLOAT, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA16F, QOpenGLTexture::Float16, 8, false } },
+
+{ DXGI_FORMAT_R32_FLOAT, { QOpenGLTexture::Red, QOpenGLTexture::R32F, QOpenGLTexture::Float32, 4, false } },
+{ DXGI_FORMAT_R32G32_FLOAT, { QOpenGLTexture::RG, QOpenGLTexture::RG32F, QOpenGLTexture::Float32, 8, false } },
+{ DXGI_FORMAT_R32G32B32_FLOAT, { QOpenGLTexture::RGB, QOpenGLTexture::RGB32F, QOpenGLTexture::Float32, 12, false } },
+{ DXGI_FORMAT_R32G32B32A32_FLOAT, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA32F, QOpenGLTexture::Float32, 16, false } },
+
+// sRGB formats
+{ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, { QOpenGLTexture::RGB, QOpenGLTexture::SRGB8, QOpenGLTexture::UInt8, 4, false } },
+{ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, { QOpenGLTexture::RGBA, QOpenGLTexture::SRGB8_Alpha8, QOpenGLTexture::UInt8, 4, false } },
+
+// packed formats
+// { DXGI_FORMAT_R10G10B10A2_UNORM, { QOpenGLTexture::RGB10A2_UNORM, QOpenGLTexture::RGBA, QOpenGLTexture::UInt32_RGB10A2, 4, false } },
+{ DXGI_FORMAT_R10G10B10A2_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGB10A2, QOpenGLTexture::UInt32_RGB10A2, 4, false } },
+{ DXGI_FORMAT_R9G9B9E5_SHAREDEXP, { QOpenGLTexture::RGB, QOpenGLTexture::RGB9E5, QOpenGLTexture::UInt32_RGB9_E5, 4, false } },
+{ DXGI_FORMAT_R11G11B10_FLOAT, { QOpenGLTexture::RGB, QOpenGLTexture::RG11B10F, QOpenGLTexture::UInt32_RG11B10F, 4, false } },
+{ DXGI_FORMAT_B5G6R5_UNORM, { QOpenGLTexture::RGB, QOpenGLTexture::R5G6B5, QOpenGLTexture::UInt16_R5G6B5, 2, false } },
+{ DXGI_FORMAT_B5G5R5A1_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGB5A1, QOpenGLTexture::UInt16_RGB5A1, 2, false } },
+{ DXGI_FORMAT_B4G4R4A4_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA4, QOpenGLTexture::UInt16_RGBA4, 2, false } },
+
+// swizzle formats
+{ DXGI_FORMAT_B8G8R8X8_UNORM, { QOpenGLTexture::BGRA, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+{ DXGI_FORMAT_B8G8R8A8_UNORM, { QOpenGLTexture::BGRA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
+{ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, { QOpenGLTexture::BGRA, QOpenGLTexture::SRGB8, QOpenGLTexture::UInt8, 4, false } },
+{ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, { QOpenGLTexture::BGRA, QOpenGLTexture::SRGB8_Alpha8, QOpenGLTexture::UInt8, 4, false } },
+
+// luminance alpha formats
+{ DXGI_FORMAT_R8_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
+{ DXGI_FORMAT_R8G8_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
+{ DXGI_FORMAT_R16_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R16_UNorm, QOpenGLTexture::UInt16, 2, false } },
+{ DXGI_FORMAT_R16_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG16_UNorm, QOpenGLTexture::UInt16, 4, false } },
+
+// depth formats
+{ DXGI_FORMAT_D16_UNORM, { QOpenGLTexture::Depth, QOpenGLTexture::D16, QOpenGLTexture::NoPixelType, 2, false } },
+{ DXGI_FORMAT_D24_UNORM_S8_UINT, { QOpenGLTexture::DepthStencil, QOpenGLTexture::D24S8, QOpenGLTexture::NoPixelType, 4, false } },
+{ DXGI_FORMAT_D32_FLOAT, { QOpenGLTexture::Depth, QOpenGLTexture::D32F, QOpenGLTexture::NoPixelType, 4, false } },
+{ DXGI_FORMAT_D32_FLOAT_S8X24_UINT, { QOpenGLTexture::DepthStencil, QOpenGLTexture::D32FS8X24, QOpenGLTexture::NoPixelType, 8, false } },
+
+// compressed formats
+{ DXGI_FORMAT_BC1_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
+{ DXGI_FORMAT_BC2_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT3, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC3_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT5, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC4_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::R_ATI1N_UNorm, QOpenGLTexture::NoPixelType, 8, true } },
+{ DXGI_FORMAT_BC4_SNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::R_ATI1N_SNorm, QOpenGLTexture::NoPixelType, 8, true } },
+{ DXGI_FORMAT_BC5_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RG_ATI2N_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC5_SNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RG_ATI2N_SNorm, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC6H_UF16, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC6H_SF16, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGB_BP_SIGNED_FLOAT, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC7_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGB_BP_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
+
+// compressed sRGB formats
+{ DXGI_FORMAT_BC1_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
+{ DXGI_FORMAT_BC1_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_Alpha_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
+{ DXGI_FORMAT_BC2_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_Alpha_DXT3, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC3_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_Alpha_DXT5, QOpenGLTexture::NoPixelType, 16, true } },
+{ DXGI_FORMAT_BC7_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_BP_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
+};
+
+int bitCount(quint32 n)
+{
+ int r = 0;
+
+ for (; n; n >>= 1)
+ r += (n & 1);
+
+ return r;
+}
+
+enum CompressedFormatExtension {
+ None = 0,
+ DDS,
+ PKM
+};
+
+CompressedFormatExtension texturedCompressedFormat(const QString &source)
+{
+ const QString suffix = QFileInfo(source).suffix();
+ if (suffix == QStringLiteral("pkm"))
+ return PKM;
+ if (suffix == QStringLiteral("dds"))
+ return DDS;
+ return None;
+}
+
+QTextureImageDataPtr setPkmFile(const QString &source)
+{
+ QTextureImageDataPtr imageData;
+ QFile f(source);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qWarning() << "Failed to open" << source;
+ return imageData;
+ }
+
+ // ETC1 in PKM, as generated by f.ex. Android's etc1tool
+ static const char pkmMagic[] = { 'P', 'K', 'M', ' ', '1', '0' };
+ const int pkmHeaderSize = 6 + 2 + 4 * 2;
+ const QByteArray header = f.read(pkmHeaderSize);
+ if (header.size() >= pkmHeaderSize && !qstrncmp(header.constData(), pkmMagic, 6)) {
+ imageData = QTextureImageDataPtr::create();
+ imageData->setTarget(QOpenGLTexture::Target2D);
+ imageData->setFormat(QOpenGLTexture::RGB8_ETC1); // may get changed to RGB8_ETC2 later on
+ // get the extended (multiple of 4) width and height
+ imageData->setWidth(qFromBigEndian(*(reinterpret_cast<const quint16 *>(header.constData() + 6 + 2))));
+ imageData->setHeight(qFromBigEndian(*(reinterpret_cast<const quint16 *>(header.constData() + 6 + 2 + 2))));
+ imageData->setDepth(1);
+ const QByteArray data = f.readAll();
+ if (data.size() < (imageData->width() / 4) * (imageData->height() / 4) * 8)
+ qWarning() << "Unexpected end of ETC1 data in" << source;
+ const bool isCompressed = true;
+ const int blockSize = 8;
+ imageData->setPixelFormat(QOpenGLTexture::RGBA);
+ imageData->setPixelType(QOpenGLTexture::UInt8);
+ imageData->setData(data, blockSize, isCompressed);
+ }
+ return imageData;
+}
+
+QTextureImageDataPtr setDdsFile(const QString &source)
+{
+ QTextureImageDataPtr imageData;
+ QFile f(source);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qWarning() << "Failed to open" << source;
+ return imageData;
+ }
+
+ DdsHeader header;
+ if ((f.read(reinterpret_cast<char *>(&header), sizeof header) != sizeof header)
+ || (qstrncmp(header.magic, "DDS ", 4) != 0))
+ return imageData;
+
+ int layers = 1;
+ const quint32 pixelFlags = qFromLittleEndian(header.pixelFormat.flags);
+ const quint32 fourCC = qFromLittleEndian(header.pixelFormat.fourCC);
+ const FormatInfo *formatInfo = nullptr;
+
+ if ((pixelFlags & FourCCFlag) == FourCCFlag) {
+ if (fourCC == DdsFourCC<'D', 'X', '1', '0'>::value) {
+ // DX10 texture
+ DdsDX10Header dx10Header;
+ if (f.read(reinterpret_cast<char *>(&dx10Header), sizeof dx10Header) != sizeof dx10Header)
+ return imageData;
+
+ layers = qFromLittleEndian(dx10Header.arraySize);
+ DXGIFormat format = static_cast<DXGIFormat>(qFromLittleEndian(dx10Header.format));
+
+ for (auto i = 0U; i < sizeof(dx10Formats) / sizeof(*dx10Formats); ++i) {
+ if (dx10Formats[i].dxgiFormat == format) {
+ formatInfo = &dx10Formats[i].formatInfo;
+ break;
+ }
+ }
+ } else {
+ // compressed, FourCC texture
+ for (auto i = 0U; i < sizeof(fourCCFormats) / sizeof(*fourCCFormats); ++i) {
+ if (fourCCFormats[i].fourCC == fourCC) {
+ formatInfo = &fourCCFormats[i].formatInfo;
+ break;
+ }
+ }
+ }
+ } else {
+ // uncompressed texture
+ const quint32 rgbBitCount = qFromLittleEndian(header.pixelFormat.rgbBitCount);
+ const quint32 redMask = qFromLittleEndian(header.pixelFormat.redMask);
+ const quint32 greenMask = qFromLittleEndian(header.pixelFormat.greenMask);
+ const quint32 blueMask = qFromLittleEndian(header.pixelFormat.blueMask);
+ const quint32 alphaMask = qFromLittleEndian(header.pixelFormat.alphaMask);
+
+ for (unsigned i = 0; i < sizeof rgbaFormats/sizeof *rgbaFormats; i++) {
+ const RGBAFormat *info = &rgbaFormats[i];
+
+ if (info->formatInfo.components * 8u == rgbBitCount &&
+ info->redMask == redMask && info->greenMask == greenMask &&
+ info->blueMask == blueMask && info->alphaMask == alphaMask) {
+ formatInfo = &info->formatInfo;
+ break;
+ }
+ }
+ }
+
+ if (formatInfo == nullptr) {
+ qWarning() << "Unrecognized pixel format in" << source;
+ return imageData;
+ }
+
+ // target
+ // XXX should worry about Target1D?
+ QOpenGLTexture::Target target;
+ const int width = qFromLittleEndian(header.width);
+ const int height = qFromLittleEndian(header.height);
+ const quint32 caps2Flags = qFromLittleEndian(header.caps2);
+ const int blockSize = formatInfo->components;
+ const bool isCompressed = formatInfo->compressed;
+ const int mipLevelCount = ((qFromLittleEndian(header.flags) & MipmapCountFlag) == MipmapCountFlag) ? qFromLittleEndian(header.mipmapCount) : 1;
+ int depth;
+ int faces;
+
+ if ((caps2Flags & VolumeFlag) == VolumeFlag) {
+ target = QOpenGLTexture::Target3D;
+ depth = qFromLittleEndian(header.depth);
+ faces = 1;
+ } else if ((caps2Flags & CubemapFlag) == CubemapFlag) {
+ target = layers > 1 ? QOpenGLTexture::TargetCubeMapArray : QOpenGLTexture::TargetCubeMap;
+ depth = 1;
+ faces = bitCount(caps2Flags & AllCubemapFaceFlags);
+ } else {
+ target = layers > 1 ? QOpenGLTexture::Target2DArray : QOpenGLTexture::Target2D;
+ depth = 1;
+ faces = 1;
+ }
+
+ int layerSize = 0;
+ int tmpSize = 0;
+
+ auto computeMipMapLevelSize = [&] (int level) {
+ const int w = qMax(width >> level, 1);
+ const int h = qMax(height >> level, 1);
+ const int d = qMax(depth >> level, 1);
+
+ if (isCompressed)
+ return ((w + 3) / 4) * ((h + 3) / 4) * blockSize * d;
+ else
+ return w * h * blockSize * d;
+ };
+
+ for (auto i = 0; i < mipLevelCount; ++i)
+ tmpSize += computeMipMapLevelSize(i);
+
+ layerSize = faces * tmpSize;
+
+ // data
+ const QByteArray data = f.readAll();
+ if (data.size() != layers * layerSize) {
+ qWarning() << "Unexpected data size (got " << data.size() << ", expecting" << layers * layerSize << ")";
+ return imageData;
+ }
+ imageData = QTextureImageDataPtr::create();
+ imageData->setData(data,blockSize, isCompressed);
+
+ // target
+ imageData->setTarget(target);
+
+ // mip levels
+ imageData->setMipLevels(mipLevelCount);
+
+ // texture format
+ imageData->setFormat(formatInfo->textureFormat);
+ imageData->setPixelType(formatInfo->pixelType);
+ imageData->setPixelFormat(formatInfo->pixelFormat);
+
+ // dimensions
+ imageData->setLayers(layers);
+ imageData->setDepth(depth);
+ imageData->setWidth(width);
+ imageData->setHeight(height);
+ imageData->setFaces(faces);
+
+ return imageData;
+}
+
+} // anonynous
+
+QTextureImageDataPtr TextureLoadingHelper::loadTextureData(const QUrl &url, bool allow3D)
+{
+ QTextureImageDataPtr textureData;
+ if (url.isLocalFile() || url.scheme() == QLatin1String("qrc")) {
+ const QString source = Qt3DRender::QUrlHelper::urlToLocalFileOrQrc(url);
+ const CompressedFormatExtension formatExtension = texturedCompressedFormat(source);
+ switch (formatExtension) {
+ case DDS:
+ textureData = setDdsFile(source);
+ break;
+ case PKM:
+ textureData = setPkmFile(source);
+ break;
+ default:
+ QImage img;
+ if (img.load(source)) {
+ textureData = QTextureImageDataPtr::create();
+ textureData->setImage(img);
+ }
+ break;
+ }
+
+ if (!allow3D && (textureData->layers() > 1 || textureData->depth() > 1))
+ qWarning() << "Texture data has a 3rd dimension which wasn't expected";
+ }
+ return textureData;
+}
+
+QTextureDataPtr QTextureFromSourceGenerator::operator ()()
+{
+ QTextureDataPtr generatedData = QTextureDataPtr::create();
+ m_status = QAbstractTexture::Loading;
+
+ const QTextureImageDataPtr textureData = TextureLoadingHelper::loadTextureData(m_url, true);
+
+ if (textureData && textureData->data().length() > 0) {
+ generatedData->setTarget(static_cast<QAbstractTexture::Target>(textureData->target()));
+ generatedData->setFormat(static_cast<QAbstractTexture::TextureFormat>(textureData->format()));
+ generatedData->setWidth(textureData->width());
+ generatedData->setHeight(textureData->height());
+ generatedData->setDepth(textureData->depth());
+ generatedData->setLayers(textureData->layers());
+ generatedData->addImageData(textureData);
+ // TO DO: Check that we aren't forgetting to set something here
+ m_status = QAbstractTexture::Ready;
+ } else {
+ m_status = QAbstractTexture::Error;
+ }
+ return generatedData;
+}
+
QTextureLoaderPrivate::QTextureLoaderPrivate()
: QAbstractTexturePrivate()
{
@@ -304,64 +930,14 @@ bool QTextureFromSourceGenerator::operator ==(const QTextureGenerator &other) co
{
const QTextureFromSourceGenerator *otherFunctor = functor_cast<QTextureFromSourceGenerator>(&other);
return (otherFunctor != Q_NULLPTR && otherFunctor->m_url == m_url);
-
}
-
QTextureFromSourceGenerator::QTextureFromSourceGenerator(const QUrl &url)
: QTextureGenerator()
, m_url(url)
{
}
-// Note: Maybe this should return a struct containing information such as
-// the format, number of layers ....
-// This would also give more flexibility for the future
-QTextureDataPtr QTextureFromSourceGenerator::operator ()()
-{
- QTextureDataPtr generatedData = QTextureDataPtr::create();
- // TO DO: Make it handle more formats and formats with nested images
-
- m_status = QAbstractTexture::Loading;
-
- if (m_url.isLocalFile() || m_url.scheme() == QStringLiteral("qrc")) {
- QString source = Qt3DRender::QUrlHelper::urlToLocalFileOrQrc(m_url);
- QVector<QTextureImageDataPtr> images;
- QTextureImageDataPtr dataPtr = QTextureImageDataPtr::create();
- // TO DO: Ideally a setter shouldn't return a value
- // Separate that into isCompressedFile and setCompressedFile
- // Set compressed fill the QTextImageData if possible,
- // returns false if it failed or is not a compressed format
-
- // TO DO: Make separateSetCompressed from the loading of a compressed file
- // Make such loader set the property formats, targets and sizes in the generatedData
-
- if (!dataPtr->setCompressedFile(source)) {
- // Try to load using QImage
- QImage img;
- if (img.load(source))
- dataPtr->setImage(img);
- generatedData->setTarget(QAbstractTexture::Target2D);
- generatedData->setWidth(img.width());
- generatedData->setHeight(img.height());
- generatedData->setDepth(1);
- }
-
- if (dataPtr->data().length() > 0) {
- m_status = QAbstractTexture::Ready;
- generatedData->addImageData(dataPtr);
- images.push_back(dataPtr);
- } else {
- m_status = QAbstractTexture::Error;
- qWarning() << "Failed to load image : " << source;
- }
- } else {
- m_status = QAbstractTexture::Error;
- qWarning() << "implement loading from remote URLs";
- }
- return generatedData;
-}
-
} // namespace Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/texture/qtexture_p.h b/src/render/texture/qtexture_p.h
index 7f295bbbe..d80e048f7 100644
--- a/src/render/texture/qtexture_p.h
+++ b/src/render/texture/qtexture_p.h
@@ -81,6 +81,12 @@ private:
QAbstractTexture::Status m_status;
};
+class Q_AUTOTEST_EXPORT TextureLoadingHelper
+{
+public:
+ static QTextureImageDataPtr loadTextureData(const QUrl &source, bool allow3D);
+};
+
} // namespace Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/texture/qtextureimage.cpp b/src/render/texture/qtextureimage.cpp
index 717a80100..67bef5efb 100644
--- a/src/render/texture/qtextureimage.cpp
+++ b/src/render/texture/qtextureimage.cpp
@@ -39,6 +39,7 @@
#include "qtextureimage.h"
#include "qtextureimage_p.h"
+#include "qtexture_p.h"
#include "qabstracttextureimage_p.h"
#include <Qt3DCore/qpropertyupdatedchange.h>
@@ -149,6 +150,25 @@ void QTextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
setStatus(static_cast<QTextureImage::Status>(e->value().toInt()));
}
+QImageTextureDataFunctor::QImageTextureDataFunctor(const QUrl &url)
+ : QTextureImageDataGenerator()
+ , m_url(url)
+{}
+
+QTextureImageDataPtr QImageTextureDataFunctor::operator ()()
+{
+ // We assume that a texture image is going to contain a single image data
+ // For compressed dds or ktx textures a warning should be issued if
+ // there are layers or 3D textures
+ return TextureLoadingHelper::loadTextureData(m_url, false);
+}
+
+bool QImageTextureDataFunctor::operator ==(const QTextureImageDataGenerator &other) const
+{
+ const QImageTextureDataFunctor *otherFunctor = functor_cast<QImageTextureDataFunctor>(&other);
+ return (otherFunctor != Q_NULLPTR && otherFunctor->m_url == m_url);
+}
+
} // namespace Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/texture/qtextureimage_p.h b/src/render/texture/qtextureimage_p.h
index 30bc44628..ed1ae2ced 100644
--- a/src/render/texture/qtextureimage_p.h
+++ b/src/render/texture/qtextureimage_p.h
@@ -78,44 +78,11 @@ public:
class QImageTextureDataFunctor : public QTextureImageDataGenerator
{
public:
- QImageTextureDataFunctor(const QUrl &url)
- : QTextureImageDataGenerator()
- , m_url(url)
- {}
-
+ QImageTextureDataFunctor(const QUrl &url);
// Will be executed from within a QAspectJob
- QTextureImageDataPtr operator ()() Q_DECL_FINAL
- {
- QTextureImageDataPtr dataPtr;
- if (m_url.isLocalFile() || m_url.scheme() == QLatin1String("qrc")) {
- QString source = Qt3DRender::QUrlHelper::urlToLocalFileOrQrc(m_url);
- dataPtr.reset(new QTextureImageData());
- if (dataPtr->setCompressedFile(source))
- return dataPtr;
- QImage img;
- if (img.load(source)) {
- dataPtr->setImage(img);
- return dataPtr;
- }
- dataPtr.reset();
- qWarning() << "Failed to load image : " << source;
- } else if (!m_url.isEmpty()) {
- qWarning() << "implement loading from remote URLs";
- }
- return dataPtr;
- }
-
- bool operator ==(const QTextureImageDataGenerator &other) const Q_DECL_FINAL
- {
- const QImageTextureDataFunctor *otherFunctor = functor_cast<QImageTextureDataFunctor>(&other);
- return (otherFunctor != Q_NULLPTR && otherFunctor->m_url == m_url);
- }
-
- QTextureImage::Status status() const
- {
- return m_status;
- }
-
+ QTextureImageDataPtr operator ()() Q_DECL_FINAL;
+ bool operator ==(const QTextureImageDataGenerator &other) const Q_DECL_FINAL;
+ inline QTextureImage::Status status() const { return m_status; }
QT3D_FUNCTOR(QImageTextureDataFunctor)
private:
diff --git a/src/render/texture/qtextureimagedata.cpp b/src/render/texture/qtextureimagedata.cpp
index 80e6f5575..ee080ee9f 100644
--- a/src/render/texture/qtextureimagedata.cpp
+++ b/src/render/texture/qtextureimagedata.cpp
@@ -41,370 +41,11 @@
#include <QDebug>
#include <QFileInfo>
#include <QFile>
-#include <qendian.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
-namespace {
-
-struct DdsPixelFormat {
- quint32 size;
- quint32 flags;
- quint32 fourCC;
- quint32 rgbBitCount;
- quint32 redMask;
- quint32 greenMask;
- quint32 blueMask;
- quint32 alphaMask;
-};
-
-struct DdsHeader {
- char magic[4];
- quint32 size;
- quint32 flags;
- quint32 height;
- quint32 width;
- quint32 pitchOrLinearSize;
- quint32 depth;
- quint32 mipmapCount;
- quint32 reserved[11];
- DdsPixelFormat pixelFormat;
- quint32 caps;
- quint32 caps2;
- quint32 caps3;
- quint32 caps4;
- quint32 reserved2;
-};
-
-struct DdsDX10Header {
- quint32 format;
- quint32 dimension;
- quint32 miscFlag;
- quint32 arraySize;
- quint32 miscFlags2;
-};
-
-enum DdsFlags {
- MipmapCountFlag = 0x20000,
-};
-
-enum PixelFormatFlag {
- AlphaFlag = 0x1,
- FourCCFlag = 0x4,
- RGBFlag = 0x40,
- RGBAFlag = RGBFlag | AlphaFlag,
- YUVFlag = 0x200,
- LuminanceFlag = 0x20000
-};
-
-enum Caps2Flags {
- CubemapFlag = 0x200,
- CubemapPositiveXFlag = 0x400,
- CubemapNegativeXFlag = 0x800,
- CubemapPositiveYFlag = 0x1000,
- CubemapNegativeYFlag = 0x2000,
- CubemapPositiveZFlag = 0x4000,
- CubemapNegativeZFlag = 0x8000,
- AllCubemapFaceFlags = CubemapPositiveXFlag |
- CubemapNegativeXFlag |
- CubemapPositiveYFlag |
- CubemapNegativeYFlag |
- CubemapPositiveZFlag |
- CubemapNegativeZFlag,
- VolumeFlag = 0x200000
-};
-
-enum DXGIFormat {
- DXGI_FORMAT_UNKNOWN = 0,
- DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
- DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
- DXGI_FORMAT_R32G32B32A32_UINT = 3,
- DXGI_FORMAT_R32G32B32A32_SINT = 4,
- DXGI_FORMAT_R32G32B32_TYPELESS = 5,
- DXGI_FORMAT_R32G32B32_FLOAT = 6,
- DXGI_FORMAT_R32G32B32_UINT = 7,
- DXGI_FORMAT_R32G32B32_SINT = 8,
- DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
- DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
- DXGI_FORMAT_R16G16B16A16_UNORM = 11,
- DXGI_FORMAT_R16G16B16A16_UINT = 12,
- DXGI_FORMAT_R16G16B16A16_SNORM = 13,
- DXGI_FORMAT_R16G16B16A16_SINT = 14,
- DXGI_FORMAT_R32G32_TYPELESS = 15,
- DXGI_FORMAT_R32G32_FLOAT = 16,
- DXGI_FORMAT_R32G32_UINT = 17,
- DXGI_FORMAT_R32G32_SINT = 18,
- DXGI_FORMAT_R32G8X24_TYPELESS = 19,
- DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
- DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
- DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
- DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
- DXGI_FORMAT_R10G10B10A2_UNORM = 24,
- DXGI_FORMAT_R10G10B10A2_UINT = 25,
- DXGI_FORMAT_R11G11B10_FLOAT = 26,
- DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
- DXGI_FORMAT_R8G8B8A8_UNORM = 28,
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
- DXGI_FORMAT_R8G8B8A8_UINT = 30,
- DXGI_FORMAT_R8G8B8A8_SNORM = 31,
- DXGI_FORMAT_R8G8B8A8_SINT = 32,
- DXGI_FORMAT_R16G16_TYPELESS = 33,
- DXGI_FORMAT_R16G16_FLOAT = 34,
- DXGI_FORMAT_R16G16_UNORM = 35,
- DXGI_FORMAT_R16G16_UINT = 36,
- DXGI_FORMAT_R16G16_SNORM = 37,
- DXGI_FORMAT_R16G16_SINT = 38,
- DXGI_FORMAT_R32_TYPELESS = 39,
- DXGI_FORMAT_D32_FLOAT = 40,
- DXGI_FORMAT_R32_FLOAT = 41,
- DXGI_FORMAT_R32_UINT = 42,
- DXGI_FORMAT_R32_SINT = 43,
- DXGI_FORMAT_R24G8_TYPELESS = 44,
- DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
- DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
- DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
- DXGI_FORMAT_R8G8_TYPELESS = 48,
- DXGI_FORMAT_R8G8_UNORM = 49,
- DXGI_FORMAT_R8G8_UINT = 50,
- DXGI_FORMAT_R8G8_SNORM = 51,
- DXGI_FORMAT_R8G8_SINT = 52,
- DXGI_FORMAT_R16_TYPELESS = 53,
- DXGI_FORMAT_R16_FLOAT = 54,
- DXGI_FORMAT_D16_UNORM = 55,
- DXGI_FORMAT_R16_UNORM = 56,
- DXGI_FORMAT_R16_UINT = 57,
- DXGI_FORMAT_R16_SNORM = 58,
- DXGI_FORMAT_R16_SINT = 59,
- DXGI_FORMAT_R8_TYPELESS = 60,
- DXGI_FORMAT_R8_UNORM = 61,
- DXGI_FORMAT_R8_UINT = 62,
- DXGI_FORMAT_R8_SNORM = 63,
- DXGI_FORMAT_R8_SINT = 64,
- DXGI_FORMAT_A8_UNORM = 65,
- DXGI_FORMAT_R1_UNORM = 66,
- DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
- DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
- DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
- DXGI_FORMAT_BC1_TYPELESS = 70,
- DXGI_FORMAT_BC1_UNORM = 71,
- DXGI_FORMAT_BC1_UNORM_SRGB = 72,
- DXGI_FORMAT_BC2_TYPELESS = 73,
- DXGI_FORMAT_BC2_UNORM = 74,
- DXGI_FORMAT_BC2_UNORM_SRGB = 75,
- DXGI_FORMAT_BC3_TYPELESS = 76,
- DXGI_FORMAT_BC3_UNORM = 77,
- DXGI_FORMAT_BC3_UNORM_SRGB = 78,
- DXGI_FORMAT_BC4_TYPELESS = 79,
- DXGI_FORMAT_BC4_UNORM = 80,
- DXGI_FORMAT_BC4_SNORM = 81,
- DXGI_FORMAT_BC5_TYPELESS = 82,
- DXGI_FORMAT_BC5_UNORM = 83,
- DXGI_FORMAT_BC5_SNORM = 84,
- DXGI_FORMAT_B5G6R5_UNORM = 85,
- DXGI_FORMAT_B5G5R5A1_UNORM = 86,
- DXGI_FORMAT_B8G8R8A8_UNORM = 87,
- DXGI_FORMAT_B8G8R8X8_UNORM = 88,
- DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
- DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
- DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
- DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
- DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
- DXGI_FORMAT_BC6H_TYPELESS = 94,
- DXGI_FORMAT_BC6H_UF16 = 95,
- DXGI_FORMAT_BC6H_SF16 = 96,
- DXGI_FORMAT_BC7_TYPELESS = 97,
- DXGI_FORMAT_BC7_UNORM = 98,
- DXGI_FORMAT_BC7_UNORM_SRGB = 99,
- DXGI_FORMAT_AYUV = 100,
- DXGI_FORMAT_Y410 = 101,
- DXGI_FORMAT_Y416 = 102,
- DXGI_FORMAT_NV12 = 103,
- DXGI_FORMAT_P010 = 104,
- DXGI_FORMAT_P016 = 105,
- DXGI_FORMAT_420_OPAQUE = 106,
- DXGI_FORMAT_YUY2 = 107,
- DXGI_FORMAT_Y210 = 108,
- DXGI_FORMAT_Y216 = 109,
- DXGI_FORMAT_NV11 = 110,
- DXGI_FORMAT_AI44 = 111,
- DXGI_FORMAT_IA44 = 112,
- DXGI_FORMAT_P8 = 113,
- DXGI_FORMAT_A8P8 = 114,
- DXGI_FORMAT_B4G4R4A4_UNORM = 115,
- DXGI_FORMAT_P208 = 130,
- DXGI_FORMAT_V208 = 131,
- DXGI_FORMAT_V408 = 132,
-};
-
-template <int a, int b, int c, int d>
-struct DdsFourCC
-{
- static const quint32 value = a | (b << 8) | (c << 16) | (d << 24);
-};
-
-struct FormatInfo {
- QOpenGLTexture::PixelFormat pixelFormat;
- QOpenGLTexture::TextureFormat textureFormat;
- QOpenGLTexture::PixelType pixelType;
- int components;
- bool compressed;
-};
-
-const struct RGBAFormat {
- quint32 redMask;
- quint32 greenMask;
- quint32 blueMask;
- quint32 alphaMask;
- FormatInfo formatInfo;
-} rgbaFormats[] = {
- // unorm formats
- { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
- { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, { QOpenGLTexture::BGRA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
- { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
- { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, { QOpenGLTexture::BGRA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
- { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, { QOpenGLTexture::RGB, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, 3, false } },
- { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, { QOpenGLTexture::BGR, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, 3, false } },
-
- // packed formats
- { 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000, { QOpenGLTexture::RGB, QOpenGLTexture::R5G6B5, QOpenGLTexture::UInt16_R5G6B5, 2, false } },
- { 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGB5A1, QOpenGLTexture::UInt16_RGB5A1, 2, false } },
- { 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA4, QOpenGLTexture::UInt16_RGBA4, 2, false } },
- { 0x000000e0, 0x0000001c, 0x00000003, 0x00000000, { QOpenGLTexture::RGB, QOpenGLTexture::RG3B2, QOpenGLTexture::UInt8_RG3B2, 1, false } },
- { 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000, { QOpenGLTexture::RGBA, QOpenGLTexture::RGB10A2, QOpenGLTexture::UInt32_RGB10A2, 4, false } },
-
- // luminance alpha
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x00000000, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
- { 0x000000ff, 0x00000000, 0x00000000, 0x00000000, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x0000ff00, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
- { 0x000000ff, 0x00000000, 0x00000000, 0x0000ff00, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
-};
-
-const struct FourCCFormat {
- quint32 fourCC;
- FormatInfo formatInfo;
-} fourCCFormats[] = {
- { DdsFourCC<'D','X','T','1'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
- { DdsFourCC<'D','X','T','3'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT3, QOpenGLTexture::NoPixelType, 16, true } },
- { DdsFourCC<'D','X','T','5'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT5, QOpenGLTexture::NoPixelType, 16, true } },
- { DdsFourCC<'A','T','I','1'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::R_ATI1N_UNorm, QOpenGLTexture::NoPixelType, 8, true } },
- { DdsFourCC<'A','T','I','2'>::value, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RG_ATI2N_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
-};
-
-const struct DX10Format {
- DXGIFormat dxgiFormat;
- FormatInfo formatInfo;
-} dx10Formats[] = {
- // unorm formats
- { DXGI_FORMAT_R8_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
- { DXGI_FORMAT_R8G8_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
- { DXGI_FORMAT_R8G8B8A8_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
-
- { DXGI_FORMAT_R16_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R16_UNorm, QOpenGLTexture::UInt16, 2, false } },
- { DXGI_FORMAT_R16G16_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG16_UNorm, QOpenGLTexture::UInt16, 4, false } },
- { DXGI_FORMAT_R16G16B16A16_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA16_UNorm, QOpenGLTexture::UInt16, 8, false } },
-
- // snorm formats
- { DXGI_FORMAT_R8_SNORM, { QOpenGLTexture::Red, QOpenGLTexture::R8_SNorm, QOpenGLTexture::Int8, 1, false } },
- { DXGI_FORMAT_R8G8_SNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG8_SNorm, QOpenGLTexture::Int8, 2, false } },
- { DXGI_FORMAT_R8G8B8A8_SNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA8_SNorm, QOpenGLTexture::Int8, 4, false } },
-
- { DXGI_FORMAT_R16_SNORM, { QOpenGLTexture::Red, QOpenGLTexture::R16_SNorm, QOpenGLTexture::Int16, 2, false } },
- { DXGI_FORMAT_R16G16_SNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG16_SNorm, QOpenGLTexture::Int16, 4, false } },
- { DXGI_FORMAT_R16G16B16A16_SNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA16_SNorm, QOpenGLTexture::Int16, 8, false } },
-
- // unsigned integer formats
- { DXGI_FORMAT_R8_UINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R8U, QOpenGLTexture::UInt8, 1, false } },
- { DXGI_FORMAT_R8G8_UINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG8U, QOpenGLTexture::UInt8, 2, false } },
- { DXGI_FORMAT_R8G8B8A8_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA8U, QOpenGLTexture::UInt8, 4, false } },
-
- { DXGI_FORMAT_R16_UINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R16U, QOpenGLTexture::UInt16, 2, false } },
- { DXGI_FORMAT_R16G16_UINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG16U, QOpenGLTexture::UInt16, 4, false } },
- { DXGI_FORMAT_R16G16B16A16_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA16U, QOpenGLTexture::UInt16, 8, false } },
-
- { DXGI_FORMAT_R32_UINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R32U, QOpenGLTexture::UInt32, 4, false } },
- { DXGI_FORMAT_R32G32_UINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG32U, QOpenGLTexture::UInt32, 8, false } },
- { DXGI_FORMAT_R32G32B32_UINT, { QOpenGLTexture::RGB_Integer, QOpenGLTexture::RGB32U, QOpenGLTexture::UInt32, 12, false } },
- { DXGI_FORMAT_R32G32B32A32_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA32U, QOpenGLTexture::UInt32, 16, false } },
-
- // signed integer formats
- { DXGI_FORMAT_R8_SINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R8I, QOpenGLTexture::Int8, 1, false } },
- { DXGI_FORMAT_R8G8_SINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG8I, QOpenGLTexture::Int8, 2, false } },
- { DXGI_FORMAT_R8G8B8A8_SINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA8I, QOpenGLTexture::Int8, 4, false } },
-
- { DXGI_FORMAT_R16_SINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R16I, QOpenGLTexture::Int16, 2, false } },
- { DXGI_FORMAT_R16G16_SINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG16I, QOpenGLTexture::Int16, 4, false } },
- { DXGI_FORMAT_R16G16B16A16_SINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA16I, QOpenGLTexture::Int16, 8, false } },
-
- { DXGI_FORMAT_R32_SINT, { QOpenGLTexture::Red_Integer, QOpenGLTexture::R32I, QOpenGLTexture::Int32, 4, false } },
- { DXGI_FORMAT_R32G32_SINT, { QOpenGLTexture::RG_Integer, QOpenGLTexture::RG32I, QOpenGLTexture::Int32, 8, false } },
- { DXGI_FORMAT_R32G32B32_SINT, { QOpenGLTexture::RGB_Integer, QOpenGLTexture::RGB32I, QOpenGLTexture::Int32, 12, false } },
- { DXGI_FORMAT_R32G32B32A32_SINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGBA32I, QOpenGLTexture::Int32, 16, false } },
-
- // floating formats
- { DXGI_FORMAT_R16_FLOAT, { QOpenGLTexture::Red, QOpenGLTexture::R16F, QOpenGLTexture::Float16, 2, false } },
- { DXGI_FORMAT_R16G16_FLOAT, { QOpenGLTexture::RG, QOpenGLTexture::RG16F, QOpenGLTexture::Float16, 4, false } },
- { DXGI_FORMAT_R16G16B16A16_FLOAT, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA16F, QOpenGLTexture::Float16, 8, false } },
-
- { DXGI_FORMAT_R32_FLOAT, { QOpenGLTexture::Red, QOpenGLTexture::R32F, QOpenGLTexture::Float32, 4, false } },
- { DXGI_FORMAT_R32G32_FLOAT, { QOpenGLTexture::RG, QOpenGLTexture::RG32F, QOpenGLTexture::Float32, 8, false } },
- { DXGI_FORMAT_R32G32B32_FLOAT, { QOpenGLTexture::RGB, QOpenGLTexture::RGB32F, QOpenGLTexture::Float32, 12, false } },
- { DXGI_FORMAT_R32G32B32A32_FLOAT, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA32F, QOpenGLTexture::Float32, 16, false } },
-
- // sRGB formats
- { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, { QOpenGLTexture::RGB, QOpenGLTexture::SRGB8, QOpenGLTexture::UInt8, 4, false } },
- { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, { QOpenGLTexture::RGBA, QOpenGLTexture::SRGB8_Alpha8, QOpenGLTexture::UInt8, 4, false } },
-
- // packed formats
- // { DXGI_FORMAT_R10G10B10A2_UNORM, { QOpenGLTexture::RGB10A2_UNORM, QOpenGLTexture::RGBA, QOpenGLTexture::UInt32_RGB10A2, 4, false } },
- { DXGI_FORMAT_R10G10B10A2_UINT, { QOpenGLTexture::RGBA_Integer, QOpenGLTexture::RGB10A2, QOpenGLTexture::UInt32_RGB10A2, 4, false } },
- { DXGI_FORMAT_R9G9B9E5_SHAREDEXP, { QOpenGLTexture::RGB, QOpenGLTexture::RGB9E5, QOpenGLTexture::UInt32_RGB9_E5, 4, false } },
- { DXGI_FORMAT_R11G11B10_FLOAT, { QOpenGLTexture::RGB, QOpenGLTexture::RG11B10F, QOpenGLTexture::UInt32_RG11B10F, 4, false } },
- { DXGI_FORMAT_B5G6R5_UNORM, { QOpenGLTexture::RGB, QOpenGLTexture::R5G6B5, QOpenGLTexture::UInt16_R5G6B5, 2, false } },
- { DXGI_FORMAT_B5G5R5A1_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGB5A1, QOpenGLTexture::UInt16_RGB5A1, 2, false } },
- { DXGI_FORMAT_B4G4R4A4_UNORM, { QOpenGLTexture::RGBA, QOpenGLTexture::RGBA4, QOpenGLTexture::UInt16_RGBA4, 2, false } },
-
- // swizzle formats
- { DXGI_FORMAT_B8G8R8X8_UNORM, { QOpenGLTexture::BGRA, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, 4, false } },
- { DXGI_FORMAT_B8G8R8A8_UNORM, { QOpenGLTexture::BGRA, QOpenGLTexture::RGBA8_UNorm, QOpenGLTexture::UInt8, 4, false } },
- { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, { QOpenGLTexture::BGRA, QOpenGLTexture::SRGB8, QOpenGLTexture::UInt8, 4, false } },
- { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, { QOpenGLTexture::BGRA, QOpenGLTexture::SRGB8_Alpha8, QOpenGLTexture::UInt8, 4, false } },
-
- // luminance alpha formats
- { DXGI_FORMAT_R8_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R8_UNorm, QOpenGLTexture::UInt8, 1, false } },
- { DXGI_FORMAT_R8G8_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG8_UNorm, QOpenGLTexture::UInt8, 2, false } },
- { DXGI_FORMAT_R16_UNORM, { QOpenGLTexture::Red, QOpenGLTexture::R16_UNorm, QOpenGLTexture::UInt16, 2, false } },
- { DXGI_FORMAT_R16_UNORM, { QOpenGLTexture::RG, QOpenGLTexture::RG16_UNorm, QOpenGLTexture::UInt16, 4, false } },
-
- // depth formats
- { DXGI_FORMAT_D16_UNORM, { QOpenGLTexture::Depth, QOpenGLTexture::D16, QOpenGLTexture::NoPixelType, 2, false } },
- { DXGI_FORMAT_D24_UNORM_S8_UINT, { QOpenGLTexture::DepthStencil, QOpenGLTexture::D24S8, QOpenGLTexture::NoPixelType, 4, false } },
- { DXGI_FORMAT_D32_FLOAT, { QOpenGLTexture::Depth, QOpenGLTexture::D32F, QOpenGLTexture::NoPixelType, 4, false } },
- { DXGI_FORMAT_D32_FLOAT_S8X24_UINT, { QOpenGLTexture::DepthStencil, QOpenGLTexture::D32FS8X24, QOpenGLTexture::NoPixelType, 8, false } },
-
- // compressed formats
- { DXGI_FORMAT_BC1_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
- { DXGI_FORMAT_BC2_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT3, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC3_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGBA_DXT5, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC4_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::R_ATI1N_UNorm, QOpenGLTexture::NoPixelType, 8, true } },
- { DXGI_FORMAT_BC4_SNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::R_ATI1N_SNorm, QOpenGLTexture::NoPixelType, 8, true } },
- { DXGI_FORMAT_BC5_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RG_ATI2N_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC5_SNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RG_ATI2N_SNorm, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC6H_UF16, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC6H_SF16, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGB_BP_SIGNED_FLOAT, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC7_UNORM, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::RGB_BP_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
-
- // compressed sRGB formats
- { DXGI_FORMAT_BC1_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
- { DXGI_FORMAT_BC1_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_Alpha_DXT1, QOpenGLTexture::NoPixelType, 8, true } },
- { DXGI_FORMAT_BC2_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_Alpha_DXT3, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC3_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_Alpha_DXT5, QOpenGLTexture::NoPixelType, 16, true } },
- { DXGI_FORMAT_BC7_UNORM_SRGB, { QOpenGLTexture::NoSourceFormat, QOpenGLTexture::SRGB_BP_UNorm, QOpenGLTexture::NoPixelType, 16, true } },
-};
-
-} // namespace
-
QTextureImageDataPrivate::QTextureImageDataPrivate()
: m_width(-1)
, m_height(-1)
@@ -425,10 +66,12 @@ QByteArray QTextureImageDataPrivate::data(int layer, int face, int mipmapLevel)
{
if (layer < 0 || layer >= m_layers ||
face < 0 || face >= m_faces ||
- mipmapLevel < 0 || mipmapLevel >= m_mipLevels)
+ mipmapLevel < 0 || mipmapLevel >= m_mipLevels) {
+ qWarning() << Q_FUNC_INFO << "Requesting texture data for invalid layer, face or mipMapLevel";
return QByteArray();
+ }
- int offset = layer*layerSize() + face*faceSize();
+ int offset = layer * layerSize() + face * faceSize();
for (int i = 0; i < mipmapLevel; i++)
offset += mipmapLevelSize(i);
@@ -436,204 +79,18 @@ QByteArray QTextureImageDataPrivate::data(int layer, int face, int mipmapLevel)
return QByteArray::fromRawData(m_data.constData() + offset, mipmapLevelSize(mipmapLevel));
}
-void QTextureImageDataPrivate::setData(const QByteArray &data, QOpenGLTexture::PixelFormat fmt,
- QOpenGLTexture::PixelType ptype)
+void QTextureImageDataPrivate::setData(const QByteArray &data,
+ int blockSize,
+ bool isCompressed)
{
- m_isCompressed = false;
+ m_isCompressed = isCompressed;
m_data = data;
- m_layers = 1;
- m_faces = 1;
- m_mipLevels = 1;
- m_target = QOpenGLTexture::Target2D;
- m_pixelFormat = fmt;
- m_pixelType = ptype;
-}
-
-bool QTextureImageDataPrivate::setCompressedFile(const QString &source)
-{
- QString suffix = QFileInfo(source).suffix();
-
- if (suffix == QLatin1String("pkm"))
- return setPkmFile(source);
- else if (suffix == QLatin1String("dds"))
- return setDdsFile(source);
- else
- return false;
-}
-
-bool QTextureImageDataPrivate::setPkmFile(const QString &source)
-{
- QFile f(source);
- if (!f.open(QIODevice::ReadOnly)) {
- qWarning() << "Failed to open" << source;
- return false;
- }
-
- // ETC1 in PKM, as generated by f.ex. Android's etc1tool
- static const char pkmMagic[] = { 'P', 'K', 'M', ' ', '1', '0' };
- const int pkmHeaderSize = 6 + 2 + 4 * 2;
- QByteArray header = f.read(pkmHeaderSize);
- if (header.size() >= pkmHeaderSize && !qstrncmp(header.constData(), pkmMagic, 6)) {
- m_format = QOpenGLTexture::RGB8_ETC1; // may get changed to RGB8_ETC2 later on
- // get the extended (multiple of 4) width and height
- m_width = qFromBigEndian(*(reinterpret_cast<const quint16 *>(header.constData() + 6 + 2)));
- m_height = qFromBigEndian(*(reinterpret_cast<const quint16 *>(header.constData() + 6 + 2 + 2)));
- m_depth = 1;
- QByteArray data = f.readAll();
- if (data.size() < (m_width / 4) * (m_height / 4) * 8)
- qWarning() << "Unexpected end of ETC1 data in" << source;
- setData(data, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
- m_blockSize = 8;
- m_isCompressed = true;
- return true;
- }
-
- return false;
-}
-
-static int bitCount(quint32 n)
-{
- int r = 0;
-
- for (; n; n >>= 1)
- r += (n & 1);
-
- return r;
-}
-
-bool QTextureImageDataPrivate::setDdsFile(const QString &source)
-{
- QFile f(source);
- if (!f.open(QIODevice::ReadOnly)) {
- qWarning() << "Failed to open" << source;
- return false;
- }
-
- DdsHeader header;
- if (f.read(reinterpret_cast<char *>(&header), sizeof header) != sizeof header)
- return false;
-
- if (qstrncmp(header.magic, "DDS ", 4) != 0)
- return false;
-
- // dimensions
-
- m_width = qFromLittleEndian(header.width);
- m_height = qFromLittleEndian(header.height);
-
- // mip levels
-
- if ((qFromLittleEndian(header.flags) & MipmapCountFlag) == MipmapCountFlag)
- m_mipLevels = qFromLittleEndian(header.mipmapCount);
- else
- m_mipLevels = 1;
-
- // texture format
-
- m_layers = 1;
-
- const quint32 pixelFlags = qFromLittleEndian(header.pixelFormat.flags);
- const quint32 fourCC = qFromLittleEndian(header.pixelFormat.fourCC);
-
- const FormatInfo *formatInfo = nullptr;
-
- if ((pixelFlags & FourCCFlag) == FourCCFlag) {
- if (fourCC == DdsFourCC<'D', 'X', '1', '0'>::value) {
- // DX10 texture
-
- DdsDX10Header dx10Header;
- if (f.read(reinterpret_cast<char *>(&dx10Header), sizeof dx10Header) != sizeof dx10Header)
- return false;
-
- m_layers = qFromLittleEndian(dx10Header.arraySize);
-
- DXGIFormat format = static_cast<DXGIFormat>(qFromLittleEndian(dx10Header.format));
-
- for (unsigned i = 0; i < sizeof dx10Formats/sizeof *dx10Formats; i++) {
- if (dx10Formats[i].dxgiFormat == format) {
- formatInfo = &dx10Formats[i].formatInfo;
- break;
- }
- }
- } else {
- // compressed, FourCC texture
-
- for (unsigned i = 0; i < sizeof fourCCFormats/sizeof *fourCCFormats; i++) {
- if (fourCCFormats[i].fourCC == fourCC) {
- formatInfo = &fourCCFormats[i].formatInfo;
- break;
- }
- }
- }
- } else {
- // uncompressed texture
-
- m_pixelFormat = QOpenGLTexture::NoSourceFormat;
-
- const quint32 rgbBitCount = qFromLittleEndian(header.pixelFormat.rgbBitCount);
- const quint32 redMask = qFromLittleEndian(header.pixelFormat.redMask);
- const quint32 greenMask = qFromLittleEndian(header.pixelFormat.greenMask);
- const quint32 blueMask = qFromLittleEndian(header.pixelFormat.blueMask);
- const quint32 alphaMask = qFromLittleEndian(header.pixelFormat.alphaMask);
-
- for (unsigned i = 0; i < sizeof rgbaFormats/sizeof *rgbaFormats; i++) {
- const RGBAFormat *info = &rgbaFormats[i];
-
- if (info->formatInfo.components*8u == rgbBitCount &&
- info->redMask == redMask && info->greenMask == greenMask &&
- info->blueMask == blueMask && info->alphaMask == alphaMask) {
- formatInfo = &info->formatInfo;
- break;
- }
- }
- }
-
- if (formatInfo == nullptr) {
- qWarning() << "Unrecognized pixel format in" << source;
- return false;
- }
-
- m_pixelFormat = formatInfo->pixelFormat;
- m_format = formatInfo->textureFormat;
- m_pixelType = formatInfo->pixelType;
- m_blockSize = formatInfo->components;
- m_isCompressed = formatInfo->compressed;
-
- // target
-
- // XXX should worry about Target1D?
-
- const quint32 caps2Flags = qFromLittleEndian(header.caps2);
-
- if ((caps2Flags & VolumeFlag) == VolumeFlag) {
- m_target = QOpenGLTexture::Target3D;
- m_depth = qFromLittleEndian(header.depth);
- m_faces = 1;
- } else if ((caps2Flags & CubemapFlag) == CubemapFlag) {
- m_target = m_layers > 1 ? QOpenGLTexture::TargetCubeMapArray : QOpenGLTexture::TargetCubeMap;
- m_depth = 1;
- m_faces = bitCount(caps2Flags & AllCubemapFaceFlags);
- } else {
- m_target = m_layers > 1 ? QOpenGLTexture::Target2DArray : QOpenGLTexture::Target2D;
- m_depth = 1;
- m_faces = 1;
- }
-
- // data
-
- m_data = f.readAll();
-
- if (m_data.size() != m_layers*layerSize()) {
- qWarning() << "Unexpected data size (got " << m_data.size() << ", expecting" << m_layers*layerSize() << ")";
- return false;
- }
-
- return true;
+ m_blockSize = blockSize;
}
int QTextureImageDataPrivate::layerSize() const
{
- return m_faces*faceSize();
+ return m_faces * faceSize();
}
int QTextureImageDataPrivate::faceSize() const
@@ -738,6 +195,42 @@ int QTextureImageData::faces() const Q_DECL_NOTHROW
return d->m_faces;;
}
+void QTextureImageData::setWidth(int width) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_width = width;
+}
+
+void QTextureImageData::setHeight(int height) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_height = height;
+}
+
+void QTextureImageData::setDepth(int depth) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_depth = depth;
+}
+
+void QTextureImageData::setLayers(int layers) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_layers = layers;
+}
+
+void QTextureImageData::setMipLevels(int mipLevels) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_mipLevels = mipLevels;
+}
+
+void QTextureImageData::setFaces(int faces) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_faces = faces;
+}
+
QOpenGLTexture::Target QTextureImageData::target() const Q_DECL_NOTHROW
{
Q_D(const QTextureImageData);
@@ -750,33 +243,55 @@ QOpenGLTexture::TextureFormat QTextureImageData::format() const Q_DECL_NOTHROW
return d->m_format;
}
+void QTextureImageData::setTarget(QOpenGLTexture::Target target) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_target = target;
+}
+
+void QTextureImageData::setFormat(QOpenGLTexture::TextureFormat format) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_format = format;
+}
+
+void QTextureImageData::setPixelFormat(QOpenGLTexture::PixelFormat pixelFormat) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_pixelFormat = pixelFormat;
+}
+
+void QTextureImageData::setPixelType(QOpenGLTexture::PixelType pixelType) Q_DECL_NOTHROW
+{
+ Q_D(QTextureImageData);
+ d->m_pixelType = pixelType;
+}
+
void QTextureImageData::setImage(const QImage &image)
{
Q_D(QTextureImageData);
d->m_width = image.width();
d->m_height = image.height();
d->m_depth = 1;
-
+ d->m_faces = 1;
+ d->m_layers = 1;
+ d->m_mipLevels = 1;
QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
Q_ASSERT_X(glImage.bytesPerLine() == (glImage.width() * glImage.depth() + 7) / 8,
"QTextureImageData::setImage", "glImage is not packed"); // QTBUG-48330
+ d->m_blockSize = 4;
QByteArray imageBytes((const char*) glImage.constBits(), glImage.byteCount());
- setData(imageBytes, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
+ setData(imageBytes, d->m_blockSize, false);
d->m_format = QOpenGLTexture::RGBA8_UNorm;
- d->m_blockSize = 4;
-}
-
-void QTextureImageData::setData(const QByteArray &data, QOpenGLTexture::PixelFormat fmt,
- QOpenGLTexture::PixelType ptype)
-{
- Q_D(QTextureImageData);
- d->setData(data, fmt, ptype);
+ d->m_pixelFormat = QOpenGLTexture::RGBA;
+ d->m_pixelType = QOpenGLTexture::UInt8;
+ d->m_target = QOpenGLTexture::Target2D;
}
-bool QTextureImageData::setCompressedFile(const QString &source)
+void QTextureImageData::setData(const QByteArray &data, int blockSize, bool isCompressed)
{
Q_D(QTextureImageData);
- return d->setCompressedFile(source);
+ d->setData(data, blockSize, isCompressed);
}
QByteArray QTextureImageData::data(int layer, int face, int mipmapLevel) const
diff --git a/src/render/texture/qtextureimagedata.h b/src/render/texture/qtextureimagedata.h
index c1cc40593..6d66f2390 100644
--- a/src/render/texture/qtextureimagedata.h
+++ b/src/render/texture/qtextureimagedata.h
@@ -71,24 +71,32 @@ public:
int mipLevels() const Q_DECL_NOTHROW;
int faces() const Q_DECL_NOTHROW;
- QOpenGLTexture::Target target() const Q_DECL_NOTHROW;
-
- QOpenGLTexture::TextureFormat format() const Q_DECL_NOTHROW;
+ void setWidth(int width) Q_DECL_NOTHROW;
+ void setHeight(int height) Q_DECL_NOTHROW;
+ void setDepth(int depth) Q_DECL_NOTHROW;
- void setImage(const QImage &);
+ void setLayers(int layers) Q_DECL_NOTHROW;
+ void setMipLevels(int mipLevels) Q_DECL_NOTHROW;
+ void setFaces(int faces) Q_DECL_NOTHROW;
- void setData(const QByteArray &data,
- QOpenGLTexture::PixelFormat fmt,
- QOpenGLTexture::PixelType ptype);
+ QOpenGLTexture::Target target() const Q_DECL_NOTHROW;
+ QOpenGLTexture::TextureFormat format() const Q_DECL_NOTHROW;
- bool setCompressedFile(const QString &source);
+ QOpenGLTexture::PixelFormat pixelFormat() const Q_DECL_NOTHROW;
+ QOpenGLTexture::PixelType pixelType() const Q_DECL_NOTHROW;
- QByteArray data(int layer = 0, int face = 0, int mipmapLevel = 0) const;
+ void setTarget(QOpenGLTexture::Target target) Q_DECL_NOTHROW;
+ void setFormat(QOpenGLTexture::TextureFormat format) Q_DECL_NOTHROW;
- QOpenGLTexture::PixelFormat pixelFormat() const Q_DECL_NOTHROW;
+ void setPixelFormat(QOpenGLTexture::PixelFormat pixelFormat) Q_DECL_NOTHROW;
+ void setPixelType(QOpenGLTexture::PixelType pixelType) Q_DECL_NOTHROW;
- QOpenGLTexture::PixelType pixelType() const Q_DECL_NOTHROW;
+ void setImage(const QImage &);
+ void setData(const QByteArray &data,
+ int blockSize,
+ bool isCompressed = false);
+ QByteArray data(int layer = 0, int face = 0, int mipmapLevel = 0) const;
protected:
QTextureImageData(QTextureImageDataPrivate &dd);
diff --git a/src/render/texture/qtextureimagedata_p.h b/src/render/texture/qtextureimagedata_p.h
index 6d46ae1b7..4426ba27b 100644
--- a/src/render/texture/qtextureimagedata_p.h
+++ b/src/render/texture/qtextureimagedata_p.h
@@ -62,8 +62,7 @@ class QTextureImageDataPrivate
public:
QTextureImageDataPrivate();
- void setData(const QByteArray &data, QOpenGLTexture::PixelFormat fmt,
- QOpenGLTexture::PixelType ptype);
+ void setData(const QByteArray &data, int blockSize, bool isCompressed);
bool setCompressedFile(const QString &source);
diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp
index f0aef843e..387a00b3b 100644
--- a/src/render/texture/texture.cpp
+++ b/src/render/texture/texture.cpp
@@ -269,9 +269,6 @@ QOpenGLTexture *Texture::buildGLTexture()
QOpenGLTexture* glTex = new QOpenGLTexture(static_cast<QOpenGLTexture::Target>(m_target));
- if (m_format == QAbstractTexture::Automatic)
- qWarning() << Q_FUNC_INFO << "something went wrong, format shouldn't be automatic at this point";
-
// m_format may not be ES2 compatible. Now it's time to convert it, if necessary.
QAbstractTexture::TextureFormat format = m_format;
if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) {