Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to clear the background of a QOpenGLWidget?
Forum Updated to NodeBB v4.3 + New Features

How to clear the background of a QOpenGLWidget?

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 3 Posters 2.0k Views 2 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.
  • K Offline
    K Offline
    Kattia
    wrote on last edited by
    #1

    I have succeeded in clearing the background of a QOpenGLWidget only after calling setAttribute(Qt::WA_AlwaysStackOnTop);
    however, as the name describes, the widgets become on top of other widgets.

    I also tried:

            initializeOpenGLFunctions();
    	this->glClearColor(0.0, 0.0, 0.0, 0.0);
    

    But the background also didn't get 'cleared'.

    #include <qopenglwidget.h>
    #include <qopenglfunctions.h>
    
    
    
    class OpenGL : public QOpenGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
        QImage image;
    
        OpenGL(QWidget* parent = NULL) : QOpenGLWidget(parent) 
        {
            //setAutoFillBackground(false);
            //setAttribute(Qt::WA_AlwaysStackOnTop);
    
            QGridLayout* layout = new QGridLayout(this);
            this->setLayout(layout);
    
            QPushButton* btn = new QPushButton(this);
            btn->setGeometry(100, 100, 300, 50);
            btn->setStyleSheet("background-color: red;");
            btn->setText("test");
    
            layout->addWidget(btn);
        };
    
        void initializeGL()
        {
            initializeOpenGLFunctions();
    	this->glClearColor(0.0, 0.0, 0.0, 0.0);
    
            if (!image.load(":/logos/dr_logo"))
                qDebug() << "Failed to load the image.";
        };
        
        void paintGL()
        {
            if (image.isNull())
                return;
    
            QPainter p(this);
            p.setRenderHint(QPainter::Antialiasing);
                    
            QRect area = this->rect();
            p.drawImage(area, image, image.rect());
        };
        
        //void resizeGL(int width, int heigh)
        //{
        //};
    };
    

    Also, isn't possible to add widgets to an OpenGLWidget in the Qt Designer?

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      glClearColor only sets a color that would be used for clearing. To actually clear the background call

      glClear(GL_COLOR_BUFFER_BIT);
      

      at the start of paintGL function. This will clear the color buffer. You can also clear depth and stencil buffers if you have those enabled with GL_DEPTH_BUFFER_BIT and GL_STENCIL_BUFFER_BIT.

      K 1 Reply Last reply
      0
      • Chris KawaC Chris Kawa

        glClearColor only sets a color that would be used for clearing. To actually clear the background call

        glClear(GL_COLOR_BUFFER_BIT);
        

        at the start of paintGL function. This will clear the color buffer. You can also clear depth and stencil buffers if you have those enabled with GL_DEPTH_BUFFER_BIT and GL_STENCIL_BUFFER_BIT.

        K Offline
        K Offline
        Kattia
        wrote on last edited by Kattia
        #3

        @Chris-Kawa said in How to clear the background of a QOpenGLWidget?:

        glClear(GL_COLOR_BUFFER_BIT);

        The background continues black, tried single and both options glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        I'm missing anything else? and about the Qt Designer thing?

        Chris KawaC 1 Reply Last reply
        0
        • K Kattia

          @Chris-Kawa said in How to clear the background of a QOpenGLWidget?:

          glClear(GL_COLOR_BUFFER_BIT);

          The background continues black, tried single and both options glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

          I'm missing anything else? and about the Qt Designer thing?

          Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          The background continues black

          this->glClearColor(0.0, 0.0, 0.0, 0.0); is a black color so yeah, you're gonna have it clear to black. If you want it for example white set the clear color to all ones.

          and about the Qt Designer thing?

          QOpenGLWidget creates a native window for OpenGL painting on top of the widget. You can't have another widget on top of that. All widgets are below it.

          K 1 Reply Last reply
          0
          • Chris KawaC Chris Kawa

            The background continues black

            this->glClearColor(0.0, 0.0, 0.0, 0.0); is a black color so yeah, you're gonna have it clear to black. If you want it for example white set the clear color to all ones.

            and about the Qt Designer thing?

            QOpenGLWidget creates a native window for OpenGL painting on top of the widget. You can't have another widget on top of that. All widgets are below it.

            K Offline
            K Offline
            Kattia
            wrote on last edited by
            #5

            @Chris-Kawa said in How to clear the background of a QOpenGLWidget?:

            The background continues black

            this->glClearColor(0.0, 0.0, 0.0, 0.0); is a black color so yeah, you're gonna have it clear to black. If you want it for example white set the clear color to all ones.

            I have removed this line. The background continued black.

            class OpenGL : public QOpenGLWidget, protected QOpenGLFunctions
            {
                Q_OBJECT
            
            public:
                QImage image;
            
                OpenGL(QWidget* parent = NULL) : QOpenGLWidget(parent) 
                {
                    //setAutoFillBackground(false);
                    //setAttribute(Qt::WA_AlwaysStackOnTop);
                    //setAttribute(Qt::WA_TranslucentBackground);
            
                    QGridLayout* layout = new QGridLayout(this);
                    this->setLayout(layout);
            
                    QPushButton* btn = new QPushButton(this);
                    btn->setGeometry(100, 100, 300, 50);
                    btn->setStyleSheet("background-color: red;");
                    btn->setText("test");
            
                    layout->addWidget(btn);
                };
            
                void initializeGL()
                {
                    initializeOpenGLFunctions();
            	//glClearColor(0.0, 0.0, 0.0, 100);
                    //glClear(GL_COLOR_BUFFER_BIT);
            
                    if (!image.load(":/sw_logos/sw_logo1"))
                        qDebug() << "Failed to load the image.";
                };
                
                void paintGL()
                {
                    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    glClear(GL_COLOR_BUFFER_BIT);
            
                    if (image.isNull())
                        return;
            
                    QPainter p(this);
                    p.setRenderHint(QPainter::Antialiasing);
                            
                    QRect area = this->rect();
                    p.drawImage(area, image, image.rect());
                };
            };
            
            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by Chris Kawa
              #6

              I have removed this line. The background continued black.

              Because black is also the default. Changing black to black doesn't change anything :)
              Don't remove glClearColor. Set it to color that you want to clear to. For example if you want a red background it's glClearColor(1.0, 0.0, 0.0, 1.0).

              K 1 Reply Last reply
              0
              • Chris KawaC Chris Kawa

                I have removed this line. The background continued black.

                Because black is also the default. Changing black to black doesn't change anything :)
                Don't remove glClearColor. Set it to color that you want to clear to. For example if you want a red background it's glClearColor(1.0, 0.0, 0.0, 1.0).

                K Offline
                K Offline
                Kattia
                wrote on last edited by
                #7

                @Chris-Kawa i'm trying to get the openglwidget background transparent, is it possible?

                Chris KawaC 1 Reply Last reply
                0
                • K Kattia

                  @Chris-Kawa i'm trying to get the openglwidget background transparent, is it possible?

                  Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  It depends on couple different factors, including your OS and window manager. See Limitations and Other Considerations.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    Kattia
                    wrote on last edited by Kattia
                    #9

                    The OS is Windows 10, i read the doc you sent, and after setting setAttribute(Qt::WA_TranslucentBackground); to the parent window
                    the OpenGLWidget background also got transparent.

                    However, which setAttribute(Qt::WA_TranslucentBackground); turned on the GUI is using 3x more CPU for simple tasks like moving around the screen.

                    Why this option is so 'evil' in resource usage? it transform the window in a layered window?

                    Also, why the image draw in the paintGL has a very lower quality compared to when drawn directly into a QWidget ?

                    S 1 Reply Last reply
                    0
                    • K Kattia

                      The OS is Windows 10, i read the doc you sent, and after setting setAttribute(Qt::WA_TranslucentBackground); to the parent window
                      the OpenGLWidget background also got transparent.

                      However, which setAttribute(Qt::WA_TranslucentBackground); turned on the GUI is using 3x more CPU for simple tasks like moving around the screen.

                      Why this option is so 'evil' in resource usage? it transform the window in a layered window?

                      Also, why the image draw in the paintGL has a very lower quality compared to when drawn directly into a QWidget ?

                      S Offline
                      S Offline
                      SimonSchroeder
                      wrote on last edited by
                      #10

                      @Kattia said in How to clear the background of a QOpenGLWidget?:

                      However, which setAttribute(Qt::WA_TranslucentBackground); turned on the GUI is using 3x more CPU for simple tasks like moving around the screen.

                      Here is my (uninformed) guess: If you have an opaque background you just clear the OpenGL canvas, then paint on it an finally draw it on the screen. The last step is just a simple swap of the buffers (and maybe additional blitting). This is all relatively fast. With a transparent background you first need to get a picture from the desktop in the OpenGL drawing area. This is now first set as the background of the OpenGL canvas and only after that you paint on the canvas and draw it on the screen.

                      Especially when moving widgets around this will have a huge impact: Windows is optimized for opaque widgets to just move the picture around without painting anything new. However, with a transparent background you always have to repaint the whole widget for every single pixel moved. So, this has to run through the whole OpenGL painting again.

                      One thing you can try to speed this up is to use masking for the fully transparent parts of your widgets (like so: https://doc.qt.io/qt-6/qtwidgets-widgets-shapedclock-example.html). You could use OpenGL with a special buffer to write the mask. I am not sure if this helps at all. It certainly only works when there is nothing partially transparent in your OpenGL paintings.

                      @Kattia said in How to clear the background of a QOpenGLWidget?:

                      Also, why the image draw in the paintGL has a very lower quality compared to when drawn directly into a QWidget ?

                      Most likely because Qt uses anti aliasing. You need to use something like super sampling or similar techniques in OpenGL to have a better quality.

                      1 Reply Last reply
                      0
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @SimonSchroeder said:

                        With a transparent background you first need to get a picture from the desktop in the OpenGL drawing area. This is now first set as the background of the OpenGL canvas and only after that you paint on the canvas and draw it on the screen

                        That's not how it works. Each window is drawn to its own buffer with alpha information. A window manager then takes these buffers and composes them in z-order. Depending on the window manager implementation and type of the window it's possible that a GPU readback to the main memory is needed for the composition and that could be what's eating up CPU. In general hardware accelerated transparent surfaces are not very efficient.

                        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