2d HUD not drawing properly over QGLWidget (using QPainter)
I am trying to display HUD over my 3D game. For starters, I am just trying to display "Hello World", but I haven't had any success yet! The scene freezes / flickers once I am done.
I am using Qt/C++ and QGLWdiget / QPainter to get this done. I have used overpainting example as my reference to get started. Here is what I do:
- override paintEvent(...) in my own subclassed GameGL Class ( GameGL : public QGLWidget )
- Push openGL ModelView matrix as the current matrix
- enable parameters as gl_depth_test
- render my game (:: paintGL1() )
- disable the modelview parameters
pop modelview matrix
Make QPainter object
- invoke paint.drawText()
- Flush using paint.end()
This is pretty much the same as mentioned in the example. However, when I run this code, it experiences freezing / flickering and is highly un-responsive. Would anyone have any idea as to why this might be happening ? I'd really appreaciate any help.
Code:makeCurrent(); glMatrixMode(GL_MODELVIEW); glPushMatrix();
//Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//.50f, 1.0f );
//glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
m_pLight->SetupLight(GL_AMBIENT | GL_DIFFUSE | GL_SPECULAR);
glEnableClientState( GL_INDEX_ARRAY );
glEnableClientState( GL_VERTEX_ARRAY );
resizeGL( width(), height() );
paintGL1();开发者_JAVA技巧
//glShadeModel(GL_FLAT);
glDisable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glDisableClientState( GL_INDEX_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.drawText(100, 50, QString("Hello"));
painter.end();
Thank you
For anyone who is still struggling with this and came across this post: here is how I solved it::
Please follow the overpainting example as is. If you look over at the code in the example, you would notice in the constructor, a timer timeout()
SIGNAL is connected to animate()
SLOT. If you look closely at the animate() slot, it in-turn calls update()
a.k.a GLWidget::update()
. If you follow the documentation for GLWidget::update(); this in-turn calls paintEvent(...)
.
This background is important and was the missing piece to my problem. I was earlier using paintGL(...) to draw my scene since I had overriden GLWidget. To support animation or updates to my scene, I had connected the timer to updateGL(). This was in-turn invoking paintGL() via glDraw(). This was the root cause of all the problems.
The code as I had written was calling paintGL() again and again. Following overpainting example, I got rid of paintGL method completely and switched to paintEvent(...) rendering methodology instead. Thus, to keep things in-sync, I had to call update() (instead of updateGL() ) to make things work. The minute I made this transition, things started working as expected. (GLWidget::update()
calls paintEvent(...)
)
I hope it has helped you any bit. If it still doesn't work for you or need firther explanaition, leave me a comment here and I will try to help.
精彩评论