Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QtQuick 2.0 scene on top of Direct3D scene



  • Hi everyone,

    I have been trying to come up with a solution for having a QtQuick 2.0 scene together with a Direct3D scene for quite a while, but wasn't very successful. My goal is to have a Direct3D engine running at reasonable speed (60 FPS?) together with QML UI on top. Both things run just fine at 150-200 FPS on their own. But when forced to cooperate together within one window, everything just goes bananas. I have investigated several approaches, but none of them seems to be sufficient enough:

    Solution A: Rendering Direct3D scene into a texture, visualizing with QImage & QQuickPaintedItem

    • this solution works quite well and it seems to be the preferred one according to other people on the web. However it is TERRIBLY slow. I wasn't able to have more than 18-20 FPS in full HD. The bottleneck was clearly in the texture transfer chain from GPU (D3D) to CPU (QImage) and back to GPU (QML renderer) each frame. Especially the CPU->GPU processing on the QML side was way too slow!

    Solution B: Rendering QtQuick scene into a FBO, then using Direct3D texture

    • this is basically the previous solution other way round. The speed is a little bit better when the UI does not require an update. Once it starts animating, everything drops down to 18-20 FPS again. QOpenGLFramebufferObject::toImage() obviously takes its time. Implementing texture/FBO double buffering on both sides to reduce stalls does not really help.

    Solution C: QQuickView with enabled transparency on top of QWidget with Direct3D scene

    • was not lucky with this approach either. It seems like the transparency works only when QQuickView is in its own window. Once I put it on top of my D3D QWidget within the same window, it immediately stopped working and became fully opaque. Someone was trying to do something similar there as well: http://qt-project.org/forums/viewthread/5484 , but I had no luck with that solution at all. Maybe keeping two completely separated windows (main D3D window + frameless transparent QML window) on top of each other all time would do the trick, but that just sounds silly.

    Solution X: Modify ANGLE library and try to extract & share D3D device context with my Direct3D renderer

    • haven't tried this yet, avoiding any library modifications as long as possible. Would that even be a sensible option?

    My obvious questions here are: Am I doing something wrong? What is the preferred solution? A, B, C, X or maybe something totally different? Can someone point me to the right direction?

    TL;DR: What is the fastest way to render QML scene on top of Direct3D scene?

    Thank you for your time and help!
    Jan


Log in to reply