From 7ee97f3489bb1cba4095e58d4aa5241de772dc7b Mon Sep 17 00:00:00 2001 From: Janne Kangas Date: Fri, 7 Feb 2020 11:32:25 +0200 Subject: Add size and format to textureid query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returns texture size and format for layer and material textures. Add corresponding test. Task-id: QT3DS-4005 Change-Id: I773715712dc78cf511f6c4d0095f5491834df311 Reviewed-by: Antti Määttä Reviewed-by: Miikka Heikkinen Reviewed-by: Tomi Korpipää --- src/api/studio3d/q3dspresentation.cpp | 19 +++++++ src/api/studio3d/q3dspresentation.h | 2 + src/engine/Qt3DSRuntimeView.cpp | 17 ++++++ src/engine/Qt3DSRuntimeView.h | 1 + src/runtime/Qt3DSIScriptBridge.h | 3 ++ src/runtime/Qt3DSQmlEngine.cpp | 34 ++++++++++++ src/runtimerender/Qt3DSRenderer.h | 5 ++ .../rendererimpl/Qt3DSRendererImpl.cpp | 34 ++++++++++++ src/runtimerender/rendererimpl/Qt3DSRendererImpl.h | 5 +- src/viewer/Qt3DSViewerApp.cpp | 10 ++++ src/viewer/Qt3DSViewerApp.h | 2 + .../q3dssurfaceviewer/tst_q3dssurfaceviewer.cpp | 60 +++++++++++++++++++++ .../shared/maps/OpenfootageNET_garage-512.hdr | Bin 0 -> 422659 bytes .../auto/studio3d/shared/shared_presentations.qrc | 1 + 14 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 tests/auto/studio3d/shared/maps/OpenfootageNET_garage-512.hdr diff --git a/src/api/studio3d/q3dspresentation.cpp b/src/api/studio3d/q3dspresentation.cpp index 0270e42..e6cc423 100644 --- a/src/api/studio3d/q3dspresentation.cpp +++ b/src/api/studio3d/q3dspresentation.cpp @@ -1024,6 +1024,25 @@ uint Q3DSPresentation::textureId(const QString &elementPath) return 0; } +/*! + \since Qt 3D Studio 2.7 + Returns the OpenGL texture id associated with a layer or an image specified + by \a elementPath. Texture \a size and \a format are returned in corresponding parameters. + + For example, \c{Scene.Layer} returns the texture id of a layer while + \c{Scene.Layer.Rectangle.Material.diffusemap} returns the texture id of + an image or a subpresentation. + */ +uint Q3DSPresentation::textureId(const QString &elementPath, QSize &size, GLenum &format) +{ + if (d_ptr->m_viewerApp) + return d_ptr->m_viewerApp->textureId(elementPath, size, format); + + size = {}; + format = GL_INVALID_ENUM; + return 0; +} + /*! Activate or deactivate the presentation identified by \a id depending on the value of \a active. diff --git a/src/api/studio3d/q3dspresentation.h b/src/api/studio3d/q3dspresentation.h index 1e8dedf..44bcad5 100644 --- a/src/api/studio3d/q3dspresentation.h +++ b/src/api/studio3d/q3dspresentation.h @@ -38,6 +38,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -130,6 +131,7 @@ public: void addImageProvider(const QString &providerId, QQmlImageProviderBase *provider); uint textureId(const QString &elementPath); + uint textureId(const QString &elementPath, QSize &size, GLenum &format); public Q_SLOTS: void setSource(const QUrl &source); diff --git a/src/engine/Qt3DSRuntimeView.cpp b/src/engine/Qt3DSRuntimeView.cpp index 7cebdd6..c3dc8e1 100644 --- a/src/engine/Qt3DSRuntimeView.cpp +++ b/src/engine/Qt3DSRuntimeView.cpp @@ -53,6 +53,8 @@ #include "foundation/Qt3DSSimpleTypes.h" #include "foundation/TrackingAllocator.h" #include "foundation/Qt3DSPerfTimer.h" +#include + // For perf log timestamp #include #include "Qt3DSArray.h" @@ -229,6 +231,7 @@ public: void deleteMeshes(const QStringList &meshNames) override; void addImageProvider(const QString &providerId, QQmlImageProviderBase *provider) override; uint textureId(const QString &elementPath) override; + uint textureId(const QString &elementPath, QSize &size, GLenum &format) override; void SetAttribute(const char *elementPath, const char *attributeName, const char *value) override; bool GetAttribute(const char *elementPath, const char *attributeName, void *value) override; @@ -779,6 +782,20 @@ uint CRuntimeView::textureId(const QString &elementPath) return 0; } +uint CRuntimeView::textureId(const QString &elementPath, QSize &size, GLenum &format) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast(m_RuntimeFactoryCore->GetScriptEngineQml()); + return theBridgeEngine.textureId(elementPath, + &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer(), + size, format); + } + size = {}; + format = GL_INVALID_ENUM; + return 0; +} + void CRuntimeView::SetAttribute(const char *elementPath, const char *attributeName, const char *value) { diff --git a/src/engine/Qt3DSRuntimeView.h b/src/engine/Qt3DSRuntimeView.h index e114633..822efdc 100644 --- a/src/engine/Qt3DSRuntimeView.h +++ b/src/engine/Qt3DSRuntimeView.h @@ -231,6 +231,7 @@ public: virtual void deleteMeshes(const QStringList &meshNames) = 0; virtual void addImageProvider(const QString &providerId, QQmlImageProviderBase *provider) = 0; virtual uint textureId(const QString &elementPath) = 0; + virtual uint textureId(const QString &elementPath, QSize &size, GLenum &format) = 0; virtual void SetAttribute(const char *elementPath, const char *attributeName, const char *value) = 0; virtual bool GetAttribute(const char *elementPath, const char *attributeName, void *value) = 0; diff --git a/src/runtime/Qt3DSIScriptBridge.h b/src/runtime/Qt3DSIScriptBridge.h index 246dc81..9eedfc5 100644 --- a/src/runtime/Qt3DSIScriptBridge.h +++ b/src/runtime/Qt3DSIScriptBridge.h @@ -38,6 +38,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QQmlImageProviderBase; @@ -189,6 +190,8 @@ public: // Elements qt3ds::render::IBufferManager *bufferManager) = 0; virtual uint textureId(const QString &elementPath, qt3ds::render::IQt3DSRenderer *renderer) = 0; + virtual uint textureId(const QString &elementPath, qt3ds::render::IQt3DSRenderer *renderer, + QSize &size, GLenum &format) = 0; public: // Components virtual void GotoSlide(const char *component, const char *slideName, diff --git a/src/runtime/Qt3DSQmlEngine.cpp b/src/runtime/Qt3DSQmlEngine.cpp index 1cadb3d..6730e6e 100644 --- a/src/runtime/Qt3DSQmlEngine.cpp +++ b/src/runtime/Qt3DSQmlEngine.cpp @@ -452,6 +452,8 @@ public: qt3ds::render::IBufferManager *bufferManager) override; uint textureId(const QString &elementPath, qt3ds::render::IQt3DSRenderer *renderer) override; + uint textureId(const QString &elementPath, qt3ds::render::IQt3DSRenderer *renderer, QSize &size, + GLenum &format) override; void GotoSlide(const char *component, const char *slideName, const SScriptEngineGotoSlideArgs &inArgs) override; @@ -1862,6 +1864,38 @@ uint CQmlEngineImpl::textureId(const QString &elementPath, return 0; } +uint CQmlEngineImpl::textureId(const QString &elementPath, qt3ds::render::IQt3DSRenderer *renderer, + QSize &size, GLenum &format) +{ + TElement *elem = getTarget(elementPath.toUtf8().constData()); + if (elem) { + auto translator = static_cast(elem->GetAssociation()); + if (translator) { + qt3ds::render::GraphObjectTypes::Enum elemType = translator->GetUIPType(); + if (elemType == qt3ds::render::GraphObjectTypes::Layer) { + auto layer = static_cast(&translator->RenderObject()); + auto texdetails = renderer->getLayerTextureDetails(*layer); + size = QSize(texdetails.m_Width, texdetails.m_Height); + // Assume that NVRenderTextureFormats enums match GL texture format enums + format = renderer->getTextureGlFormat(texdetails.m_Format); + return renderer->getLayerTextureId(*layer); + } else if (elemType == qt3ds::render::GraphObjectTypes::Image) { + auto image = static_cast(&translator->RenderObject()); + if (image->m_TextureData.m_Texture) { + auto texdetails = image->m_TextureData.m_Texture->GetTextureDetails(); + size = QSize(texdetails.m_Width, texdetails.m_Height); + format = renderer->getTextureGlFormat(texdetails.m_Format); + return static_cast(reinterpret_cast( + image->m_TextureData.m_Texture->GetTextureObjectHandle())); + } + } + } + } + size = {}; + format = GL_INVALID_ENUM; + return 0; +} + void CQmlEngineImpl::GotoSlide(const char *component, const char *slideName, const SScriptEngineGotoSlideArgs &inArgs) { diff --git a/src/runtimerender/Qt3DSRenderer.h b/src/runtimerender/Qt3DSRenderer.h index 2e6e6aa..336baab 100644 --- a/src/runtimerender/Qt3DSRenderer.h +++ b/src/runtimerender/Qt3DSRenderer.h @@ -40,6 +40,7 @@ #include "Qt3DSRenderCamera.h" #include "render/Qt3DSRenderBaseTypes.h" #include "Qt3DSRenderRay.h" +#include namespace qt3ds { namespace render { @@ -171,6 +172,10 @@ namespace render { virtual uint getLayerTextureId(SLayer &layer) = 0; + virtual GLenum getTextureGlFormat(NVRenderTextureFormats::Enum internalFormat) = 0; + + virtual STextureDetails getLayerTextureDetails(SLayer &layer) = 0; + // Roughly equivalent of gluPickMatrix, allows users to setup a perspective transform that // will draw some sub component // of the layer. Used in combination with an expected viewport of 0,0,width,height the diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp index 104bd09..300980c 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp @@ -57,6 +57,7 @@ #include "Qt3DSRenderPath.h" #include "Qt3DSRenderShaderCodeGeneratorV2.h" #include "Qt3DSRenderDefaultMaterialShaderGenerator.h" +#include "backends/gl/Qt3DSOpenGLUtil.h" #include #ifdef _WIN32 @@ -983,6 +984,39 @@ namespace render { return 0; } + GLenum Qt3DSRendererImpl::getTextureGlFormat(NVRenderTextureFormats::Enum internalFormat) + { + auto ctxType = m_Context->GetRenderContextType(); + GLConversion conversion; + GLenum glInternalFormat, glformat, gltype; + + if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) { + conversion.fromUncompressedTextureFormatToGL(ctxType, internalFormat, + glformat, gltype, glInternalFormat); + return glInternalFormat; + } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) { + return conversion.fromCompressedTextureFormatToGL(internalFormat); + } else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat)) { + conversion.fromDepthTextureFormatToGL(ctxType, internalFormat, glformat, + gltype, glInternalFormat); + return glInternalFormat; + } else { + return GL_INVALID_ENUM; + } + } + + STextureDetails Qt3DSRendererImpl::getLayerTextureDetails(SLayer &inLayer) + { + SLayerRenderData *theData = GetOrCreateLayerRenderDataForNode(inLayer); + + if (theData->m_LayerCachedTexture) + return theData->m_LayerCachedTexture->GetTextureDetails(); + if (theData->m_LayerTexture) + return theData->m_LayerTexture->GetTextureDetails(); + + return {}; + } + Option Qt3DSRendererImpl::GetLayerPickSetup(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, const QSize &inPickDims) diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h index 792d71e..99b0b51 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h @@ -388,6 +388,10 @@ namespace render { uint getLayerTextureId(SLayer &layer) override; + STextureDetails getLayerTextureDetails(SLayer &inLayer) override; + + GLenum getTextureGlFormat(NVRenderTextureFormats::Enum internalFormat) override; + Option GetLayerPickSetup(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, const QSize &inPickDims) override; @@ -566,7 +570,6 @@ namespace render { Option GetLayerMouseCoords(SLayer &inLayer, const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, bool forceImageIntersect = false) const override; - protected: Option GetLayerMouseCoords(SLayerRenderData &inLayer, const QT3DSVec2 &inMouseCoords, const QT3DSVec2 &inViewportDimensions, diff --git a/src/viewer/Qt3DSViewerApp.cpp b/src/viewer/Qt3DSViewerApp.cpp index ae671d0..5b3ba4a 100644 --- a/src/viewer/Qt3DSViewerApp.cpp +++ b/src/viewer/Qt3DSViewerApp.cpp @@ -1064,6 +1064,16 @@ uint Q3DSViewerApp::textureId(const QString &elementPath) return m_Impl.m_view->textureId(elementPath); } +uint Q3DSViewerApp::textureId(const QString &elementPath, QSize &size, GLenum &format) +{ + if (!m_Impl.m_view) { + size = {}; + format = GL_INVALID_ENUM; + return 0; + } + return m_Impl.m_view->textureId(elementPath, size, format); +} + Q3DSViewerApp &Q3DSViewerApp::Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer, QElapsedTimer *startupTimer) { diff --git a/src/viewer/Qt3DSViewerApp.h b/src/viewer/Qt3DSViewerApp.h index a23b5f9..0aa8ade 100644 --- a/src/viewer/Qt3DSViewerApp.h +++ b/src/viewer/Qt3DSViewerApp.h @@ -42,6 +42,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QQmlImageProviderBase; @@ -498,6 +499,7 @@ public: void addImageProvider(const QString &providerId, QQmlImageProviderBase *provider); uint textureId(const QString &elementPath); + uint textureId(const QString &elementPath, QSize &size, GLenum &format); QString error(); diff --git a/tests/auto/studio3d/q3dssurfaceviewer/tst_q3dssurfaceviewer.cpp b/tests/auto/studio3d/q3dssurfaceviewer/tst_q3dssurfaceviewer.cpp index a4b5aa2..7dcf254 100644 --- a/tests/auto/studio3d/q3dssurfaceviewer/tst_q3dssurfaceviewer.cpp +++ b/tests/auto/studio3d/q3dssurfaceviewer/tst_q3dssurfaceviewer.cpp @@ -85,6 +85,8 @@ private slots: void testMouseInput(); void testDataInput_data(); void testDataInput(); + void testTextureQuery(); + void testTextureQuery_data(); private: QWindow *createWindow(const QSize &size); @@ -1507,6 +1509,64 @@ void tst_Q3DSSurfaceViewer::testDataInput() delete slideInput; } +void tst_Q3DSSurfaceViewer::testTextureQuery_data() +{ + testBasics_data(); +} + +void tst_Q3DSSurfaceViewer::testTextureQuery() +{ + QFETCH(bool, isWindow); + + if (isWindow) + createWindowAndViewer(m_viewer, DATAINPUT); + else + createOffscreenAndViewer(m_viewer, DATAINPUT); + + m_viewer->settings()->setScaleMode(Q3DSViewerSettings::ScaleModeFill); + + QGuiApplication::processEvents(); + // Test texture info getters, first for layer then for individual material. + // Texture id's are likely to change if test ordering changes. + QSize texsize; + GLenum format; + + uint textureid = m_viewer->presentation()->textureId("Scene.Layer", texsize, format); + if (isWindow) + QCOMPARE(textureid, 6); + else + QCOMPARE(textureid, 7); + + QCOMPARE(texsize, QSize(300,200)); + QCOMPARE(format, GL_RGBA8); + + textureid = m_viewer->presentation()->textureId("Scene.Layer.Rectangle.Default.diffusemap", + texsize, format); + if (isWindow) + QCOMPARE(textureid, 1); + else + QCOMPARE(textureid, 2); + QCOMPARE(texsize, QSize(400,200)); + QCOMPARE(format, GL_RGBA8); + + m_viewer->presentation()->setAttribute("Scene.Layer.Rectangle.Default.diffusemap", + "subpresentation", ""); + m_viewer->presentation()->setAttribute("Scene.Layer.Rectangle.Default.diffusemap", "sourcepath", + "maps/OpenfootageNET_garage-512.hdr"); + + QGuiApplication::processEvents(); + + // Changed to HDR texture, studio-internally RGB8E but texture query should map to GL RGBA8 + textureid = m_viewer->presentation()->textureId("Scene.Layer.Rectangle.Default.diffusemap", + texsize, format); + if (isWindow) + QCOMPARE(textureid, 8); + else + QCOMPARE(textureid, 9); + + QCOMPARE(texsize, QSize(512,256)); + QCOMPARE(format, GL_RGBA8); +} QTEST_MAIN(tst_Q3DSSurfaceViewer) diff --git a/tests/auto/studio3d/shared/maps/OpenfootageNET_garage-512.hdr b/tests/auto/studio3d/shared/maps/OpenfootageNET_garage-512.hdr new file mode 100644 index 0000000..015b478 Binary files /dev/null and b/tests/auto/studio3d/shared/maps/OpenfootageNET_garage-512.hdr differ diff --git a/tests/auto/studio3d/shared/shared_presentations.qrc b/tests/auto/studio3d/shared/shared_presentations.qrc index d4bb668..25dd40e 100644 --- a/tests/auto/studio3d/shared/shared_presentations.qrc +++ b/tests/auto/studio3d/shared/shared_presentations.qrc @@ -11,5 +11,6 @@ presentation/datainput.uip presentation/datainput.uia presentation/datainput_sub.uip + maps/OpenfootageNET_garage-512.hdr -- cgit v1.2.3