diff options
15 files changed, 81 insertions, 30 deletions
diff --git a/src/engine/Qt3DSRenderRuntimeBinding.cpp b/src/engine/Qt3DSRenderRuntimeBinding.cpp index a8107a4..28c5403 100644 --- a/src/engine/Qt3DSRenderRuntimeBinding.cpp +++ b/src/engine/Qt3DSRenderRuntimeBinding.cpp @@ -206,6 +206,11 @@ struct Qt3DSRenderScene : public Q3DStudio::IScene return m_Presentation->m_preferKTX; } + bool flipCompressedTextures() const override + { + return m_Presentation->m_flipCompressedTextures; + } + // Update really just adds objects to the dirty set bool Update() { @@ -948,12 +953,14 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, toConstDataRef(theSourcePathList.data(), theSourcePathList.size()), CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() .GetRenderContextType(), - theScene->m_Presentation->m_preferKTX, false); + theScene->m_Presentation->m_preferKTX, false, + theScene->m_Presentation->m_flipCompressedTextures); QT3DSU64 iblImageBatchId = m_Context->m_Context->GetImageBatchLoader().LoadImageBatch( toConstDataRef(iblList.data(), iblList.size()), CRegisteredString(), nullptr, m_Context->m_Context->GetRenderContext() .GetRenderContextType(), - theScene->m_Presentation->m_preferKTX, true); + theScene->m_Presentation->m_preferKTX, true, + theScene->m_Presentation->m_flipCompressedTextures); m_Context->m_Context->GetImageBatchLoader().BlockUntilLoaded( static_cast<TImageBatchId>(imageBatchId)); m_Context->m_Context->GetImageBatchLoader().BlockUntilLoaded( diff --git a/src/runtime/Qt3DSApplication.cpp b/src/runtime/Qt3DSApplication.cpp index 04065c3..cb8f732 100644 --- a/src/runtime/Qt3DSApplication.cpp +++ b/src/runtime/Qt3DSApplication.cpp @@ -324,6 +324,7 @@ struct STextureUploadRenderTask : public IRenderTask, public IImageLoadListener IBufferManager &m_bufferManager; NVRenderContextType m_type; bool m_preferKtx; + bool m_flipCompressedTextures; QSet<QString> m_uploadSet; QSet<QString> m_uploadWaitSet; QSet<QString> m_deleteSet; @@ -335,8 +336,9 @@ struct STextureUploadRenderTask : public IRenderTask, public IImageLoadListener .GetAllocator()) STextureUploadRenderTask(IImageBatchLoader &loader, IBufferManager &mgr, - NVRenderContextType type, bool preferKtx) + NVRenderContextType type, bool preferKtx, bool flipCompressedTextures) : m_batchLoader(loader), m_bufferManager(mgr), m_type(type), m_preferKtx(preferKtx), + m_flipCompressedTextures(flipCompressedTextures), mRefCount(0) { @@ -368,7 +370,7 @@ struct STextureUploadRenderTask : public IRenderTask, public IImageLoadListener this, m_type, m_preferKtx, false); if (id) { m_batchLoader.BlockUntilLoaded(id); - m_bufferManager.loadSet(m_uploadWaitSet); + m_bufferManager.loadSet(m_uploadWaitSet, m_flipCompressedTextures); m_uploadWaitSet.clear(); } } @@ -1857,7 +1859,9 @@ struct SApp : public IApplication STextureUploadRenderTask(rc.GetImageBatchLoader(), rc.GetBufferManager(), rc.GetRenderContext().GetRenderContextType(), - GetPrimaryPresentation()->GetScene()->preferKtx())); + GetPrimaryPresentation()->GetScene()->preferKtx(), + GetPrimaryPresentation()->GetScene() + ->flipCompressedTextures())); m_uploadRenderTask->add(m_createSet, true); m_RuntimeFactory->GetQt3DSRenderContext().GetRenderList() .AddRenderTask(*m_uploadRenderTask); diff --git a/src/runtime/Qt3DSIScene.h b/src/runtime/Qt3DSIScene.h index f754196..38f705e 100644 --- a/src/runtime/Qt3DSIScene.h +++ b/src/runtime/Qt3DSIScene.h @@ -144,6 +144,8 @@ public: // Base Interface virtual bool preferKtx() const = 0; + virtual bool flipCompressedTextures() const = 0; + virtual void GetActiveSubPresentations(QVector<qt3ds::foundation::CRegisteredString> &subs) = 0; virtual qt3ds::NVAllocatorCallback &allocator() = 0; diff --git a/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp b/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp index 0789d51..b9215d6 100644 --- a/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp +++ b/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp @@ -431,7 +431,7 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator vertexShader << "\tvec2 " << m_ImageTemp << " = getTransformedUVCoords( vec3( " << m_TexCoordTemp << ", 1.0), uTransform, vTransform );" << Endl; if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - vertexShader << "\t" << m_ImageTemp << ".y = 1.0 - " << m_ImageFragCoords << ".y;" + vertexShader << "\t" << m_ImageTemp << ".y = 1.0 - " << m_ImageTemp << ".y;" << Endl; vertexShader.AssignOutput(m_ImageFragCoords.c_str(), m_ImageTemp.c_str()); diff --git a/src/runtimerender/Qt3DSRenderUIPLoader.cpp b/src/runtimerender/Qt3DSRenderUIPLoader.cpp index 24e4c18..df02e78 100644 --- a/src/runtimerender/Qt3DSRenderUIPLoader.cpp +++ b/src/runtimerender/Qt3DSRenderUIPLoader.cpp @@ -1699,6 +1699,7 @@ struct SRenderUIPLoader : public IDOMReferenceResolver QT3DS_ASSERT(success); } m_Reader.Att("preferKTX", m_Presentation->m_preferKTX); + m_Reader.Att("flipCompressedTextures", m_Presentation->m_flipCompressedTextures); } } { diff --git a/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp b/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp index 1910d70..69cc35b 100644 --- a/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp +++ b/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp @@ -67,7 +67,7 @@ static void HandleOffscreenResult(SImage &theImage, SImageTextureData &newImage, } bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager &inRenderManager, - IRenderPluginManager &inPluginManager, bool forIbl) + IRenderPluginManager &inPluginManager, bool forIbl, bool flipCompressed) { bool wasDirty = m_Flags.IsDirty(); @@ -103,7 +103,7 @@ bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager m_LoadedTextureData->m_callbacks.removeOne(this); forIbl = forIbl || m_MappingMode == ImageMappingModes::LightProbe; m_LoadedTextureData = inBufferManager.CreateReloadableImage(m_ImagePath, false, - forIbl); + forIbl, flipCompressed); m_LoadedTextureData->m_callbacks.push_back(this); } if (m_LoadedTextureData) { diff --git a/src/runtimerender/graphobjects/Qt3DSRenderImage.h b/src/runtimerender/graphobjects/Qt3DSRenderImage.h index 9b71d3f..26b4377 100644 --- a/src/runtimerender/graphobjects/Qt3DSRenderImage.h +++ b/src/runtimerender/graphobjects/Qt3DSRenderImage.h @@ -89,7 +89,8 @@ namespace render { // Or finds the image. // and sets up the texture transform bool ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager &inRenderManager, - IRenderPluginManager &pluginManager, bool forIbl = false); + IRenderPluginManager &pluginManager, bool forIbl = false, + bool flipCompressed = false); void CalculateTextureTransform(); diff --git a/src/runtimerender/graphobjects/Qt3DSRenderPresentation.h b/src/runtimerender/graphobjects/Qt3DSRenderPresentation.h index 2403e3b..f777347 100644 --- a/src/runtimerender/graphobjects/Qt3DSRenderPresentation.h +++ b/src/runtimerender/graphobjects/Qt3DSRenderPresentation.h @@ -54,6 +54,7 @@ namespace render { QT3DSVec2 m_PresentationDimensions; RenderRotationValues::Enum m_PresentationRotation; bool m_preferKTX; + bool m_flipCompressedTextures; SScene *m_Scene; CRegisteredString m_PresentationDirectory; @@ -63,6 +64,7 @@ namespace render { , m_PresentationDimensions(800, 400) , m_PresentationRotation(RenderRotationValues::NoRotation) , m_preferKTX(false) + , m_flipCompressedTextures(false) , m_Scene(NULL) { } @@ -72,6 +74,7 @@ namespace render { , m_PresentationDimensions(w, h) , m_PresentationRotation(RenderRotationValues::NoRotation) , m_preferKTX(preferKTX) + , m_flipCompressedTextures(false) , m_Scene(NULL) , m_PresentationDirectory(presDir) { diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp index eb768d3..45839e0 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp @@ -603,7 +603,8 @@ namespace render { IOffscreenRenderManager &theOffscreenRenderManager( qt3dsContext.GetOffscreenRenderManager()); IRenderPluginManager &theRenderPluginManager(qt3dsContext.GetRenderPluginManager()); - if (inImage.ClearDirty(bufferManager, theOffscreenRenderManager, theRenderPluginManager)) + if (inImage.ClearDirty(bufferManager, theOffscreenRenderManager, theRenderPluginManager, + false, m_Layer.m_Scene->m_Presentation->m_flipCompressedTextures)) ioFlags |= RenderPreparationResultFlagValues::Dirty; // All objects with offscreen renderers are pickable so we can pass the pick through to the diff --git a/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp b/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp index b07f16b..20b0738 100644 --- a/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp +++ b/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp @@ -265,7 +265,7 @@ struct SBufferManager : public IBufferManager c(x); } - void loadTextureImage(SReloadableImageTextureData &data) + void loadTextureImage(SReloadableImageTextureData &data, bool flipCompressed = false) { CRegisteredString imagePath = getImagePath(data.m_path); TImageMap::iterator theIter = m_ImageMap.find(imagePath); @@ -274,7 +274,7 @@ struct SBufferManager : public IBufferManager NVScopedReleasable<SLoadedTexture> theLoadedImage; SImageTextureData textureData; - doImageLoad(imagePath, theLoadedImage); + doImageLoad(imagePath, theLoadedImage, flipCompressed); if (theLoadedImage) { textureData = LoadRenderImage(imagePath, *theLoadedImage, data.m_scanTransparency, @@ -316,12 +316,12 @@ struct SBufferManager : public IBufferManager InvalidateBuffer(r); } - void loadSet(const QSet<QString> &imageSet) override + void loadSet(const QSet<QString> &imageSet, bool flipCompressed) override { for (const auto &x : imageSet) { if (!m_reloadableTextures.contains(x)) { auto img = CreateReloadableImage(m_StrTable->RegisterStr(qPrintable(x)), false, - false); + false, flipCompressed); img->m_initialized = false; loadTextureImage(*m_reloadableTextures[x]); } else if (!m_reloadableTextures[x]->m_loaded) { @@ -340,9 +340,20 @@ struct SBufferManager : public IBufferManager } } + void reloadAll(bool flipCompressed) override + { + for (const auto &tx : qAsConst(m_reloadableTextures)) { + if (tx->m_loaded) { + unloadTextureImage(*tx.data()); + loadTextureImage(*tx.data(), flipCompressed); + } + } + } + virtual ReloadableTexturePtr CreateReloadableImage(CRegisteredString inSourcePath, bool inForceScanForTransparency, - bool inBsdfMipmaps) override + bool inBsdfMipmaps, + bool flipCompressed) override { QString path = QString::fromLatin1(inSourcePath.c_str()); const bool inserted = m_reloadableTextures.contains(path); @@ -354,10 +365,11 @@ struct SBufferManager : public IBufferManager m_reloadableTextures[path]->m_bsdfMipmap = inBsdfMipmaps; m_reloadableTextures[path]->m_initialized = true; + #ifndef LEGACY_ASTC_LOADING if (!m_reloadableResources) #endif - loadTextureImage(*m_reloadableTextures[path]); + loadTextureImage(*m_reloadableTextures[path], flipCompressed); CRegisteredString imagePath = getImagePath(path); TImageMap::iterator theIter = m_ImageMap.find(imagePath); @@ -375,12 +387,13 @@ struct SBufferManager : public IBufferManager } void doImageLoad(CRegisteredString inImagePath, - NVScopedReleasable<SLoadedTexture> &theLoadedImage) + NVScopedReleasable<SLoadedTexture> &theLoadedImage, + bool inFlipCompressed = false) { QT3DS_PERF_SCOPED_TIMER(m_PerfTimer, "BufferManager: Image Decompression") theLoadedImage = SLoadedTexture::Load( inImagePath.c_str(), m_Context->GetFoundation(), *m_InputStreamFactory, - true, m_Context->GetRenderContextType(), false, this); + true, inFlipCompressed, m_Context->GetRenderContextType(), false, this); // Hackish solution to custom materials not finding their textures if they are used // in sub-presentations. if (!theLoadedImage) { @@ -392,7 +405,7 @@ struct SBufferManager : public IBufferManager while (!theLoadedImage && ++loops <= 3) { theLoadedImage = SLoadedTexture::Load( searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, + *m_InputStreamFactory, true, false, m_Context->GetRenderContextType(), false, this); searchPath.prepend(QLatin1String("../")); } @@ -409,7 +422,7 @@ struct SBufferManager : public IBufferManager while (!theLoadedImage && ++loops <= 3) { theLoadedImage = SLoadedTexture::Load( searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, + *m_InputStreamFactory, true, false, m_Context->GetRenderContextType(), false, this); searchPath = splitPath.at(0); for (int i = 0; i < loops; i++) diff --git a/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h b/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h index b8cd49b..0debd9c 100644 --- a/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h +++ b/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.h @@ -95,12 +95,14 @@ namespace render { virtual ReloadableTexturePtr CreateReloadableImage(CRegisteredString inSourcePath, bool inForceScanForTransparency = false, - bool inBsdfMipmaps = false) = 0; + bool inBsdfMipmaps = false, + bool flipCompressed = false) = 0; virtual void enableReloadableResources(bool enable) = 0; virtual bool isReloadableResourcesEnabled() const = 0; - virtual void loadSet(const QSet<QString> &imageSet) = 0; + virtual void loadSet(const QSet<QString> &imageSet, bool flipCompressed = false) = 0; virtual void unloadSet(const QSet<QString> &imageSet) = 0; + virtual void reloadAll(bool flipCompressed) = 0; virtual void loadCustomMesh(const QString &name, qt3dsimp::Mesh *mesh) = 0; virtual SRenderMesh *LoadMesh(CRegisteredString inSourcePath) = 0; diff --git a/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp b/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp index 8c3f929..5289351 100644 --- a/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp +++ b/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.cpp @@ -109,6 +109,7 @@ struct SImageLoaderBatch QT3DSU32 m_NumImages; NVRenderContextType m_contextType; bool m_preferKTX; + bool m_flipCompressedTextures; bool m_ibl; // Called from main thread @@ -117,13 +118,14 @@ struct SImageLoaderBatch CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, NVRenderContextType contextType, - bool preferKTX, bool ibl); + bool preferKTX, bool iblImage, + bool flipCompressedTextures); // Called from main thread SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, const TLoadingImageList &inImageList, TImageBatchId inBatchId, QT3DSU32 inImageCount, NVRenderContextType contextType, - bool preferKTX, bool ibl); + bool preferKTX, bool ibl, bool flipCompressedTextures); // Called from main thread ~SImageLoaderBatch(); @@ -263,7 +265,8 @@ struct SBatchLoader : public IImageBatchLoader CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, NVRenderContextType contextType, - bool preferKTX, bool iblImages) override + bool preferKTX, bool iblImages, + bool flipCompressedTextures) override { if (inSourcePaths.size() == 0) return 0; @@ -279,7 +282,7 @@ struct SBatchLoader : public IImageBatchLoader SImageLoaderBatch *theBatch(SImageLoaderBatch::CreateLoaderBatch( *this, theBatchId, inSourcePaths, inImageTillLoaded, inListener, contextType, - preferKTX, iblImages)); + preferKTX, iblImages, flipCompressedTextures)); if (theBatch) { m_Batches.insert(eastl::make_pair(theBatchId, theBatch)); return theBatchId; @@ -387,6 +390,7 @@ 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_flipCompressedTextures, theThis->m_Batch->m_contextType, theThis->m_Batch->m_preferKTX, &theThis->m_Batch->m_Loader.m_BufferManager); @@ -432,7 +436,8 @@ SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBat CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, NVRenderContextType contextType, - bool preferKTX, bool iblImages) + bool preferKTX, bool iblImages, + bool flipCompressedTextures) { TLoadingImageList theImages; QT3DSU32 theLoadingImageCount = 0; @@ -470,7 +475,7 @@ SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBat (SImageLoaderBatch *)inLoader.m_BatchPool.allocate(__FILE__, __LINE__); new (theBatch) SImageLoaderBatch(inLoader, inListener, theImages, inBatchId, theLoadingImageCount, - contextType, preferKTX, iblImages); + contextType, preferKTX, iblImages, flipCompressedTextures); return theBatch; } return NULL; @@ -479,7 +484,7 @@ SImageLoaderBatch::CreateLoaderBatch(SBatchLoader &inLoader, TImageBatchId inBat SImageLoaderBatch::SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener *inLoadListener, const TLoadingImageList &inImageList, TImageBatchId inBatchId, QT3DSU32 inImageCount, NVRenderContextType contextType, - bool preferKTX, bool ibl) + bool preferKTX, bool ibl, bool flipCompressedTextures) : m_Loader(inLoader) , m_LoadListener(inLoadListener) , m_LoadEvent(inLoader.m_Foundation.getAllocator()) @@ -492,6 +497,7 @@ SImageLoaderBatch::SImageLoaderBatch(SBatchLoader &inLoader, IImageLoadListener , m_contextType(contextType) , m_preferKTX(preferKTX) , m_ibl(ibl) + , m_flipCompressedTextures(flipCompressedTextures) { for (TLoadingImageList::iterator iter = m_Images.begin(), end = m_Images.end(); iter != end; ++iter) { diff --git a/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h b/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h index 2805940..64caa21 100644 --- a/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h +++ b/src/runtimerender/resourcemanager/Qt3DSRenderImageBatchLoader.h @@ -73,7 +73,8 @@ namespace render { CRegisteredString inImageTillLoaded, IImageLoadListener *inListener, NVRenderContextType type, - bool preferKTX, bool iblImages) = 0; + bool preferKTX, bool iblImages, + bool flipCompressedTextures = false) = 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/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp b/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp index e88931a..b47ade1 100644 --- a/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp +++ b/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.cpp @@ -912,6 +912,7 @@ void SLoadedTexture::ReleaseDecompressedTexture(STextureData inImage) SLoadedTexture *SLoadedTexture::Load(const QString &inPath, NVFoundationBase &inFoundation, IInputStreamFactory &inFactory, bool inFlipY, + bool inFlipCompressed, NVRenderContextType renderContextType, bool preferKTX, IBufferManager *bufferManager) { @@ -958,8 +959,16 @@ SLoadedTexture *SLoadedTexture::Load(const QString &inPath, NVFoundationBase &in } else if (path.endsWith(QLatin1String("hdr"), Qt::CaseInsensitive)) { theLoadedImage = LoadHDR(*theStream, inFoundation, renderContextType); } else if (path.endsWith(QLatin1String("ktx"), Qt::CaseInsensitive)) { + // We need to flip y coordinate in shader as it cannot be done at load time for + // compressed textures. + bufferManager->SetInvertImageUVCoords(bufferManager->GetStringTable().RegisterStr(path), + inFlipCompressed); theLoadedImage = LoadKTX(*theStream, inFlipY, inFoundation, renderContextType); } else if (path.endsWith(QLatin1String("astc"), Qt::CaseInsensitive)) { + // We need to flip y coordinate in shader as it cannot be done at load time for + // compressed textures. + bufferManager->SetInvertImageUVCoords(bufferManager->GetStringTable().RegisterStr(path), + inFlipCompressed); theLoadedImage = LoadASTC(fileName, inFlipY, inFoundation, renderContextType); } else { qCWarning(INTERNAL_ERROR, "Unrecognized image extension: %s", qPrintable(inPath)); diff --git a/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h b/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h index 8d65c1f..44d07de 100644 --- a/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h +++ b/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTexture.h @@ -154,6 +154,7 @@ namespace render { static SLoadedTexture *Load(const QString &inPath, NVFoundationBase &inAllocator, IInputStreamFactory &inFactory, bool inFlipY = true, + bool inFlipCompressed = false, NVRenderContextType renderContextType = NVRenderContextValues::NullContext, bool preferKTX = false, |