Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved QPainter Overwrites OpenGL state in QOpenGLWidget

    General and Desktop
    3
    4
    1099
    Loading More Posts
    • 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
      bobthebuilder last edited by

      I am using a QOpenGLWidget to render some 3D shapes using OpenGL. I occasionally want to render some text into the GL frame buffer, and QPainter seems to have support for this. I noticed that when I create a QPainter as a local member variable within the QOpenGLWidget instance via

      // My OpenGL settings are valid here
      {
          QPainter painter(this);
          // ... code to render text with painter
      }
      // QPainter has overwritten my OpenGL settings here
      

      that the QPainter overwrites my OpenGL settings, however (including multi-sampling settings that I set previously through QSurfaceFormat::setDefaultFormat). I see that QPainter has beginNativePainting and endNativePainting methods, but these don't seem to work in my case where I already have existing OpenGL state that I want restored when the QPainter is destructed:

      {
          QPainter painter;
          painter.endNativePainting(); // This doesn't work, QPainter prints 'Painter not active' at this line
          painter.begin(this);
          // ... code to render text with painter
          painter.end();
          painter.beginNativePainting();
      }
      

      Is there a way to have the QPainter restore any settings that it overwrites? Restoring the settings manually seems brittle, and the documentation says that the overwritten settings may change in the future. I am using Qt 5.8 on OS X 10.11.6.

      1 Reply Last reply Reply Quote 0
      • R
        Rondog last edited by

        I believe this is known to happen; I think I read that somewhere. Anyway you just push all the OpenGL attributes and pop them when you are done with QPainter.

        Example:

        	// QPainter changes one or more attributes so all relevent ones
        	// are pushed then popped on end of QPainter
        	glPushAttrib(GL_ACCUM_BUFFER_BIT);
        	glPushAttrib(GL_VIEWPORT_BIT);
        	glPushAttrib(GL_TRANSFORM_BIT);
        	glPushAttrib(GL_POLYGON_BIT);
        	
        	glPushAttrib(GL_PIXEL_MODE_BIT);
        	glPushAttrib(GL_MULTISAMPLE_BIT);
        	glPushAttrib(GL_LIGHTING_BIT);
        	glPushAttrib(GL_ENABLE_BIT);
        	
        	glPushAttrib(GL_DEPTH_BUFFER_BIT);
        	glPushAttrib(GL_CURRENT_BIT);
        	glPushAttrib(GL_COLOR_BUFFER_BIT);
        
        	// start of QPainter
        	QPainter	 painter(this);
        	
        	// painter stuff	
        	painter.end();
        	
        	// restore OpenGL attributes
        	glPopAttrib();
        	glPopAttrib();
        	glPopAttrib();
        	glPopAttrib();
        	
        	glPopAttrib();
        	glPopAttrib();
        	glPopAttrib();
        	glPopAttrib();
        	
        	glPopAttrib();
        	glPopAttrib();
        	glPopAttrib();
        
        
        S 1 Reply Last reply Reply Quote 2
        • B
          bobthebuilder last edited by bobthebuilder

          Thanks, I ended up manually pushing and popping the state that QPainter overwrites like you suggest. I was hoping that the widget would be able to tell me what state it overwrites (because who else would know!), but reading through the source code it appears there is nothing that offers this functionality.

          1 Reply Last reply Reply Quote 0
          • S
            StefanBruens @Rondog last edited by

            @Rondog

            Unfortunately, I can not use this approach - glPushAttrib is deprecated, and even not available in GLES or Core 3.1 contexts.

            1 Reply Last reply Reply Quote 0
            • First post
              Last post