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. rendering text in QOpenGLWidget
Forum Updated to NodeBB v4.3 + New Features

rendering text in QOpenGLWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 5 Posters 7.6k 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
    belgiansteve
    wrote on 17 Feb 2016, 19:47 last edited by
    #1

    Hi,

    I'm trying to render some text on a QOpenGLWidget using QPainter.

    painter->setRenderHint(QPainter::TextAntialiasing);
    QPen pen = painter->pen();
    pen.setColor(QColor(m_fgc.r, m_fgc.g, m_fgc.b));
    painter->setPen(pen);
    painter->setFont(QFont(m_font, m_font_size));
    painter->drawText(x0, y0, m_w, m_h, Qt::AlignLeft| Qt::AlignVCenter, QString(szlabel));

    The text gets drawn, but looks corrupted. Is this a bug? Am I doing something wrong? Is there another way of rendering text without QPainter? I'm kind of stuck on a project because of this issue so I'd really appreciate it if someone could offer some help. Thanks!

    B 1 Reply Last reply 18 Feb 2016, 14:23
    0
    • B belgiansteve
      17 Feb 2016, 19:47

      Hi,

      I'm trying to render some text on a QOpenGLWidget using QPainter.

      painter->setRenderHint(QPainter::TextAntialiasing);
      QPen pen = painter->pen();
      pen.setColor(QColor(m_fgc.r, m_fgc.g, m_fgc.b));
      painter->setPen(pen);
      painter->setFont(QFont(m_font, m_font_size));
      painter->drawText(x0, y0, m_w, m_h, Qt::AlignLeft| Qt::AlignVCenter, QString(szlabel));

      The text gets drawn, but looks corrupted. Is this a bug? Am I doing something wrong? Is there another way of rendering text without QPainter? I'm kind of stuck on a project because of this issue so I'd really appreciate it if someone could offer some help. Thanks!

      B Offline
      B Offline
      belgiansteve
      wrote on 18 Feb 2016, 14:23 last edited by belgiansteve
      #2

      If it may help, here is a small example code that produces the issue.

      #include <QApplication>
      #include <QOpenglWidget>
      #include <QPainter>
      
      class MyOpenGLWidget : public QOpenGLWidget
      {
      public:
      	MyOpenGLWidget(){}
      
      	void initializeGL()
      	{
      		glClearColor(1.f, 1.f, 1.f, 1.f);
      	}
      
      	void resizeGL(int w, int h)
      	{
      		glViewport(0, 0, w, h);
      	}
      
      	void paintGL()
      	{
      		glClear(GL_COLOR_BUFFER_BIT);
      	
      		QPainter painter(this);
      		painter.setPen(Qt::black);
      		painter.setFont(QFont("Arial", 16));
      		painter.drawText(0, 0, width(), height(), Qt::AlignCenter, "Hello World!");
      		painter.end();
      	}
      };
      
      int main(int argc, char **argv)
      {
      	QApplication app(argc, argv);
      
      	MyOpenGLWidget wnd;
      	wnd.resize(400, 300);
      	wnd.show();
      
      	return app.exec();
      }
      
      1 Reply Last reply
      0
      • R Offline
        R Offline
        Rondog
        wrote on 18 Feb 2016, 18:35 last edited by Rondog
        #3

        I tried your example and it worked fine. I changed the size of the font from 16 to 56 and didn't see anything that I would consider 'corrupted'.

        I am using OSX 10.10 Qt 5.4.0 XCode 7.2

        One thing that seems to be missing from your example is the QOpenGLFunctions. From the Qt help file showing an example of the QOpenGLWidget using the QOpenGLFunctions:

        class MyGLWidget : public QOpenGLWidget
        {
        public:
            MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }
        
        protected:
            void initializeGL()
            {
                // Set up the rendering context, load shaders and other resources, etc.:
                QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
                f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
                ...
            }
        
            void resizeGL(int w, int h)
            {
                // Update projection matrix and other size related settings:
                m_projection.setToIdentity();
                m_projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);
                ...
            }
        
            void paintGL()
            {
                // Draw the scene:
                QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
                f->glClear(GL_COLOR_BUFFER_BIT);
                ...
            }
        };
        

        I realize you are using QPainter to draw the text but it is possible it is not using the same rendering context you setup.

        Your updated example program:

        class MyOpenGLWidget : public QOpenGLWidget
        {
        public:
        	MyOpenGLWidget(){}
        	
        	void initializeGL()
        	{
        		QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        		f->glClearColor(1.f, 1.f, 1.f, 1.f);
        	}
        	
        	void resizeGL(int w, int h)
        	{
        		QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        		f->glViewport(0, 0, w, h);
        	}
        	
        	void paintGL()
        	{
        		QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        		
        		f->glClear(GL_COLOR_BUFFER_BIT);
        		
        		QPainter painter(this);
        		painter.setPen(Qt::black);
        		painter.setFont(QFont("Arial", 56));
        		painter.drawText(0, 0, width(), height(), Qt::AlignCenter, "Hello World!");
        		painter.end();
        	}
        };
        
        1 Reply Last reply
        0
        • B Offline
          B Offline
          belgiansteve
          wrote on 18 Feb 2016, 18:52 last edited by
          #4

          Thanks for the reply. Unfortunately, it didn't work. I added the QOpenGLFunctions to the example but the text remains corrupted. (The reason I am not using QOpenGLFunctions is because it does not appear to support glBegin()/glEnd() which I need since I'm porting some old fixed functionality code to Qt). It sounds like it might be an OS issue then (I'm using Windows7).

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on 18 Feb 2016, 22:16 last edited by
            #5

            I'm on Windows 10 and there's no issue either. Can you show a screenshot of what "corrupted" means?

            Technically when you're mixing QPainter and native GL calls you should put the latter in a painter's begin/end native paint clause. Although clearing the buffer is simple and should just work you might try this:

            QPainter painter(this);
            painter.beginNativePainting();
            glClear(GL_COLOR_BUFFER_BIT);
            painter.endNativePainting();
            
            painter.setPen(Qt::black);
            painter.setFont(QFont("Arial", 16));
            painter.drawText(0, 0, width(), height(), Qt::AlignCenter, "Hello World!");
            

            Btw. a call to end() is not needed here. It will be called by the painter's destructor implicitly.

            1 Reply Last reply
            1
            • S Offline
              S Offline
              Stephocke
              wrote on 29 Dec 2019, 01:54 last edited by Stephocke
              #6
              This post is deleted!
              1 Reply Last reply
              0
              • P Offline
                P Offline
                PythonDuncan
                wrote on 11 Oct 2023, 14:02 last edited by
                #7

                I had this issue when I needed to draw axis and corresponding ticks. In Qt4, I can use the following code:

                for (int i = _Ymin; i <= _Ymax; i = i + _yGrid)
                {
                  double yPos = (_Ymax-i)*_yscaleF*_yscalingF;
                  double xPos = -_xmin*_xscaleF-_shiftX;
                  if(yPos < (_Ymax-_Ymin)*_yscaleF-_shiftY+1)
                  {
                      glBegin(GL_LINES);
                      glVertex2f(xPos-2, yPos);
                      glVertex2f(xPos+2, yPos);
                      glEnd();
                     renderText (xPos - offset,yPos+5 , 0, QString::number(i/10.0));
                  }
                }
                glScalef(_xscalingF,_yscalingF,0);
                

                However, when I try to migrate my code to Qt6, there's no renderText anymore. After searching on the web and investigating the source code of renderText, finally I found the solution, one needs to save/load gl status:

                glBegin(GL_LINES);
                glVertex2f(xPos-4, yPos);
                glVertex2f(xPos+4, yPos);
                glEnd();
                qt_save_gl_state();
                renderText(xPos - offset,yPos+5 , QString::number(i/10.0));
                qt_restore_gl_state();
                

                Here are the def of qt_save_gl_state, renderText, qt_restore_gl_state:

                static void qt_save_gl_state()
                {
                    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
                    glPushAttrib(GL_ALL_ATTRIB_BITS);
                    glMatrixMode(GL_TEXTURE);
                    glPushMatrix();
                    glLoadIdentity();
                    glMatrixMode(GL_PROJECTION);
                    glPushMatrix();
                    glMatrixMode(GL_MODELVIEW);
                    glPushMatrix();
                
                    glShadeModel(GL_FLAT);
                    glDisable(GL_CULL_FACE);
                    glDisable(GL_LIGHTING);
                    glDisable(GL_STENCIL_TEST);
                    glDisable(GL_DEPTH_TEST);
                    glEnable(GL_BLEND);
                    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
                }
                static void qt_restore_gl_state()
                {
                    glMatrixMode(GL_TEXTURE);
                    glPopMatrix();
                    glMatrixMode(GL_PROJECTION);
                    glPopMatrix();
                    glMatrixMode(GL_MODELVIEW);
                    glPopMatrix();
                    glPopAttrib();
                    glPopClientAttrib();
                }
                void GLWidgetnew::renderText(double x, double y, const QString text)
                {
                    GLdouble textPosX = x, textPosY = y;
                    // Retrieve last OpenGL color to use as a font color
                    GLdouble glColor[4];
                    glGetDoublev(GL_CURRENT_COLOR, glColor);
                    QColor fontColor = QColor(glColor[0]*255, glColor[1]*255, 
                    glColor[2]*255, glColor[3]*255);
                    // Render text
                    QPainter painter(this);
                    painter.translate(float(_shiftX),float(_shiftY)); //This is for my own mouse event (scaling) 
                                                
                    painter.setPen(fontColor);
                    QFont f;
                    f.setPixelSize(10);
                    painter.setFont(f);
                    painter.drawText(textPosX, textPosY, text);
                    painter.end();
                }
                

                Note that one might need to adjust the renderText function for some special purposes (e.g., scaling, translation etc)

                src code of the project can be found here QtSignalProcessing

                1 Reply Last reply
                1

                • Login

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