0

I want to render a QML subtree manually to a Canvas3D by having all the subtree's items' be-texture-source flag (layer.enabled) enabled, and taking the geometry (x, y, width, height) of each item from the corresponding QML properties of each item (calculated by layouts, anchors, etc), so I know how to position and size each item with OpenGL calls.

I have no problems with implementing this, except for a performance issue: since I'm drawing the items in OpenGL, I don't want Qt to also draw them to the window (this would be doing the same work twice). I could achieve that easily by setting opacity: 0 on the items, but that would probably only fix the visual problem, it wouldn't save performance. I could also set visible: false but then I think the layout components wouldn't be able to do their job correctly.

The reasons I want to implement the described architecture are:

  • I want to implement custom rendering for some of the items in the subtree, but still use their positions and sizes (calculated by the layout for me) for the custom rendering. This custom rendering is complex enough that it can't be done with QML features alone, and I don't want to use Qt3D.
  • I could use use another approach: use a separate Canvas3D for every item that I want to render customly. And let Qt Quick render the rest of the items for me normally. That's what I've been doing until now. The problem, however, is that:
    1. The different Canvas3Ds can't share GL resources, so I need to initialize and keep copies of the GL resources in each Canvas3D. This increases load time and memory usage.
    2. The creation time of each Canvas3D (even without my GL init code) is significant, I think

So instead I want to use a single, big Canvas3D.

Stefan Monov
  • 11,332
  • 10
  • 63
  • 120
  • Use `QQuickRenderControl` to be able to render whenever you want. But the Canvas3D is rendered by Qt too? Why do you need Canvas3D? There is a raw OpenGL available. – Velkan Dec 22 '16 at 11:31
  • @Velkan: Please see my last edit. `QQuickRenderControl` renders the entire scene to a framebuffer, as-is. But I want to implement custom rendering for certain items. About `Canvas3D`: it has several advantages over raw OpenGL. 1. It lets me code in JS which is nicer. 2. It can fetch any QML item as an auto-updated texture. 3. It can be put into a Qt Quick window, alongside other QML items. – Stefan Monov Dec 22 '16 at 14:16
  • 3. Custom QQuickItem can be put into a Qt Quick window, alongside other QML items. 2. You can fetch any QML item as an auto-updated texture by using the `textureProvider()` function. 3. Words 'JS' and 'nicer' in one sentence. – Velkan Dec 22 '16 at 15:31
  • @Velkan: wrt 3: Are you saying it's appropriate to implement my "custom items" as separate `QQuickItem`'s? I have several concerns about doing that. 1. Can I implement my `QQuickItem`s with OpenGL, rather than with the Qt scenegraph API? 2. Can I share GL resources between several `QQuickItem`s? 3. Is the initialization of a `QQuickItem` slow like the initialization of a `Canvas3D` is? – Stefan Monov Dec 22 '16 at 19:28
  • When you need to 'go deeper', you inherit from `QQuickItem`. 1. Canvas is like a `QQuickItem` where you do all rendering into a texture inside the `QQuickItem::updatePaintNode()` function and then put it on scenegraph as a simple rectangle using Qt scenegraph API. 2. Resources are in single OpenGL context, I don't know about what sharing problems you're talking about. 3. Empty `QQuickItem` costs almost nothing (object allocated, its empty functions are called several times, no GL calls AFAIK). You then create nodes on the scene graph, so you load some vertex buffers, create textures, maybe FB. – Velkan Dec 23 '16 at 07:36
  • @Velkan: wrt 1: Sorry but you seem to sidestep the question. Can I implement my QQuickItems with OpenGL? You seem to imply that I can, but all the examples I've seen use the Qt scenegraph API instead, which I don't want to use. – Stefan Monov Dec 23 '16 at 19:52
  • Yes, take the `QQuickFramebufferObject` that inherits from `QQuickItem` and a `QQuickFramebufferObject::Renderer`. They deal with creating an FBO and putting it on the scene graph. – Velkan Dec 23 '16 at 19:52
  • @Velkan: Thanks, sounds good. And I've read that QQuickFramebufferObject doesn't use a separate GL context, which is great. I'm worried about the performance of allocating a new QQuickFramebufferObject, though (it involves allocating a new FBO, which may be slow?). Do you know about that? – Stefan Monov Dec 23 '16 at 19:58
  • That's what it does - allocates an FBO. I don't have experience in profiling OpenGL programs. – Velkan Dec 23 '16 at 22:39

0 Answers0