[Interest] QOpenGLFramebufferObject, render to FBO using texture from another Image item?

Sletta Gunnar Gunnar.Sletta at digia.com
Fri Dec 13 12:03:27 CET 2013


Getting the Image element's textureProvider at the time of QQuickFrameBufferObject::synchronize should give you a QSGTextureProvider for that image, assuming that the Image.status == Ready. This is the same mechanism that ShaderEffect uses internally as well. You are not supposed to use the item on the render thread. That is unsafe and will lead to crashes. The texture provider is the right thing.

cheers,
Gunnar


________________________________
Fra: interest-bounces+gunnar.sletta=digia.com at qt-project.org [interest-bounces+gunnar.sletta=digia.com at qt-project.org] på vegne av Ola Røer Thorsen [ola at silentwings.no]
Sendt: 12. desember 2013 15:34
To: interest at qt-project.org
Emne: [Interest] QOpenGLFramebufferObject, render to FBO using texture from another Image item?

I recently discovered the new way of doing render-to-FBO in Qt 5.2.0. It's a major improvement compared with what had to be done previously, I think! :-)

However I have run into something tricky as I want to do something more advanced:

I need to render some textured geometry into an FBO. The use-case is something similar to correcting for lens artifacts in a photograph, and the geometry is too advanced for using the Shadereffect items (can't use a regular mesh grid).

The texture is loaded from a .jpg file on disk. The image is rather large, so I want to use similar mechanisms as used by the Quick2 Image item (cache, asynchronous loading, etc).

It's not a good idea to use the internals from qquickimage, so I thought of doing something similar to what the Shadereffectsource item does, by using the texture created by an Image item. This way, I can re-use all the advanced things the Image item does internally for loading an image.

I have now got a class inheriting QQuickFramebufferObject. It has a sourceItem property, which holds a QQuickItem*. In my QML code, i set this to be a Image item.

Image {
   id: rawImage
   source: "picture.jpg"
   visible: false
   asynchronous: true

   onStatusChanged: {
      (status === Image.Ready) {
         fboRender.updateTexture(); // this calls "update();" on the item in c++
      }
   }
}

MyFboRenderer {
   id: fboRender
   sourceItem: rawImage
}

In c++, I now need to safely pass the texture eventually found in the sourceItem to my QQuickFramebufferObject::Renderer. This has to be thread-safe in every way. As the Image and FBO render items in QML are to be used in model view delegates, they are created and deleted runtime.

Any hints on how to accomplish this would be very welcome!

Things I've found so far are:
- calling "sourceItem()->textureProvider()->texture()" from the renderer's "synchronize" function returns "0" even if synchronize was triggered as result of an update called when the image has completed loading.
- calling the same from the render-function gives a texture valid texture, and this sortof works, but there is no obvious safe way of accessing "sourceItem" at this point. I've tried to store a pointer to either the source item or the QQuickFramebufferObject, but both of these might be deleted/invalid when render() is called and crashes do happen.

Cheers
Ola








-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20131213/0a5f076d/attachment.html>


More information about the Interest mailing list