Uploaded image for project: 'Qt 3D Studio'
  1. Qt 3D Studio
  2. QT3DS-111 C++ and QML API for Runtime 2.x
  3. QT3DS-2032

Add QML API to expose layers as texture providing Quick items

    XMLWordPrintable

Details

    Description

      As outlined in https://codereview.qt-project.org/#/c/236109/

      Due to the usage of synchronous rendering, a Studio3D item (or rather, the renderer part of it running on the Quick render thread) can safely dig out the OpenGL texture id for any Qt 3D texture once renderSyncronous() has returned:

      QSharedPointer<Qt3DRender::Render::ResourceAccessor> ra = m_renderAspectD->m_renderer->nodeManagers()->resourceAccessor();
      QOpenGLTexture *tex = nullptr;
      ra->accessResource(Qt3DRender::Render::ResourceAccessor::OGLTextureRead, layerTexId(), (void**) &tex, nullptr);
      

      Experiment with this. We could add a mode to Studio3D where, in addition to its default visual operation mode showing the final composed texture from the 3D scene, layer textures are also exposed individually as Quick items that are texture providers.

      This provides a reasonable solution to the common "multiple Studio3D" problem (where one needs 3D content in different areas of the Quick UI but instantiating separate Studio3D items causes firing up new instances of the entire engine and is thus not really recommendable in practice)

      In addition, it gives a significant performance boost for single-layer scenes since using a View3D avoids the unnecessary layer composition step by nature.

      A further option is to think about a mode where a Studio3D item becomes completely non-visual, only representing the "engine". The content is then showed by separate Quick items, moving the composition completely to Qt Quick domain. (alternatively, the composed-by-Qt3D texture could still be exposed)

      As a final target, we could have something like these (imaginary examples):

      Still with .uip:

      Studio3DEngine { // non-visual, maybe just a QObject
          id: s3d
          source: "blah.uip"
      }
      Rectangle {
          ...
         Layer3D { // visual QQuickItem, rendering the texture for layer named "Layer2" defined in the editor/.uip - but also a textureProvider, so things like ShaderEffect function efficiently without an additional texture/FBO in the middle
             engine: s3d
             layer: "Layer2"
         }
      }
      ... and so on
      

      The future is .uip-less of course, so scenes would then be defined fully in QML:

      Studio3DEngine {
          id: s3d
      }
      
      ...
      Layer3D { // like above, an ordinary visual Quick item that's also a textureProvider
          engine: s3d
          Group3D {
             rotation: Qt.vector3D(45, 0 0)
             Model3D {
                source: "#Cube"
                materials: [ DefaultMaterial3D { } ]
              }
              Model3D {
                 source: "car.mesh"
                 materials: [ ... ]
                 position: Qt.vector3D(100, 100, 0)
              }
          }
      }
      ...
      Layer3D { // another one
          ...
      }
      

      Internally this would create the same old Q3DSGraphObject tree:

      Scene
        Layer
          Group
            Model
              DefaultMaterial
            Model
              ...
        Layer
          ...
      

      The 3DS runtime's built-in compositor is then turned off since the composed texture is not needed.

      Attachments

        Issue Links

          For Gerrit Dashboard: QT3DS-2032
          # Subject Branch Project Status CR V

          Activity

            People

              lagocs Laszlo Agocs
              lagocs Laszlo Agocs
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes