diff options
author | Antti Määttä <antti.maatta@qt.io> | 2019-04-05 12:41:53 +0300 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2019-04-09 06:05:01 +0000 |
commit | 4ab49546f539734f5c86d08cf56f37fe9e86c4ff (patch) | |
tree | 19f96d2434bd3af7a01ecbfa2037e334dd6c5e46 /src/Runtime | |
parent | 57ae437d1c01dea34a2ac5b1c2a74e81312fa051 (diff) |
Add support for KTX textures
Task-number: QT3DS-3205
Change-Id: If54d1404b934c6ae7de704884ba0afdf71419170
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Runtime')
14 files changed, 645 insertions, 66 deletions
diff --git a/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro b/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro index eeb3e4b0..e004a44d 100644 --- a/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro +++ b/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro @@ -160,7 +160,8 @@ SOURCES += \ ../Source/UIPParser/Source/Qt3DSUIPParserActionHelper.cpp \ ../Source/UIPParser/Source/Qt3DSUIPParserImpl.cpp \ ../Source/UIPParser/Source/Qt3DSUIPParserObjectRefHelper.cpp \ - ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp + ../Source/Qt3DSRuntimeRender/Source/Qt3DSRenderContextCore.cpp \ + ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp HEADERS += \ ../Source/Qt3DSFoundation/Include/foundation/ConvertUTF.h \ @@ -444,7 +445,8 @@ HEADERS += \ ../Source/Engine/Include/Qt3DSPluginDLL.h \ ../Source/Engine/Include/Qt3DSWindowSystem.h \ ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderContextCore.h \ - ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h + ../Source/Qt3DSRuntimeRender/Include/Qt3DSRenderLightConstantProperties.h \ + ../Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h win32 { SOURCES += \ diff --git a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp index 39558a25..b70bd48e 100644 --- a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp +++ b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp @@ -769,7 +769,7 @@ struct Qt3DSRenderScene : public Q3DStudio::IScene { return static_cast<Q3DStudio::INT32>(m_Context->GetImageBatchLoader().LoadImageBatch( toConstDataRef(inFullPaths, (QT3DSU32)inNumPaths), inDefaultImage, inLoadCallback, - m_Context->GetRenderContext().GetRenderContextType())); + m_Context->GetRenderContext().GetRenderContextType(), m_Presentation->m_preferKTX)); } void RegisterOffscreenRenderer(const char *inKey) override @@ -1018,8 +1018,9 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, // Fire off parallel loading of the source paths QT3DSU64 imageBatchId = m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), - CRegisteredString(), NULL, m_Context->m_Context->GetRenderContext() - .GetRenderContextType()); + CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() + .GetRenderContextType(), + theScene->m_Presentation->m_preferKTX); m_Context->m_Context->GetImageBatchLoader().BlockUntilLoaded( static_cast<TImageBatchId>(imageBatchId)); @@ -1182,14 +1183,22 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, } } + bool pktx = false; + for (int i = 0; i < m_Scenes.size(); ++i) { + if (m_Scenes[i].second->m_Presentation->m_preferKTX) { + pktx = true; + break; + } + } + { SStackPerfTimer __perfTimer(m_Context->m_CoreContext->GetPerfTimer(), "Initial Batch Image Load"); m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), - CRegisteredString(), NULL, m_Context->m_Context->GetRenderContext() - .GetRenderContextType()); + CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() + .GetRenderContextType(), pktx); } { diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h index 945d5084..c988b2f1 100644 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h +++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h @@ -325,38 +325,84 @@ struct NVRenderRenderBufferFormats } }; -#define QT3DS_RENDER_ITERATE_TEXTURE_FORMATS \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32I) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32UI) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8A8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB565) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA5551) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Alpha8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance16) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(LuminanceAlpha8) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA16F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG16F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA32F) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R11G11B10) \ - QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB9E5) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT1) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_DXT1) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT3) \ - QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT5) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth16) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24) \ - QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth32) \ +#define QT3DS_RENDER_ITERATE_TEXTURE_FORMATS \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32I) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32UI) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8A8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB565) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA5551) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Alpha8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance16) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(LuminanceAlpha8) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG16F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA32F) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R11G11B10) \ + QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB9E5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_DXT1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT3) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC1) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_PunchThrough_Alpha1_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_PunchThrough_Alpha1_ETC2) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA8_ETC2_EAC) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ETC2_EAC) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_SNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNSIGNED_FLOAT) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_SIGNED_FLOAT) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNorm) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_4x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x12) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_4x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x4) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x5) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x6) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x8) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x10) \ + QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x12) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth16) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24) \ + QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth32) \ QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24Stencil8) struct NVRenderTextureFormats diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h index da28e154..32f7dad7 100644 --- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h +++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h @@ -116,6 +116,82 @@ namespace render { #define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 #endif +#ifndef GL_ETC1_RGB8_OES +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +#ifndef GL_COMPRESSED_RED_RGTC1 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#endif + +#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#endif + +#ifndef GL_COMPRESSED_RG_RGTC2 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#endif + +#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#endif + +#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#endif + +#ifndef GL_COMPRESSED_RGB8_ETC2 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ETC2 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#endif + +#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#endif + +#ifndef GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#endif + +#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#endif + +#ifndef GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#endif + +#ifndef GL_COMPRESSED_R11_EAC +#define GL_COMPRESSED_R11_EAC 0x9270 +#endif + +#ifndef GL_COMPRESSED_SIGNED_R11_EAC +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#endif + +#ifndef GL_COMPRESSED_RG11_EAC +#define GL_COMPRESSED_RG11_EAC 0x9272 +#endif + +#ifndef GL_COMPRESSED_SIGNED_RG11_EAC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#endif + #define QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC \ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ZERO, Zero) \ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE, One) \ @@ -1040,6 +1116,100 @@ namespace render { return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; case NVRenderTextureFormats::RGBA_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case NVRenderTextureFormats::R_ATI1N_UNorm: + return GL_COMPRESSED_RED_RGTC1; + case NVRenderTextureFormats::R_ATI1N_SNorm: + return GL_COMPRESSED_SIGNED_RED_RGTC1; + case NVRenderTextureFormats::RG_ATI2N_UNorm: + return GL_COMPRESSED_RG_RGTC2; + case NVRenderTextureFormats::RG_ATI2N_SNorm: + return GL_COMPRESSED_SIGNED_RG_RGTC2; + case NVRenderTextureFormats::RGB_BP_UNSIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_SIGNED_FLOAT: + return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB; + case NVRenderTextureFormats::RGB_BP_UNorm: + return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + case NVRenderTextureFormats::R11_EAC_UNorm: + return GL_COMPRESSED_R11_EAC; + case NVRenderTextureFormats::R11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_R11_EAC; + case NVRenderTextureFormats::RG11_EAC_UNorm: + return GL_COMPRESSED_RG11_EAC; + case NVRenderTextureFormats::RG11_EAC_SNorm: + return GL_COMPRESSED_SIGNED_RG11_EAC; + case NVRenderTextureFormats::RGB8_ETC2: + return GL_COMPRESSED_RGB8_ETC2; + case NVRenderTextureFormats::SRGB8_ETC2: + return GL_COMPRESSED_SRGB8_ETC2; + case NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2: + return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + case NVRenderTextureFormats::RGBA8_ETC2_EAC: + return GL_COMPRESSED_RGBA8_ETC2_EAC; + case NVRenderTextureFormats::SRGB8_Alpha8_ETC2_EAC: + return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + case NVRenderTextureFormats::RGB8_ETC1: + return GL_ETC1_RGB8_OES; +#ifdef GL_KHR_texture_compression_astc_hdr + case NVRenderTextureFormats::RGBA_ASTC_4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x4: + return GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + case NVRenderTextureFormats::RGBA_ASTC_5x5: + return GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x5: + return GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_6x6: + return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x5: + return GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x6: + return GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_8x8: + return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x5: + return GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x6: + return GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x8: + return GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + case NVRenderTextureFormats::RGBA_ASTC_10x10: + return GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x10: + return GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + case NVRenderTextureFormats::RGBA_ASTC_12x12: + return GL_COMPRESSED_RGBA_ASTC_12x12_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_4x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x4: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x5: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x6: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x8: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x10: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR; + case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x12: + return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; +#endif // GL_KHR_texture_compression_astc_hdr default: break; } diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h index da1a5da4..2403e3b8 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderPresentation.h @@ -53,6 +53,7 @@ namespace render { { QT3DSVec2 m_PresentationDimensions; RenderRotationValues::Enum m_PresentationRotation; + bool m_preferKTX; SScene *m_Scene; CRegisteredString m_PresentationDirectory; @@ -61,14 +62,16 @@ namespace render { : SGraphObject(GraphObjectTypes::Presentation) , m_PresentationDimensions(800, 400) , m_PresentationRotation(RenderRotationValues::NoRotation) + , m_preferKTX(false) , m_Scene(NULL) { } - SPresentation(QT3DSF32 w, QT3DSF32 h, CRegisteredString presDir) + SPresentation(QT3DSF32 w, QT3DSF32 h, bool preferKTX, CRegisteredString presDir) : SGraphObject(GraphObjectTypes::Presentation) , m_PresentationDimensions(w, h) , m_PresentationRotation(RenderRotationValues::NoRotation) + , m_preferKTX(preferKTX) , m_Scene(NULL) , m_PresentationDirectory(presDir) { @@ -88,4 +91,4 @@ namespace render { } } -#endif
\ No newline at end of file +#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp index e1cb67d2..37ca281f 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderBufferManager.cpp @@ -233,8 +233,8 @@ struct SBufferManager : public IBufferManager } SImageTextureData LoadRenderImage(CRegisteredString inImagePath, - SLoadedTexture &inLoadedImage, - bool inForceScanForTransparency, bool inBsdfMipmaps) override + SLoadedTexture &inLoadedImage, + bool inForceScanForTransparency, bool inBsdfMipmaps) override { SStackPerfTimer __perfTimer(m_PerfTimer, "Image Upload"); { diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp index d5e0bdd1..8f1cb14f 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.cpp @@ -108,18 +108,21 @@ struct SImageLoaderBatch QT3DSU32 m_FinalizedImageCount; QT3DSU32 m_NumImages; NVRenderContextType m_contextType; + bool m_preferKTX; // Called from main thread static SImageLoaderBatch *CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBatchId, NVConstDataRef<CRegisteredString> inSourcePaths, CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, - NVRenderContextType contextType); + NVRenderContextType contextType, + bool preferKTX); // Called from main thread SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, const TLoadingImageList &inImageList, TImageBatchId inBatchId, - QT3DSU32 inImageCount, NVRenderContextType contextType); + QT3DSU32 inImageCount, NVRenderContextType contextType, + bool preferKTX); // Called from main thread ~SImageLoaderBatch(); @@ -258,7 +261,8 @@ struct SBatchLoader : public IImageBatchLoader TImageBatchId LoadImageBatch(NVConstDataRef<CRegisteredString> inSourcePaths, CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, - NVRenderContextType contextType) override + NVRenderContextType contextType, + bool preferKTX) override { if (inSourcePaths.size() == 0) return 0; @@ -273,7 +277,7 @@ struct SBatchLoader : public IImageBatchLoader } SImageLoaderBatch *theBatch(SImageLoaderBatch::CreateLoaderBatch( - *this, theBatchId, inSourcePaths, inImageTillLoaded, inListener, contextType)); + *this, theBatchId, inSourcePaths, inImageTillLoaded, inListener, contextType, preferKTX)); if (theBatch) { m_Batches.insert(eastl::make_pair(theBatchId, theBatch)); return theBatchId; @@ -376,7 +380,8 @@ void SLoadingImage::LoadImage(void *inImg) SLoadedTexture *theTexture = SLoadedTexture::Load( theThis->m_SourcePath.c_str(), theThis->m_Batch->m_Loader.m_Foundation, theThis->m_Batch->m_Loader.m_InputStreamFactory, true, - theThis->m_Batch->m_contextType); + theThis->m_Batch->m_contextType, + theThis->m_Batch->m_preferKTX); // if ( theTexture ) // theTexture->EnsureMultiplerOfFour( theThis->m_Batch->m_Loader.m_Foundation, //theThis->m_SourcePath.c_str() ); @@ -424,7 +429,8 @@ SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBat NVConstDataRef<CRegisteredString> inSourcePaths, CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, - NVRenderContextType contextType) + NVRenderContextType contextType, + bool preferKTX) { TLoadingImageList theImages; QT3DSU32 theLoadingImageCount = 0; @@ -462,7 +468,7 @@ SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBat (SImageLoaderBatch *)inLoader.m_BatchPool.allocate(__FILE__, __LINE__); new (theBatch) SImageLoaderBatch(inLoader, inListener, theImages, inBatchId, theLoadingImageCount, - contextType); + contextType, preferKTX); return theBatch; } return NULL; @@ -470,7 +476,8 @@ SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBat SImageLoaderBatch::SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, const TLoadingImageList &inImageList, TImageBatchId inBatchId, - QT3DSU32 inImageCount, NVRenderContextType contextType) + QT3DSU32 inImageCount, NVRenderContextType contextType, + bool preferKTX) : m_Loader(inLoader) , m_LoadListener(inLoadListener) , m_LoadEvent(inLoader.m_Foundation.getAllocator()) @@ -481,6 +488,7 @@ SImageLoaderBatch::SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener , m_FinalizedImageCount(0) , m_NumImages(inImageCount) , m_contextType(contextType) + , m_preferKTX(preferKTX) { for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; ++iter) { diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h index 58847f91..d45123f1 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderImageBatchLoader.h @@ -72,7 +72,8 @@ namespace render { virtual TImageBatchId LoadImageBatch(NVConstDataRef<CRegisteredString> inSourcePaths, CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, - NVRenderContextType type) = 0; + NVRenderContextType type, + bool preferKTX) = 0; // Blocks if any of the images in the batch are in flight virtual void CancelImageBatchLoading(TImageBatchId inBatchId) = 0; // Blocks if the image is currently in-flight diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp index 2b10f159..3365a2ce 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.cpp @@ -652,31 +652,49 @@ void SLoadedTexture::ReleaseDecompressedTexture(STextureData inImage) SLoadedTexture *SLoadedTexture::Load(const QString &inPath, NVFoundationBase &inFoundation, IInputStreamFactory &inFactory, bool inFlipY, - NVRenderContextType renderContextType) + NVRenderContextType renderContextType, bool preferKTX) { if (inPath.isEmpty()) return nullptr; + // Check KTX path first + QString path = inPath; + QString ktxSource = inPath; + if (preferKTX) { + ktxSource = ktxSource.left(ktxSource.lastIndexOf(QLatin1Char('.'))); + ktxSource.append(QLatin1String(".ktx")); + } + SLoadedTexture *theLoadedImage = nullptr; // We will get invalid error logs of files not found if we don't force quiet mode // If the file is actually missing, it will be logged later (loaded image is null) - NVScopedRefCounted<IRefCountedInputStream> theStream(inFactory.GetStreamForFile(inPath, true)); + NVScopedRefCounted<IRefCountedInputStream> theStream( + inFactory.GetStreamForFile(preferKTX ? ktxSource : inPath, true)); + if (!theStream.mPtr) { + if (!preferKTX) + theStream = inFactory.GetStreamForFile(inPath, true); + else + return nullptr; + } else { + path = ktxSource; + } QString fileName; - inFactory.GetPathForFile(inPath, fileName, true); - if (theStream.mPtr && inPath.size() > 3) { - if (inPath.endsWith("png", Qt::CaseInsensitive) - || inPath.endsWith("jpg", Qt::CaseInsensitive) - || inPath.endsWith("peg", Qt::CaseInsensitive) - || inPath.endsWith("ktx", Qt::CaseInsensitive)) { + inFactory.GetPathForFile(path, fileName, true); + if (theStream.mPtr && path.size() > 3) { + if (path.endsWith(QLatin1String("png"), Qt::CaseInsensitive) + || path.endsWith(QLatin1String("jpg"), Qt::CaseInsensitive) + || path.endsWith(QLatin1String("peg"), Qt::CaseInsensitive)) { theLoadedImage = LoadQImage(fileName, inFlipY, inFoundation, renderContextType); - } else if (inPath.endsWith("dds", Qt::CaseInsensitive)) { + } else if (path.endsWith(QLatin1String("dds"), Qt::CaseInsensitive)) { theLoadedImage = LoadDDS(*theStream, inFlipY, inFoundation, renderContextType); - } else if (inPath.endsWith("gif", Qt::CaseInsensitive)) { + } else if (path.endsWith(QLatin1String("gif"), Qt::CaseInsensitive)) { theLoadedImage = LoadGIF(*theStream, !inFlipY, inFoundation, renderContextType); - } else if (inPath.endsWith("bmp", Qt::CaseInsensitive)) { + } else if (path.endsWith(QLatin1String("bmp"), Qt::CaseInsensitive)) { theLoadedImage = LoadBMP(*theStream, !inFlipY, inFoundation, renderContextType); - } else if (inPath.endsWith("hdr", Qt::CaseInsensitive)) { + } else if (path.endsWith(QLatin1String("hdr"), Qt::CaseInsensitive)) { theLoadedImage = LoadHDR(*theStream, inFoundation, renderContextType); + } else if (path.endsWith(QLatin1String("ktx"), Qt::CaseInsensitive)) { + theLoadedImage = LoadKTX(*theStream, inFlipY, inFoundation, renderContextType); } else { qCWarning(INTERNAL_ERROR, "Unrecognized image extension: %s", qPrintable(inPath)); } diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h index 475f92a8..f0194000 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTexture.h @@ -154,10 +154,13 @@ namespace render { static SLoadedTexture *Load(const QString &inPath, NVFoundationBase &inAllocator, IInputStreamFactory &inFactory, bool inFlipY = true, NVRenderContextType renderContextType - = NVRenderContextValues::NullContext); + = NVRenderContextValues::NullContext, bool preferKTX = false); static SLoadedTexture *LoadDDS(IInStream &inStream, QT3DSI32 flipVertical, NVFoundationBase &fnd, NVRenderContextType renderContextType); + static SLoadedTexture *LoadKTX(IInStream &inStream, QT3DSI32 flipVertical, + NVFoundationBase &fnd, + NVRenderContextType renderContextType); static SLoadedTexture *LoadBMP(ISeekableIOStream &inStream, bool inFlipY, NVFoundationBase &inFnd, NVRenderContextType renderContextType); diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h index 97cc77f5..8490b474 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureDDS.h @@ -65,8 +65,10 @@ namespace render { int numMipmaps; /** If nonzero, then the file contains 6 cubemap faces */ int cubemap; - /** The GL format of the loaded texture data */ + /** The format of the loaded texture data */ int format; + /** The GL internal format of the loaded texture data(compressed textures only) */ + int internalFormat; /** Nonzero if the texture data includes alpha */ int alpha; /** Base of the allocated block of all texel data */ diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp new file mode 100644 index 00000000..b1d4b050 --- /dev/null +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "foundation/Qt3DSFoundation.h" +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "Qt3DSRenderLoadedTextureKTX.h" +#include "Qt3DSRenderLoadedTextureDDS.h" + +#include <qendian.h> +#include <qopengltexture.h> + +using namespace qt3ds::render; +using namespace qt3ds::foundation; + +namespace qt3ds { +namespace render { + +static inline int blockSizeForTextureFormat(int format) +{ + switch (format) { + case QOpenGLTexture::RGB8_ETC1: + case QOpenGLTexture::RGB8_ETC2: + case QOpenGLTexture::SRGB8_ETC2: + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::R11_EAC_UNorm: + case QOpenGLTexture::R11_EAC_SNorm: + case QOpenGLTexture::RGB_DXT1: + return 8; + + default: + return 16; + } +} + +static inline int runtimeFormat(quint32 internalFormat) +{ + switch (internalFormat) { + case QOpenGLTexture::RGB8_ETC1: + return NVRenderTextureFormats::RGB8_ETC1; + case QOpenGLTexture::RGB8_ETC2: + return NVRenderTextureFormats::RGB8_ETC2; + case QOpenGLTexture::SRGB8_ETC2: + return NVRenderTextureFormats::SRGB8_ETC2; + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + return NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2; + case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: + return NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2; + case QOpenGLTexture::R11_EAC_UNorm: + return NVRenderTextureFormats::R11_EAC_UNorm; + case QOpenGLTexture::R11_EAC_SNorm: + return NVRenderTextureFormats::R11_EAC_SNorm; + case QOpenGLTexture::RGB_DXT1: + return NVRenderTextureFormats::RGB_DXT1; + case QOpenGLTexture::RGBA_DXT1: + return NVRenderTextureFormats::RGBA_DXT3; + case QOpenGLTexture::RGBA_DXT3: + return NVRenderTextureFormats::RGBA_DXT3; + case QOpenGLTexture::RGBA_DXT5: + return NVRenderTextureFormats::RGBA_DXT5; + default: + break; + } + return NVRenderTextureFormats::Unknown; +} + +static inline int imageSize(QT3DSI32 width, QT3DSI32 height, const Qt3DSDDSImage *image) +{ + return ((width + 3) / 4) * ((height + 3) / 4) + * blockSizeForTextureFormat(image->internalFormat); +} + +static inline quint32 totalImageDataSize(Qt3DSDDSImage *image) +{ + int i, j; + int index = 0; + quint32 size = 0; + int w, h; + int cubeCount = image->cubemap ? 6 : 1; + + for (j = 0; j < cubeCount; j++) { + w = image->width; + h = image->height; + + for (i = 0; i < image->numMipmaps; i++) // account for base plus each mip + { + size += 4; // image size is saved in the file + image->size[index] = imageSize(w, h, image); + image->mipwidth[index] = w; + image->mipheight[index] = h; + size += quint32(image->size[index]); + if (w != 1) + w >>= 1; + if (h != 1) + h >>= 1; + + index++; + } + } + + return (size); +} + +static inline quint32 alignedOffset(quint32 offset, quint32 byteAlign) +{ + return (offset + byteAlign - 1) & ~(byteAlign - 1); +} + +inline SLoadedTexture *loadKtx(NVAllocatorCallback &allocator, IInStream &inStream, + QT3DSI32 flipVertical) +{ + static const int KTX_IDENTIFIER_LENGTH = 12; + static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { + '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' + }; + static const quint32 platformEndianIdentifier = 0x04030201; + static const quint32 inversePlatformEndianIdentifier = 0x01020304; + + struct KTXHeader { + quint8 identifier[KTX_IDENTIFIER_LENGTH]; + quint32 endianness; + quint32 glType; + quint32 glTypeSize; + quint32 glFormat; + quint32 glInternalFormat; + quint32 glBaseInternalFormat; + quint32 pixelWidth; + quint32 pixelHeight; + quint32 pixelDepth; + quint32 numberOfArrayElements; + quint32 numberOfFaces; + quint32 numberOfMipmapLevels; + quint32 bytesOfKeyValueData; + }; + + KTXHeader header; + if (inStream.Read(header) != sizeof(header) + || qstrncmp(reinterpret_cast<char *>(header.identifier), + ktxIdentifier, KTX_IDENTIFIER_LENGTH) != 0 + || (header.endianness != platformEndianIdentifier + && header.endianness != inversePlatformEndianIdentifier)) { + return nullptr; + } + + const bool isInverseEndian = (header.endianness == inversePlatformEndianIdentifier); + auto decode = [isInverseEndian](quint32 val) { + return isInverseEndian ? qbswap<quint32>(val) : val; + }; + + const bool isCompressed = decode(header.glType) == 0 && decode(header.glFormat) == 0 + && decode(header.glTypeSize) == 1; + if (!isCompressed) { + qWarning("Uncompressed ktx texture data is not supported"); + return nullptr; + } + + if (decode(header.numberOfArrayElements) != 0) { + qWarning("Array ktx textures not supported"); + return nullptr; + } + + if (decode(header.pixelDepth) != 0) { + qWarning("Only 2D and cube ktx textures are supported"); + return nullptr; + } + + const int bytesToSkip = int(decode(header.bytesOfKeyValueData)); + QVector<uint8_t> skipData; + skipData.resize(bytesToSkip); + if (inStream.Read(NVDataRef<uint8_t>(skipData.data(), bytesToSkip)) != bytesToSkip) { + qWarning("Unexpected end of ktx data"); + return nullptr; + } + + // now for each mipmap level we have (arrays and 3d textures not supported here) + // uint32 imageSize + // for each array element + // for each face + // for each z slice + // compressed data + // padding so that each face data starts at an offset that is a multiple of 4 + // padding so that each imageSize starts at an offset that is a multiple of 4 + + Qt3DSDDSImage *image = (Qt3DSDDSImage *)QT3DS_ALLOC(allocator, sizeof(Qt3DSDDSImage), "DoLoadDDS"); + + const quint32 level0Width = decode(header.pixelWidth); + const quint32 level0Height = decode(header.pixelHeight); + quint32 faceCount = decode(header.numberOfFaces); + const quint32 mipMapLevels = decode(header.numberOfMipmapLevels); + const quint32 format = decode(header.glInternalFormat); + image->numMipmaps = int(mipMapLevels); + image->cubemap = faceCount == 6 ? 6 : 0; + image->internalFormat = int(format); + image->format = runtimeFormat(format); + image->width = int(level0Width); + image->height = int(level0Height); + image->compressed = 1; + quint32 totalSize = totalImageDataSize(image); + image->dataBlock = QT3DS_ALLOC(allocator, totalSize, "Qt3DSDDSAllocDataBlock"); + if (inStream.Read(NVDataRef<uint8_t>(reinterpret_cast<uint8_t*>(image->dataBlock), totalSize)) + != totalSize) { + QT3DS_FREE(allocator, image); + return nullptr; + } + + SLoadedTexture *result = QT3DS_NEW(allocator, SLoadedTexture)(allocator); + result->dds = image; + result->width = int(level0Width); + result->height = int(level0Height); + result->format = static_cast<NVRenderTextureFormats::Enum>(image->format); + + // TODO: Proper support for cubemaps should be implemented at some point. + if (faceCount > 1) { + qWarning("Multiple faces (cubemaps) not currently supported in ktx"); + faceCount = 1; + } + + uint8_t *p = reinterpret_cast<uint8_t *>(image->dataBlock); + uint8_t *basep = p; + + for (quint32 mip = 0; mip < mipMapLevels; ++mip) { + if (p + 4 - basep > totalSize) + break; + const quint32 imageSize = *reinterpret_cast<const quint32 *>(p); + p += 4; + for (quint32 face = 0; face < faceCount; ++face) { + const quint32 nextOffset = quint32(p + imageSize - basep); + if (nextOffset > totalSize) + break; + image->data[mip] = reinterpret_cast<void *>(p); + p = basep + alignedOffset(nextOffset, 4); + } + } + + return result; +} + +SLoadedTexture *SLoadedTexture::LoadKTX(IInStream &inStream, QT3DSI32 flipVertical, + NVFoundationBase &inFnd, + qt3ds::render::NVRenderContextType renderContextType) +{ + Q_UNUSED(renderContextType) + SLoadedTexture *retval = loadKtx(inFnd.getAllocator(), inStream, flipVertical); + + return retval; +} + +} +} diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h new file mode 100644 index 00000000..3a2d7628 --- /dev/null +++ b/src/Runtime/Source/Qt3DSRuntimeRender/ResourceManager/Qt3DSRenderLoadedTextureKTX.h @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DS_RENDER_LOAD_KTX_H +#define QT3DS_RENDER_LOAD_KTX_H + +namespace qt3ds { +namespace render { + +} +} + +#endif diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp index 55eac14a..63341c9e 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp @@ -1614,6 +1614,7 @@ struct SRenderUIPLoader : public IDOMReferenceResolver (void)success; QT3DS_ASSERT(success); } + m_Reader.Att("preferKTX", m_Presentation->m_preferKTX); } } { |