Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

 //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

like image 596
brainydexter Avatar asked May 18 '10 22:05

brainydexter


1 Answers

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.

like image 107
brainydexter Avatar answered Sep 23 '22 23:09

brainydexter