QPainter Overwrites OpenGL state in QOpenGLWidget



  • 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.



  • 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();
    
    


  • 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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.