Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [PARTIALLY SOLVED] QML / ShadersEffectItem / Transparency
Forum Updated to NodeBB v4.3 + New Features

[PARTIALLY SOLVED] QML / ShadersEffectItem / Transparency

Scheduled Pinned Locked Moved QML and Qt Quick
13 Posts 3 Posters 8.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    billouparis
    wrote on last edited by
    #1

    I have several questions around the QML / shaderEffectItem and transparency.
    Shall I begin with the first one: I am developping under Windows XP; using the mingw compilation toolchain, and Qt 4.7.4.

    I just want to first create a QmlApplicationViewer of size 1024*768, with trransparency.

    Then I want to display a png of size 968*640 (containing transparency parts) inside this QmlApplicationViewer at position 50,50. So I expect to have transparency around the image, and inside the image itself.

    ->My application gives me the following result: i have the opaque part of the image displayed correctly, but all transparent parts I was expecting, (around the image, and in the image itself) are full of dirty stuff probably coming from a buffer that was not cleared before.

    Any idea how I could have a clean result?

    Here is my code:

    main.cpp
    @#include <QtGui/QApplication>
    #include <QtOpenGL>
    #include "qmlapplicationviewer.h"

    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
    #ifdef OPENGL_GRAPHICSSYSTEM
    QApplication::setGraphicsSystem("opengl");
    #endif

    QScopedPointer<QApplication> app(createApplication(argc, argv&#41;);
    QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
    

    #ifndef OPENGL_GRAPHICSSYSTEM
    QGLFormat format = QGLFormat::defaultFormat();
    format.setSampleBuffers(false);
    format.setSwapInterval(1);
    QGLWidget* glWidget = new QGLWidget(format);
    glWidget->setAutoFillBackground(false);
    viewer->setViewport(glWidget);
    #endif

    viewer->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    
    viewer->setAttribute(Qt::WA_TranslucentBackground);
    viewer->setAttribute(Qt::WA_NoSystemBackground);
    viewer->setStyleSheet("background:transparent;");
    viewer->setWindowFlags(Qt::FramelessWindowHint);
    viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    
    viewer->setMainQmlFile&#40;QLatin1String("qml/maskproject/main.qml"&#41;&#41;;
    viewer->showExpanded();
    
    return app->exec(&#41;;
    

    }
    @

    main.qml
    @
    import QtQuick 1.0
    import Qt.labs.shaders 1.0

    Rectangle {
    width: 1024
    height: 768
    color: "transparent"

    Image {
    id:source
    x:50
    y:50
    width:968
    height:645
    source: "../../../_DSC5401.jpg"
    }
    }
    @

    Any idea what is wrong here?
    Thank you,
    Bill

    1 Reply Last reply
    0
    • B Offline
      B Offline
      billouparis
      wrote on last edited by
      #2

      Here is the illustration of what I would like to get on the left side of the image, and the result I am getting with my current code on the right side of the image. Anyone knows why?

      !http://i40.tinypic.com/29n9jxi.png!

      1 Reply Last reply
      0
      • B Offline
        B Offline
        baysmith
        wrote on last edited by
        #3

        Generally OpenGL windows (namely QGLWidget) don't support window transparency.

        Nokia Certified Qt Specialist.

        1 Reply Last reply
        0
        • B Offline
          B Offline
          billouparis
          wrote on last edited by
          #4

          Hopefully I will get a more encouraging answer than this one! I hope so, since generally does not mean always, right?

          1 Reply Last reply
          0
          • B Offline
            B Offline
            baysmith
            wrote on last edited by
            #5

            No, not always. I've seen solutions that use offscreen OpenGL rendering with bliting into a transparent window, or enabling a platform specific extension. I haven't seen a solution that is implementable with the Qt APIs or one that is generally cross-platform. If someone knows one, I'd love to hear about it.

            Nokia Certified Qt Specialist.

            1 Reply Last reply
            0
            • B Offline
              B Offline
              billouparis
              wrote on last edited by
              #6

              I think we have such an implementation on our embedded device. I tried this code:
              @#include <QtGui/QApplication>
              #include "qmlapplicationviewer.h"
              #include <QtOpenGL>

              Q_DECL_EXPORT int main(int argc, char *argv[])
              {
              #ifdef OPENGL_GRAPHICSSYSTEM
              QApplication::setGraphicsSystem("opengl");
              #endif

              QScopedPointer<QApplication> app(createApplication(argc, argv));
              QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
              

              #ifndef OPENGL_GRAPHICSSYSTEM
              QGLFormat format = QGLFormat::defaultFormat();
              format.setSampleBuffers(false);
              format.setSwapInterval(1);

              QGLWidget* glWidget = new QGLWidget(format);
              glWidget->setAutoFillBackground(false);
              viewer->setViewport(glWidget);
              

              #endif

              viewer->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
              
              // viewer.setAttribute(Qt::WA_OpaquePaintEvent);
              //viewer->setWindowFlags(Qt::FramelessWindowHint|Qt::SplashScreen);
              //viewer->setAttribute(Qt::WA_TranslucentBackground);
              viewer->setAttribute(Qt::WA_NoSystemBackground);
              viewer->setStyleSheet("background: transparent;");
              viewer->setFrameStyle(QFrame::NoFrame);
              viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
              
              viewer->setMainQmlFile&#40;QLatin1String("qml/SimpleOpenGLWithTransparency/main.qml"&#41;);
              viewer->showExpanded();
              
              return app->exec&#40;&#41;;
              

              }

              @

              And on our target it displays white color instead of transparent. We have two different hardware framebuffers, my app is running in the FB on top, and i can not see through. If I remove the openGL initialization, I can see through the image without any problem.

              Do you think it can improve if I set the :
              format.setAlpha(true);
              instruction, or it has nothing to do with this?

              Regards,
              Bill

              1 Reply Last reply
              0
              • N Offline
                N Offline
                nicolauz
                wrote on last edited by
                #7

                I think all you need to do is setting TranslucentBackground on the viewport(!!!):
                glWidget->setAttribute(Qt::WA_TranslucentBackground);

                ... this should do magic
                (before and/or after setViewport ... there is something going on when setting the viewport .. moving this line around in the code can improve things a lot ;) )

                ... if this doesn't help, try to add:
                glWidget->qglClearColor(Qt::transparent);

                I got no MS-Windows machine here, but it should be ... somewhat similar on linux and window ;)

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  billouparis
                  wrote on last edited by
                  #8

                  Hey Thomas, do you think a
                  format.setAlpha(true);

                  could also improve things?
                  Bill

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    billouparis
                    wrote on last edited by
                    #9

                    Hello Thomas, I have tried both solutions, both on PC WindowsXP, and on our Target iMX53 linux/Wayland based, with no success in either case :(
                    I am still getting dirty data all over the place in the transparent areas...
                    I am doomed!
                    Bill

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      billouparis
                      wrote on last edited by
                      #10

                      Another guy from another working with us, told me he found a workaround by modifying the qmlApplicationViewer and replacing/adding the following:

                      "The only way i found to circumvent this issue is to overwrite QGraphicsView::drawBackground() in the QMLApplicationViewer:

                      void QmlApplicationViewer::drawBackground(QPainter* painter, const QRectF&)
                      {
                      painter->beginNativePainting();
                      glClearDepthf(1.f);
                      glClearColor(0.f, 0.f, 0.f, 0.f);
                      glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);

                      painter->endNativePainting();
                      }

                      Maybe there is another way.

                      "

                      Do you know if it's a good solution? or if there is something else I could try without changing the qmlApplicationViewer itself?
                      Thank you,
                      Bill

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        billouparis
                        wrote on last edited by
                        #11

                        I tested all solution, apparently none is working for me, neither on PC XP, nor on Target/embedded system Device.

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          billouparis
                          wrote on last edited by
                          #12

                          Finally got something working:
                          1 - add the workaround in the qmlViewerApplication as follows:
                          @void QmlApplicationViewer::drawBackground(QPainter* painter, const QRectF&)
                          {
                          painter->beginNativePainting();
                          glClearDepthf(1.f);
                          glClearColor(0.f, 0.f, 0.f, 0.f);
                          glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
                          painter->endNativePainting();
                          }@

                          2- initialise your qmlApplicationViewer as follows:
                          @#include <QtGui/QApplication>
                          #include "qmlapplicationviewer.h"
                          #include <QtOpenGL>

                          int main(int argc, char *argv[])
                          {

                          QScopedPointer<QApplication> app(createApplication(argc, argv));
                          QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
                          
                          viewer->setWindowFlags(Qt::FramelessWindowHint);
                          viewer->setAttribute(Qt::WA_NoSystemBackground);
                          viewer->setStyleSheet("background: transparent;");
                          QPalette palette;
                          palette.setColor(QPalette::Base, Qt::transparent);
                          viewer->setPalette(palette);
                          
                          viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
                          viewer->setMainQmlFile&#40;QLatin1String("qml/SimpleOpenGLWithTransparency/main.qml"&#41;&#41;;
                          
                          QGLFormat format = QGLFormat::defaultFormat();
                          format.setSampleBuffers(false);
                          format.setSwapInterval(1);
                          format.setAlpha(true);
                          
                          QGLWidget *glWidget = new QGLWidget(format);
                          glWidget->setAutoFillBackground(false);
                          viewer->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
                          viewer->setViewport(glWidget);
                          
                          viewer->showExpanded();
                          
                          
                          return app->exec&#40;&#41;;
                          

                          }
                          @

                          Thank you Mathias for your suggestions, thank you Thomas also, even if your tricks did not work for me.

                          Best of luck for all!
                          Bill

                          [Edited for code syntax highlighting. -Bradley]

                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            nicolauz
                            wrote on last edited by
                            #13

                            I think it's ok ... if "he" isn't clearing it's ok if you do. :)
                            Performance-vice it shouldn't be a big deal do clear the color-buffer... but maybe someone with more opengl-performance-experience has an opinion?

                            @
                            glWidget->setAutoFillBackground(false);
                            @
                            I think this is the problem.
                            You have disabled any background painting on the viewport (which is then overwritten by you via reimplementing the drawBackground of the DeclarativeView).
                            What he's then doing is painting transparent ... which is then composed with the "background".
                            If you try a half-transparent red as your Rectangle color, I would guess you would see red garbage :)

                            ... the only thing which is strange is that:
                            @
                            viewer->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
                            @
                            should clear the color buffer for every frame ...

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved