diff options
Diffstat (limited to 'src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp')
m--------- | src/Runtime/ogl-runtime | 0 | ||||
-rw-r--r-- | src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp | 1092 |
2 files changed, 0 insertions, 1092 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime new file mode 160000 +Subproject 427fddb50d43aa21a90fc7356ee3cdd8a908df5 diff --git a/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp b/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp deleted file mode 100644 index eb23f3d0..00000000 --- a/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderBufferManager.cpp +++ /dev/null @@ -1,1092 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 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$ -** -****************************************************************************/ -#ifdef _WIN32 -#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union -#endif -#include "Qt3DSRender.h" -#include "Qt3DSRenderBufferManager.h" -#include "EASTL/string.h" -#include "foundation/Qt3DSAllocator.h" -#include "render/Qt3DSRenderContext.h" -#include "foundation/Qt3DSAtomic.h" -#include "EASTL/hash_map.h" -#include "foundation/FileTools.h" -#include "Qt3DSImportMesh.h" -#include "Qt3DSRenderMesh.h" -#include "foundation/Qt3DSAllocatorCallback.h" -#include "Qt3DSRenderLoadedTexture.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSRenderInputStreamFactory.h" -#include "Qt3DSRenderImageScaler.h" -#include "Qt3DSRenderImage.h" -#include "Qt3DSTextRenderer.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/Qt3DSMutex.h" -#include "Qt3DSRenderPrefilterTexture.h" -#include <QtCore/qdir.h> - -using namespace qt3ds::render; - -namespace { - -using eastl::hash; -using eastl::pair; -using eastl::make_pair; -typedef eastl::basic_string<char8_t, ForwardingAllocator> TStr; -struct StrHasher -{ - size_t operator()(const TStr &str) const - { - return hash<const char8_t *>()((const char8_t *)str.c_str()); - } -}; - -struct StrEq -{ - bool operator()(const TStr &lhs, const TStr &rhs) const { return lhs == rhs; } -}; - -struct SImageEntry : public SImageTextureData -{ - bool m_Loaded; - SImageEntry() - : SImageTextureData(), m_Loaded(false) - { - } - SImageEntry(const SImageEntry &entry) - : SImageTextureData(entry), m_Loaded(entry.m_Loaded) - { - - } -}; - -struct SPrimitiveEntry -{ - // Name of the primitive as it will be in the UIP file - CRegisteredString m_PrimitiveName; - // Name of the primitive file on the filesystem - CRegisteredString m_FileName; -}; - -struct SBufferManager : public IBufferManager -{ - typedef eastl::hash_set<CRegisteredString, eastl::hash<CRegisteredString>, - eastl::equal_to<CRegisteredString>, ForwardingAllocator> - TStringSet; - typedef nvhash_map<CRegisteredString, SImageEntry> TImageMap; - typedef nvhash_map<CRegisteredString, SRenderMesh *> TMeshMap; - typedef nvhash_map<CRegisteredString, CRegisteredString> TAliasImageMap; - - NVScopedRefCounted<NVRenderContext> m_Context; - NVScopedRefCounted<IStringTable> m_StrTable; - NVScopedRefCounted<IInputStreamFactory> m_InputStreamFactory; - IPerfTimer &m_PerfTimer; - volatile QT3DSI32 mRefCount; - TStr m_PathBuilder; - TImageMap m_ImageMap; - Mutex m_LoadedImageSetMutex; - TStringSet m_LoadedImageSet; - TAliasImageMap m_AliasImageMap; - TMeshMap m_MeshMap; - SPrimitiveEntry m_PrimitiveNames[5]; - nvvector<qt3ds::render::NVRenderVertexBufferEntry> m_EntryBuffer; - bool m_GPUSupportsDXT; - bool m_reloadableResources; - - QHash<QString, ReloadableTexturePtr> m_reloadableTextures; - - static const char8_t *GetPrimitivesDirectory() { return "res//primitives"; } - - SBufferManager(NVRenderContext &ctx, IStringTable &strTable, - IInputStreamFactory &inInputStreamFactory, IPerfTimer &inTimer) - : m_Context(ctx) - , m_StrTable(strTable) - , m_InputStreamFactory(inInputStreamFactory) - , m_PerfTimer(inTimer) - , mRefCount(0) - , m_PathBuilder(ForwardingAllocator(ctx.GetAllocator(), "SBufferManager::m_PathBuilder")) - , m_ImageMap(ctx.GetAllocator(), "SBufferManager::m_ImageMap") - , m_LoadedImageSetMutex(ctx.GetAllocator()) - , m_LoadedImageSet( - ForwardingAllocator(ctx.GetAllocator(), "SBufferManager::m_LoadedImageSet")) - , m_AliasImageMap(ctx.GetAllocator(), "SBufferManager::m_AliasImageMap") - , m_MeshMap(ctx.GetAllocator(), "SBufferManager::m_MeshMap") - , m_EntryBuffer(ctx.GetAllocator(), "SBufferManager::m_EntryBuffer") - , m_GPUSupportsDXT(ctx.AreDXTImagesSupported()) - , m_reloadableResources(false) - { - } - virtual ~SBufferManager() { Clear(); } - - QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Context->GetAllocator()) - - CRegisteredString CombineBaseAndRelative(const char8_t *inBase, - const char8_t *inRelative) override - { - CFileTools::CombineBaseAndRelative(inBase, inRelative, m_PathBuilder); - return m_StrTable->RegisterStr(m_PathBuilder.c_str()); - } - - void SetImageHasTransparency(CRegisteredString inImagePath, bool inHasTransparency) override - { - pair<TImageMap::iterator, bool> theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - theImage.first->second.m_TextureFlags.SetHasTransparency(inHasTransparency); - } - - bool GetImageHasTransparency(CRegisteredString inSourcePath) const override - { - TImageMap::const_iterator theIter = m_ImageMap.find(inSourcePath); - if (theIter != m_ImageMap.end()) - return theIter->second.m_TextureFlags.HasTransparency(); - return false; - } - - void SetImageTransparencyToFalseIfNotSet(CRegisteredString inSourcePath) override - { - pair<TImageMap::iterator, bool> theImage = - m_ImageMap.insert(make_pair(inSourcePath, SImageEntry())); - // If we did actually insert something - if (theImage.second) - theImage.first->second.m_TextureFlags.SetHasTransparency(false); - } - - void SetInvertImageUVCoords(CRegisteredString inImagePath, bool inShouldInvertCoords) override - { - pair<TImageMap::iterator, bool> theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - theImage.first->second.m_TextureFlags.SetInvertUVCoords(inShouldInvertCoords); - } - - bool IsImageLoaded(CRegisteredString inSourcePath) override - { - Mutex::ScopedLock __locker(m_LoadedImageSetMutex); - return m_LoadedImageSet.find(inSourcePath) != m_LoadedImageSet.end(); - } - - bool AliasImagePath(CRegisteredString inSourcePath, CRegisteredString inAliasPath, - bool inIgnoreIfLoaded) override - { - if (inSourcePath.IsValid() == false || inAliasPath.IsValid() == false) - return false; - // If the image is loaded then we ignore this call in some cases. - if (inIgnoreIfLoaded && IsImageLoaded(inSourcePath)) - return false; - m_AliasImageMap.insert(eastl::make_pair(inSourcePath, inAliasPath)); - return true; - } - - void UnaliasImagePath(CRegisteredString inSourcePath) override - { - m_AliasImageMap.erase(inSourcePath); - } - - CRegisteredString GetImagePath(CRegisteredString inSourcePath) override - { - TAliasImageMap::iterator theAliasIter = m_AliasImageMap.find(inSourcePath); - if (theAliasIter != m_AliasImageMap.end()) - return theAliasIter->second; - return inSourcePath; - } - - CRegisteredString getImagePath(const QString &path) - { - TAliasImageMap::iterator theAliasIter - = m_AliasImageMap.find(m_StrTable->RegisterStr(qPrintable(path))); - if (theAliasIter != m_AliasImageMap.end()) - return theAliasIter->second; - return m_StrTable->RegisterStr(qPrintable(path)); - } - - static inline int wrapMod(int a, int base) - { - int ret = a % base; - if (ret < 0) - ret += base; - return ret; - } - - static inline void getWrappedCoords(int &sX, int &sY, int width, int height) - { - if (sY < 0) { - sX -= width >> 1; - sY = -sY; - } - if (sY >= height) { - sX += width >> 1; - sY = height - sY; - } - sX = wrapMod(sX, width); - sY = wrapMod(sY, height); - } - - template <typename V, typename C> - void iterateAll(const V &vv, C c) - { - for (const auto x : vv) - c(x); - } - - void loadTextureImage(SReloadableImageTextureData &data) - { - CRegisteredString imagePath = getImagePath(data.m_path); - TImageMap::iterator theIter = m_ImageMap.find(imagePath); - if ((theIter == m_ImageMap.end() || theIter->second.m_Loaded == false) - && imagePath.IsValid()) { - NVScopedReleasable<SLoadedTexture> theLoadedImage; - SImageTextureData textureData; - - doImageLoad(imagePath, theLoadedImage); - - if (theLoadedImage) { - textureData = LoadRenderImage(imagePath, *theLoadedImage, data.m_scanTransparency, - data.m_bsdfMipmap); - data.m_Texture = textureData.m_Texture; - data.m_TextureFlags = textureData.m_TextureFlags; - data.m_BSDFMipMap = textureData.m_BSDFMipMap; - data.m_loaded = true; - iterateAll(data.m_callbacks, [](SImage *img){ img->m_Flags.SetDirty(true); }); - } else { - // We want to make sure that bad path fails once and doesn't fail over and over - // again which could slow down the system quite a bit. - pair<TImageMap::iterator, bool> theImage = - m_ImageMap.insert(make_pair(imagePath, SImageEntry())); - theImage.first->second.m_Loaded = true; - qCWarning(WARNING, "Failed to load image: %s", imagePath.c_str()); - theIter = theImage.first; - } - } else { - SImageEntry textureData = theIter->second; - if (textureData.m_Loaded) { - data.m_Texture = textureData.m_Texture; - data.m_TextureFlags = textureData.m_TextureFlags; - data.m_BSDFMipMap = textureData.m_BSDFMipMap; - data.m_loaded = true; - iterateAll(data.m_callbacks, [](SImage *img){ img->m_Flags.SetDirty(true); }); - } - } - } - - void unloadTextureImage(SReloadableImageTextureData &data) - { - CRegisteredString r = m_StrTable->RegisterStr(qPrintable(data.m_path)); - data.m_loaded = false; - data.m_Texture = nullptr; - data.m_BSDFMipMap = nullptr; - data.m_TextureFlags = {}; - iterateAll(data.m_callbacks, [](SImage *img){ img->m_Flags.SetDirty(true); }); - InvalidateBuffer(r); - } - - void loadSet(const QSet<QString> &imageSet) override - { - for (const auto &x : imageSet) { - if (!m_reloadableTextures.contains(x)) { - auto img = CreateReloadableImage(m_StrTable->RegisterStr(qPrintable(x)), false, - false); - img->m_initialized = false; - loadTextureImage(*m_reloadableTextures[x]); - } else if (!m_reloadableTextures[x]->m_loaded) { - loadTextureImage(*m_reloadableTextures[x]); - } - } - } - - void unloadSet(const QSet<QString> &imageSet) override - { - for (const auto &x : imageSet) { - if (m_reloadableTextures.contains(x)) { - if (m_reloadableTextures[x]->m_loaded) - unloadTextureImage(*m_reloadableTextures[x]); - } - } - } - - virtual ReloadableTexturePtr CreateReloadableImage(CRegisteredString inSourcePath, - bool inForceScanForTransparency, - bool inBsdfMipmaps) override - { - QString path = QString::fromLatin1(inSourcePath.c_str()); - const bool inserted = m_reloadableTextures.contains(path); - if (!inserted || (inserted && m_reloadableTextures[path]->m_initialized == false)) { - if (!inserted) - m_reloadableTextures.insert(path, ReloadableTexturePtr::create()); - m_reloadableTextures[path]->m_path = path; - m_reloadableTextures[path]->m_scanTransparency = inForceScanForTransparency; - m_reloadableTextures[path]->m_bsdfMipmap = inBsdfMipmaps; - m_reloadableTextures[path]->m_initialized = true; - - if (!m_reloadableResources) - loadTextureImage(*m_reloadableTextures[path]); - - CRegisteredString imagePath = getImagePath(path); - TImageMap::iterator theIter = m_ImageMap.find(imagePath); - if (theIter != m_ImageMap.end()) { - SImageEntry textureData = theIter->second; - if (textureData.m_Loaded) { - m_reloadableTextures[path]->m_Texture = textureData.m_Texture; - m_reloadableTextures[path]->m_TextureFlags = textureData.m_TextureFlags; - m_reloadableTextures[path]->m_BSDFMipMap = textureData.m_BSDFMipMap; - m_reloadableTextures[path]->m_loaded = true; - } - } - } - return m_reloadableTextures[path]; - } - - void doImageLoad(CRegisteredString inImagePath, - NVScopedReleasable<SLoadedTexture> &theLoadedImage) - { - SStackPerfTimer __perfTimer(m_PerfTimer, "Image Decompression"); - theLoadedImage = SLoadedTexture::Load( - inImagePath.c_str(), m_Context->GetFoundation(), *m_InputStreamFactory, - true, m_Context->GetRenderContextType()); - // Hackish solution to custom materials not finding their textures if they are used - // in sub-presentations. - if (!theLoadedImage) { - if (QDir(inImagePath.c_str()).isRelative()) { - QString searchPath = inImagePath.c_str(); - if (searchPath.startsWith(QLatin1String("./"))) - searchPath.prepend(QLatin1Char('.')); - int loops = 0; - while (!theLoadedImage && ++loops <= 3) { - theLoadedImage = SLoadedTexture::Load( - searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, - m_Context->GetRenderContextType()); - searchPath.prepend(QLatin1String("../")); - } - } else { - // Some textures, for example environment maps for custom materials, - // have absolute path at this point. It points to the wrong place with - // the new project structure, so we need to split it up and construct - // the new absolute path here. - QString wholePath = inImagePath.c_str(); - QStringList splitPath = wholePath.split(QLatin1String("../")); - if (splitPath.size() > 1) { - QString searchPath = splitPath.at(0) + splitPath.at(1); - int loops = 0; - while (!theLoadedImage && ++loops <= 3) { - theLoadedImage = SLoadedTexture::Load( - searchPath.toUtf8(), m_Context->GetFoundation(), - *m_InputStreamFactory, true, - m_Context->GetRenderContextType()); - searchPath = splitPath.at(0); - for (int i = 0; i < loops; i++) - searchPath.append(QLatin1String("../")); - searchPath.append(splitPath.at(1)); - } - } - } - } - } - - void enableReloadableResources(bool enable) override - { - m_reloadableResources = enable; - } - - bool isReloadableResourcesEnabled() const override - { - return m_reloadableResources; - } - - SImageTextureData LoadRenderImage(CRegisteredString inImagePath, - SLoadedTexture &inLoadedImage, - bool inForceScanForTransparency, bool inBsdfMipmaps) override - { - SStackPerfTimer __perfTimer(m_PerfTimer, "Image Upload"); - { - Mutex::ScopedLock __mapLocker(m_LoadedImageSetMutex); - m_LoadedImageSet.insert(inImagePath); - } - pair<TImageMap::iterator, bool> theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - bool wasInserted = theImage.second; - theImage.first->second.m_Loaded = true; - // inLoadedImage.EnsureMultiplerOfFour( m_Context->GetFoundation(), inImagePath.c_str() ); - - NVRenderTexture2D *theTexture = m_Context->CreateTexture2D(); - if (inLoadedImage.data) { - qt3ds::render::NVRenderTextureFormats::Enum destFormat = inLoadedImage.format; - if (inBsdfMipmaps) { - if (m_Context->GetRenderContextType() == render::NVRenderContextValues::GLES2) - destFormat = qt3ds::render::NVRenderTextureFormats::RGBA8; - else - destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F; - } - else { - theTexture->SetTextureData( - NVDataRef<QT3DSU8>((QT3DSU8 *)inLoadedImage.data, inLoadedImage.dataSizeInBytes), 0, - inLoadedImage.width, inLoadedImage.height, inLoadedImage.format, destFormat); - { - static int enable = qEnvironmentVariableIntValue("QT3DS_GENERATE_MIPMAPS"); - if (enable) { - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - theTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - theTexture->GenerateMipmaps(); - } - } - } - - if (inBsdfMipmaps - && NVRenderTextureFormats::isUncompressedTextureFormat(inLoadedImage.format)) { - theTexture->SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear); - Qt3DSRenderPrefilterTexture *theBSDFMipMap = theImage.first->second.m_BSDFMipMap; - if (theBSDFMipMap == NULL) { - theBSDFMipMap = Qt3DSRenderPrefilterTexture::Create( - m_Context, inLoadedImage.width, inLoadedImage.height, *theTexture, - destFormat, m_Context->GetFoundation()); - theImage.first->second.m_BSDFMipMap = theBSDFMipMap; - } - - if (theBSDFMipMap) { - theBSDFMipMap->Build(inLoadedImage.data, inLoadedImage.dataSizeInBytes, - inLoadedImage.format); - } - } - } else if (inLoadedImage.dds) { - theImage.first->second.m_Texture = theTexture; - bool supportsDXT = m_GPUSupportsDXT; - bool isDXT = NVRenderTextureFormats::isCompressedTextureFormat(inLoadedImage.format); - bool requiresDecompression = (supportsDXT == false && isDXT) || false; - // test code for DXT decompression - // if ( isDXT ) requiresDecompression = true; - if (requiresDecompression) { - qCWarning(WARNING, PERF_INFO, - "Image %s is DXT format which is unsupported by " - "the graphics subsystem, decompressing in CPU", - inImagePath.c_str()); - } - STextureData theDecompressedImage; - for (int idx = 0; idx < inLoadedImage.dds->numMipmaps; ++idx) { - if (inLoadedImage.dds->mipwidth[idx] && inLoadedImage.dds->mipheight[idx]) { - if (requiresDecompression == false) { - theTexture->SetTextureData( - toU8DataRef((char *)inLoadedImage.dds->data[idx], - (QT3DSU32)inLoadedImage.dds->size[idx]), - (QT3DSU8)idx, (QT3DSU32)inLoadedImage.dds->mipwidth[idx], - (QT3DSU32)inLoadedImage.dds->mipheight[idx], inLoadedImage.format); - } else { - theDecompressedImage = - inLoadedImage.DecompressDXTImage(idx, &theDecompressedImage); - - if (theDecompressedImage.data) { - theTexture->SetTextureData( - toU8DataRef((char *)theDecompressedImage.data, - (QT3DSU32)theDecompressedImage.dataSizeInBytes), - (QT3DSU8)idx, (QT3DSU32)inLoadedImage.dds->mipwidth[idx], - (QT3DSU32)inLoadedImage.dds->mipheight[idx], - theDecompressedImage.format); - } - } - } - } - if (theDecompressedImage.data) - inLoadedImage.ReleaseDecompressedTexture(theDecompressedImage); - } - if (wasInserted == true || inForceScanForTransparency) - theImage.first->second.m_TextureFlags.SetHasTransparency( - inLoadedImage.ScanForTransparency()); - theImage.first->second.m_Texture = theTexture; - return theImage.first->second; - } - - SImageTextureData LoadRenderImage(CRegisteredString inImagePath, - bool inForceScanForTransparency, bool inBsdfMipmaps) override - { - inImagePath = GetImagePath(inImagePath); - - if (!inImagePath.IsValid()) - return SImageEntry(); - - TImageMap::iterator theIter = m_ImageMap.find(inImagePath); - if (theIter == m_ImageMap.end() && inImagePath.IsValid()) { - NVScopedReleasable<SLoadedTexture> theLoadedImage; - - doImageLoad(inImagePath, theLoadedImage); - - if (theLoadedImage) { - return LoadRenderImage(inImagePath, *theLoadedImage, inForceScanForTransparency, - inBsdfMipmaps); - } else { - // We want to make sure that bad path fails once and doesn't fail over and over - // again - // which could slow down the system quite a bit. - pair<TImageMap::iterator, bool> theImage = - m_ImageMap.insert(make_pair(inImagePath, SImageEntry())); - theImage.first->second.m_Loaded = true; - qCWarning(WARNING, "Failed to load image: %s", inImagePath.c_str()); - theIter = theImage.first; - } - } - return theIter->second; - } - - qt3dsimp::SMultiLoadResult LoadPrimitive(const char8_t *inRelativePath) - { - CRegisteredString theName(m_StrTable->RegisterStr(inRelativePath)); - if (m_PrimitiveNames[0].m_PrimitiveName.IsValid() == false) { - IStringTable &strTable(m_Context->GetStringTable()); - m_PrimitiveNames[0].m_PrimitiveName = strTable.RegisterStr("#Rectangle"); - m_PrimitiveNames[0].m_FileName = strTable.RegisterStr("Rectangle.mesh"); - m_PrimitiveNames[1].m_PrimitiveName = strTable.RegisterStr("#Sphere"); - m_PrimitiveNames[1].m_FileName = strTable.RegisterStr("Sphere.mesh"); - m_PrimitiveNames[2].m_PrimitiveName = strTable.RegisterStr("#Cube"); - m_PrimitiveNames[2].m_FileName = strTable.RegisterStr("Cube.mesh"); - m_PrimitiveNames[3].m_PrimitiveName = strTable.RegisterStr("#Cone"); - m_PrimitiveNames[3].m_FileName = strTable.RegisterStr("Cone.mesh"); - m_PrimitiveNames[4].m_PrimitiveName = strTable.RegisterStr("#Cylinder"); - m_PrimitiveNames[4].m_FileName = strTable.RegisterStr("Cylinder.mesh"); - } - for (size_t idx = 0; idx < 5; ++idx) { - if (m_PrimitiveNames[idx].m_PrimitiveName == theName) { - CFileTools::CombineBaseAndRelative(GetPrimitivesDirectory(), - m_PrimitiveNames[idx].m_FileName, m_PathBuilder); - QT3DSU32 id = 1; - NVScopedRefCounted<IRefCountedInputStream> theInStream( - m_InputStreamFactory->GetStreamForFile(m_PathBuilder.c_str())); - if (theInStream) - return qt3dsimp::Mesh::LoadMulti(m_Context->GetAllocator(), *theInStream, id); - else { - qCCritical(INTERNAL_ERROR, "Unable to find mesh primitive %s", - m_PathBuilder.c_str()); - return qt3dsimp::SMultiLoadResult(); - } - } - } - return qt3dsimp::SMultiLoadResult(); - } - - virtual NVConstDataRef<QT3DSU8> CreatePackedPositionDataArray( - const qt3dsimp::SMultiLoadResult &inResult) - { - // we assume a position consists of 3 floats - QT3DSU32 vertexCount = inResult.m_Mesh->m_VertexBuffer.m_Data.size() - / inResult.m_Mesh->m_VertexBuffer.m_Stride; - QT3DSU32 dataSize = vertexCount * 3 * sizeof(QT3DSF32); - QT3DSF32 *posData = static_cast<QT3DSF32 *>( - QT3DS_ALLOC(m_Context->GetAllocator(), dataSize, - "SRenderMesh::CreatePackedPositionDataArray")); - QT3DSU8 *baseOffset = reinterpret_cast<QT3DSU8 *>(inResult.m_Mesh); - // copy position data - if (posData) { - QT3DSF32 *srcData = reinterpret_cast<QT3DSF32 *>( - inResult.m_Mesh->m_VertexBuffer.m_Data.begin(baseOffset)); - QT3DSU32 srcStride = inResult.m_Mesh->m_VertexBuffer.m_Stride / sizeof(QT3DSF32); - QT3DSF32 *dstData = posData; - QT3DSU32 dstStride = 3; - - for (QT3DSU32 i = 0; i < vertexCount; ++i) { - dstData[0] = srcData[0]; - dstData[1] = srcData[1]; - dstData[2] = srcData[2]; - - dstData += dstStride; - srcData += srcStride; - } - - return toConstDataRef(reinterpret_cast<const qt3ds::QT3DSU8 *>(posData), dataSize); - } - - return NVConstDataRef<QT3DSU8>(); - } - - SRenderMesh *createRenderMesh(const qt3dsimp::SMultiLoadResult &result) - { - SRenderMesh *theNewMesh = QT3DS_NEW(m_Context->GetAllocator(), SRenderMesh)( - qt3ds::render::NVRenderDrawMode::Triangles, - qt3ds::render::NVRenderWinding::CounterClockwise, result.m_Id, - m_Context->GetAllocator()); - QT3DSU8 *baseAddress = reinterpret_cast<QT3DSU8 *>(result.m_Mesh); - NVConstDataRef<QT3DSU8> theVBufData( - result.m_Mesh->m_VertexBuffer.m_Data.begin(baseAddress), - result.m_Mesh->m_VertexBuffer.m_Data.size()); - - NVRenderVertexBuffer *theVertexBuffer = m_Context->CreateVertexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, - result.m_Mesh->m_VertexBuffer.m_Data.m_Size, - result.m_Mesh->m_VertexBuffer.m_Stride, theVBufData); - - // create a tight packed position data VBO - // this should improve our depth pre pass rendering - NVRenderVertexBuffer *thePosVertexBuffer = nullptr; - NVConstDataRef<QT3DSU8> posData = CreatePackedPositionDataArray(result); - if (posData.size()) { - thePosVertexBuffer - = m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, - posData.size(), 3 * sizeof(QT3DSF32), posData); - } - - NVRenderIndexBuffer *theIndexBuffer = nullptr; - if (result.m_Mesh->m_IndexBuffer.m_Data.size()) { - using qt3ds::render::NVRenderComponentTypes; - QT3DSU32 theIndexBufferSize = result.m_Mesh->m_IndexBuffer.m_Data.size(); - NVRenderComponentTypes::Enum bufComponentType = - result.m_Mesh->m_IndexBuffer.m_ComponentType; - QT3DSU32 sizeofType - = qt3ds::render::NVRenderComponentTypes::getSizeofType(bufComponentType); - - if (sizeofType == 2 || sizeofType == 4) { - // Ensure type is unsigned; else things will fail in rendering pipeline. - if (bufComponentType == NVRenderComponentTypes::QT3DSI16) - bufComponentType = NVRenderComponentTypes::QT3DSU16; - if (bufComponentType == NVRenderComponentTypes::QT3DSI32) - bufComponentType = NVRenderComponentTypes::QT3DSU32; - - NVConstDataRef<QT3DSU8> theIBufData( - result.m_Mesh->m_IndexBuffer.m_Data.begin(baseAddress), - result.m_Mesh->m_IndexBuffer.m_Data.size()); - theIndexBuffer = m_Context->CreateIndexBuffer( - qt3ds::render::NVRenderBufferUsageType::Static, bufComponentType, - theIndexBufferSize, theIBufData); - } else { - QT3DS_ASSERT(false); - } - } - nvvector<qt3ds::render::NVRenderVertexBufferEntry> &theEntryBuffer(m_EntryBuffer); - theEntryBuffer.resize(result.m_Mesh->m_VertexBuffer.m_Entries.size()); - for (QT3DSU32 entryIdx = 0, - entryEnd = result.m_Mesh->m_VertexBuffer.m_Entries.size(); - entryIdx < entryEnd; ++entryIdx) { - theEntryBuffer[entryIdx] - = result.m_Mesh->m_VertexBuffer.m_Entries.index(baseAddress, entryIdx) - .ToVertexBufferEntry(baseAddress); - } - // create our attribute layout - NVRenderAttribLayout *theAttribLayout - = m_Context->CreateAttributeLayout(theEntryBuffer); - // create our attribute layout for depth pass - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry( - "attr_pos", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - }; - NVRenderAttribLayout *theAttribLayoutDepth - = m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 1)); - - // create input assembler object - QT3DSU32 strides = result.m_Mesh->m_VertexBuffer.m_Stride; - QT3DSU32 offsets = 0; - NVRenderInputAssembler *theInputAssembler = m_Context->CreateInputAssembler( - theAttribLayout, toConstDataRef(&theVertexBuffer, 1), theIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), - result.m_Mesh->m_DrawMode); - - // create depth input assembler object - QT3DSU32 posStrides = thePosVertexBuffer ? 3 * sizeof(QT3DSF32) : strides; - NVRenderInputAssembler *theInputAssemblerDepth = m_Context->CreateInputAssembler( - theAttribLayoutDepth, - toConstDataRef(thePosVertexBuffer ? &thePosVertexBuffer : &theVertexBuffer, 1), - theIndexBuffer, toConstDataRef(&posStrides, 1), toConstDataRef(&offsets, 1), - result.m_Mesh->m_DrawMode); - - NVRenderInputAssembler *theInputAssemblerPoints = m_Context->CreateInputAssembler( - theAttribLayoutDepth, - toConstDataRef(thePosVertexBuffer ? &thePosVertexBuffer : &theVertexBuffer, 1), - nullptr, toConstDataRef(&posStrides, 1), toConstDataRef(&offsets, 1), - NVRenderDrawMode::Points); - - if (!theInputAssembler || !theInputAssemblerDepth || !theInputAssemblerPoints) { - QT3DS_ASSERT(false); - return nullptr; - } - theNewMesh->m_Joints.resize(result.m_Mesh->m_Joints.size()); - for (QT3DSU32 jointIdx = 0, jointEnd = result.m_Mesh->m_Joints.size(); - jointIdx < jointEnd; ++jointIdx) { - const qt3dsimp::Joint &theImportJoint( - result.m_Mesh->m_Joints.index(baseAddress, jointIdx)); - SRenderJoint &theNewJoint(theNewMesh->m_Joints[jointIdx]); - theNewJoint.m_JointID = theImportJoint.m_JointID; - theNewJoint.m_ParentID = theImportJoint.m_ParentID; - memCopy(theNewJoint.m_invBindPose, theImportJoint.m_invBindPose, - 16 * sizeof(QT3DSF32)); - memCopy(theNewJoint.m_localToGlobalBoneSpace, - theImportJoint.m_localToGlobalBoneSpace, 16 * sizeof(QT3DSF32)); - } - - for (QT3DSU32 subsetIdx = 0, subsetEnd = result.m_Mesh->m_Subsets.size(); - subsetIdx < subsetEnd; ++subsetIdx) { - SRenderSubset theSubset(m_Context->GetAllocator()); - const qt3dsimp::MeshSubset &source( - result.m_Mesh->m_Subsets.index(baseAddress, subsetIdx)); - theSubset.m_Bounds = source.m_Bounds; - theSubset.m_Count = source.m_Count; - theSubset.m_Offset = source.m_Offset; - theSubset.m_Joints = theNewMesh->m_Joints; - theSubset.m_Name = m_StrTable->RegisterStr(source.m_Name.begin(baseAddress)); - theVertexBuffer->addRef(); - theSubset.m_VertexBuffer = theVertexBuffer; - if (thePosVertexBuffer) { - thePosVertexBuffer->addRef(); - theSubset.m_PosVertexBuffer = thePosVertexBuffer; - } - if (theIndexBuffer) { - theIndexBuffer->addRef(); - theSubset.m_IndexBuffer = theIndexBuffer; - } - theSubset.m_InputAssembler = theInputAssembler; - theSubset.m_InputAssemblerDepth = theInputAssemblerDepth; - theSubset.m_InputAssemblerPoints = theInputAssemblerPoints; - theSubset.m_PrimitiveType = result.m_Mesh->m_DrawMode; - theInputAssembler->addRef(); - theInputAssemblerDepth->addRef(); - theSubset.m_InputAssemblerPoints->addRef(); - theNewMesh->m_Subsets.push_back(theSubset); - } - // If we want to, we can break up models into sub-subsets. - // These are assumed to use the same material as the outer subset but have fewer triangles - // and should have a more exact bounding box. This sort of thing helps with using the - // frustum culling system but it is really done incorrectly. - // It should be done via some sort of oct-tree mechanism and so that the sub-subsets - // are spatially sorted and it should only be done upon save-to-binary with the - // results saved out to disk. As you can see, doing it properly requires some real - // engineering effort so it is somewhat unlikely it will ever happen. - // Or it could be done on import if someone really wants to change the mesh buffer - // format. Either way it isn't going to happen here and it isn't going to happen this way - // but this is a working example of using the technique. -#ifdef QT3DS_RENDER_GENERATE_SUB_SUBSETS - Option<qt3ds::render::NVRenderVertexBufferEntry> thePosAttrOpt - = theVertexBuffer->GetEntryByName("attr_pos"); - bool hasPosAttr = thePosAttrOpt.hasValue() - && thePosAttrOpt->m_ComponentType == qt3ds::render::NVRenderComponentTypes::QT3DSF32 - && thePosAttrOpt->m_NumComponents == 3; - - for (size_t subsetIdx = 0, subsetEnd = theNewMesh->m_Subsets.size(); - subsetIdx < subsetEnd; ++subsetIdx) { - SRenderSubset &theOuterSubset = theNewMesh->m_Subsets[subsetIdx]; - if (theOuterSubset.m_Count && theIndexBuffer - && theIndexBuffer->GetComponentType() - == qt3ds::render::NVRenderComponentTypes::QT3DSU16 - && theNewMesh->m_DrawMode == NVRenderDrawMode::Triangles && hasPosAttr) { - // Num tris in a sub subset. - QT3DSU32 theSubsetSize = 3334 * 3; // divisible by three. - size_t theNumSubSubsets = ((theOuterSubset.m_Count - 1) / theSubsetSize) + 1; - QT3DSU32 thePosAttrOffset = thePosAttrOpt->m_FirstItemOffset; - const QT3DSU8 *theVertData = result.m_Mesh->m_VertexBuffer.m_Data.begin(); - const QT3DSU8 *theIdxData = result.m_Mesh->m_IndexBuffer.m_Data.begin(); - QT3DSU32 theVertStride = result.m_Mesh->m_VertexBuffer.m_Stride; - QT3DSU32 theOffset = theOuterSubset.m_Offset; - QT3DSU32 theCount = theOuterSubset.m_Count; - for (size_t subSubsetIdx = 0, subSubsetEnd = theNumSubSubsets; - subSubsetIdx < subSubsetEnd; ++subSubsetIdx) { - SRenderSubsetBase theBase; - theBase.m_Offset = theOffset; - theBase.m_Count = NVMin(theSubsetSize, theCount); - theBase.m_Bounds.setEmpty(); - theCount -= theBase.m_Count; - theOffset += theBase.m_Count; - // Create new bounds. - // Offset is in item size, not bytes. - const QT3DSU16 *theSubsetIdxData - = reinterpret_cast<const QT3DSU16 *>(theIdxData + theBase.m_Offset * 2); - for (size_t theIdxIdx = 0, theIdxEnd = theBase.m_Count; - theIdxIdx < theIdxEnd; ++theIdxIdx) { - QT3DSU32 theVertOffset = theSubsetIdxData[theIdxIdx] * theVertStride; - theVertOffset += thePosAttrOffset; - QT3DSVec3 thePos = *( - reinterpret_cast<const QT3DSVec3 *>(theVertData + theVertOffset)); - theBase.m_Bounds.include(thePos); - } - theOuterSubset.m_SubSubsets.push_back(theBase); - } - } else { - SRenderSubsetBase theBase; - theBase.m_Bounds = theOuterSubset.m_Bounds; - theBase.m_Count = theOuterSubset.m_Count; - theBase.m_Offset = theOuterSubset.m_Offset; - theOuterSubset.m_SubSubsets.push_back(theBase); - } - } -#endif - if (posData.size()) { - m_Context->GetAllocator().deallocate( - static_cast<void *>(const_cast<qt3ds::QT3DSU8 *>(posData.begin()))); - } - - return theNewMesh; - } - - void loadCustomMesh(const QString &name, qt3dsimp::Mesh *mesh) override - { - if (!name.isEmpty() && mesh) { - CRegisteredString meshName = m_StrTable->RegisterStr(name); - pair<TMeshMap::iterator, bool> theMesh - = m_MeshMap.insert({ meshName, static_cast<SRenderMesh *>(nullptr) }); - // Only create the mesh if it doesn't yet exist - if (theMesh.second) { - qt3dsimp::SMultiLoadResult result; - result.m_Mesh = mesh; - theMesh.first->second = createRenderMesh(result); - } - } - } - - SRenderMesh *LoadMesh(CRegisteredString inMeshPath) override - { - if (inMeshPath.IsValid() == false) - return nullptr; - pair<TMeshMap::iterator, bool> theMesh = - m_MeshMap.insert(make_pair(inMeshPath, static_cast<SRenderMesh *>(nullptr))); - if (theMesh.second) { - // Check to see if this is primitive - qt3dsimp::SMultiLoadResult theResult = LoadPrimitive(inMeshPath); - - // Attempt a load from the filesystem if this mesh isn't a primitive. - if (!theResult.m_Mesh) { - m_PathBuilder = inMeshPath; - TStr::size_type pound = m_PathBuilder.rfind('#'); - QT3DSU32 id = 0; - if (pound != TStr::npos) { - id = QT3DSU32(atoi(m_PathBuilder.c_str() + pound + 1)); - m_PathBuilder.erase(m_PathBuilder.begin() + pound, m_PathBuilder.end()); - } - NVScopedRefCounted<IRefCountedInputStream> theStream( - m_InputStreamFactory->GetStreamForFile(m_PathBuilder.c_str())); - if (theStream) { - theResult = qt3dsimp::Mesh::LoadMulti( - m_Context->GetAllocator(), *theStream, id); - } - if (!theResult.m_Mesh) - qCWarning(WARNING, "Failed to load mesh: %s", m_PathBuilder.c_str()); - } - - if (theResult.m_Mesh) { - theMesh.first->second = createRenderMesh(theResult); - m_Context->GetAllocator().deallocate(theResult.m_Mesh); - } - } - return theMesh.first->second; - } - - SRenderMesh *CreateMesh(Qt3DSBCharPtr inSourcePath, QT3DSU8 *inVertData, QT3DSU32 inNumVerts, - QT3DSU32 inVertStride, QT3DSU32 *inIndexData, QT3DSU32 inIndexCount, - qt3ds::NVBounds3 inBounds) override - { - CRegisteredString sourcePath = m_StrTable->RegisterStr(inSourcePath); - - // eastl::pair<CRegisteredString, SRenderMesh*> thePair(sourcePath, (SRenderMesh*)NULL); - pair<TMeshMap::iterator, bool> theMesh; - // Make sure there isn't already a buffer entry for this mesh. - if (m_MeshMap.contains(sourcePath)) { - theMesh = make_pair<TMeshMap::iterator, bool>(m_MeshMap.find(sourcePath), true); - } else { - theMesh = m_MeshMap.insert(make_pair(sourcePath, (SRenderMesh *)NULL)); - } - - if (theMesh.second == true) { - SRenderMesh *theNewMesh = QT3DS_NEW(m_Context->GetAllocator(), SRenderMesh)( - qt3ds::render::NVRenderDrawMode::Triangles, - qt3ds::render::NVRenderWinding::CounterClockwise, 0, m_Context->GetAllocator()); - - // If we failed to create the RenderMesh, return a failure. - if (!theNewMesh) { - QT3DS_ASSERT(false); - return NULL; - } - - // Get rid of any old mesh that was sitting here and fill it with a new one. - // NOTE : This is assuming that the source of our mesh data doesn't do its own memory - // management and always returns new buffer pointers every time. - // Don't know for sure if that's what we'll get from our intended sources, but that's - // easily - // adjustable by looking for matching pointers in the Subsets. - if (theNewMesh && theMesh.first->second != NULL) { - delete theMesh.first->second; - theMesh.first->second = NULL; - } - - theMesh.first->second = theNewMesh; - QT3DSU32 vertDataSize = inNumVerts * inVertStride; - NVConstDataRef<QT3DSU8> theVBufData(inVertData, vertDataSize); - // NVConstDataRef<QT3DSU8> theVBufData( theResult.m_Mesh->m_VertexBuffer.m_Data.begin( - // baseAddress ) - // , theResult.m_Mesh->m_VertexBuffer.m_Data.size() ); - - NVRenderVertexBuffer *theVertexBuffer = - m_Context->CreateVertexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, - vertDataSize, inVertStride, theVBufData); - NVRenderIndexBuffer *theIndexBuffer = NULL; - if (inIndexData != NULL && inIndexCount > 3) { - NVConstDataRef<QT3DSU8> theIBufData((QT3DSU8 *)inIndexData, inIndexCount * sizeof(QT3DSU32)); - theIndexBuffer = - m_Context->CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Static, - qt3ds::render::NVRenderComponentTypes::QT3DSU32, - inIndexCount * sizeof(QT3DSU32), theIBufData); - } - - // WARNING - // Making an assumption here about the contents of the stream - // PKC TODO : We may have to consider some other format. - qt3ds::render::NVRenderVertexBufferEntry theEntries[] = { - qt3ds::render::NVRenderVertexBufferEntry("attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3), - qt3ds::render::NVRenderVertexBufferEntry( - "attr_uv", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 2, 12), - qt3ds::render::NVRenderVertexBufferEntry( - "attr_norm", qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3, 18), - }; - - // create our attribute layout - NVRenderAttribLayout *theAttribLayout = - m_Context->CreateAttributeLayout(toConstDataRef(theEntries, 3)); - /* - // create our attribute layout for depth pass - qt3ds::render::NVRenderVertexBufferEntry theEntriesDepth[] = { - qt3ds::render::NVRenderVertexBufferEntry( "attr_pos", - qt3ds::render::NVRenderComponentTypes::QT3DSF32, 3 ), - }; - NVRenderAttribLayout* theAttribLayoutDepth = m_Context->CreateAttributeLayout( - toConstDataRef( theEntriesDepth, 1 ) ); - */ - // create input assembler object - QT3DSU32 strides = inVertStride; - QT3DSU32 offsets = 0; - NVRenderInputAssembler *theInputAssembler = m_Context->CreateInputAssembler( - theAttribLayout, toConstDataRef(&theVertexBuffer, 1), theIndexBuffer, - toConstDataRef(&strides, 1), toConstDataRef(&offsets, 1), - qt3ds::render::NVRenderDrawMode::Triangles); - - if (!theInputAssembler) { - QT3DS_ASSERT(false); - return NULL; - } - - // Pull out just the mesh object name from the total path - eastl::string fullName(inSourcePath); - eastl::string subName(inSourcePath); - if (fullName.rfind("#") != eastl::string::npos) { - subName = fullName.substr(fullName.rfind("#"), eastl::string::npos); - } - - theNewMesh->m_Joints.clear(); - SRenderSubset theSubset(m_Context->GetAllocator()); - theSubset.m_Bounds = inBounds; - theSubset.m_Count = inIndexCount; - theSubset.m_Offset = 0; - theSubset.m_Joints = theNewMesh->m_Joints; - theSubset.m_Name = m_StrTable->RegisterStr(subName.c_str()); - theVertexBuffer->addRef(); - theSubset.m_VertexBuffer = theVertexBuffer; - theSubset.m_PosVertexBuffer = NULL; - if (theIndexBuffer) - theIndexBuffer->addRef(); - theSubset.m_IndexBuffer = theIndexBuffer; - theSubset.m_InputAssembler = theInputAssembler; - theSubset.m_InputAssemblerDepth = theInputAssembler; - theSubset.m_InputAssemblerPoints = theInputAssembler; - theSubset.m_PrimitiveType = qt3ds::render::NVRenderDrawMode::Triangles; - theSubset.m_InputAssembler->addRef(); - theSubset.m_InputAssemblerDepth->addRef(); - theSubset.m_InputAssemblerPoints->addRef(); - theNewMesh->m_Subsets.push_back(theSubset); - } - - return theMesh.first->second; - } - - void ReleaseMesh(SRenderMesh &inMesh) - { - for (QT3DSU32 subsetIdx = 0, subsetEnd = inMesh.m_Subsets.size(); subsetIdx < subsetEnd; - ++subsetIdx) { - inMesh.m_Subsets[subsetIdx].m_VertexBuffer->release(); - if (inMesh.m_Subsets[subsetIdx].m_PosVertexBuffer) // can be NULL - inMesh.m_Subsets[subsetIdx].m_PosVertexBuffer->release(); - if (inMesh.m_Subsets[subsetIdx].m_IndexBuffer) // can be NULL - inMesh.m_Subsets[subsetIdx].m_IndexBuffer->release(); - inMesh.m_Subsets[subsetIdx].m_InputAssembler->release(); - inMesh.m_Subsets[subsetIdx].m_InputAssemblerDepth->release(); - if (inMesh.m_Subsets[subsetIdx].m_InputAssemblerPoints) - inMesh.m_Subsets[subsetIdx].m_InputAssemblerPoints->release(); - } - NVDelete(m_Context->GetAllocator(), &inMesh); - } - void ReleaseTexture(SImageEntry &inEntry) - { - if (inEntry.m_Texture) - inEntry.m_Texture->release(); - if (inEntry.m_BSDFMipMap) - inEntry.m_BSDFMipMap->release(); - } - void Clear() override - { - m_reloadableTextures.clear(); - for (TMeshMap::iterator iter = m_MeshMap.begin(), end = m_MeshMap.end(); iter != end; - ++iter) { - SRenderMesh *theMesh = iter->second; - if (theMesh) - ReleaseMesh(*theMesh); - } - m_MeshMap.clear(); - for (TImageMap::iterator iter = m_ImageMap.begin(), end = m_ImageMap.end(); iter != end; - ++iter) { - SImageEntry &theEntry = iter->second; - ReleaseTexture(theEntry); - } - m_ImageMap.clear(); - m_AliasImageMap.clear(); - { - Mutex::ScopedLock __locker(m_LoadedImageSetMutex); - m_LoadedImageSet.clear(); - } - } - void InvalidateBuffer(CRegisteredString inSourcePath) override - { - { - TMeshMap::iterator iter = m_MeshMap.find(inSourcePath); - if (iter != m_MeshMap.end()) { - if (iter->second) - ReleaseMesh(*iter->second); - m_MeshMap.erase(iter); - return; - } - } - { - TImageMap::iterator iter = m_ImageMap.find(inSourcePath); - if (iter != m_ImageMap.end()) { - SImageEntry &theEntry = iter->second; - ReleaseTexture(theEntry); - m_ImageMap.erase(inSourcePath); - { - Mutex::ScopedLock __locker(m_LoadedImageSetMutex); - m_LoadedImageSet.erase(inSourcePath); - } - } - } - } - IStringTable &GetStringTable() override { return *m_StrTable; } -}; -} - -IBufferManager &IBufferManager::Create(NVRenderContext &inRenderContext, IStringTable &inStrTable, - IInputStreamFactory &inFactory, IPerfTimer &inPerfTimer) -{ - return *QT3DS_NEW(inRenderContext.GetAllocator(), SBufferManager)(inRenderContext, inStrTable, - inFactory, inPerfTimer); -} |