2d HUD 无法在 QGLWidget 上正确绘制(使用 QPainter)
我正在尝试在 3D 游戏上显示 HUD。对于初学者来说,我只是想显示“Hello World”,但我还没有取得任何成功!一旦我完成,场景就会冻结/闪烁。
我正在使用 Qt/C++ 和 QGLWdiget / QPainter 来完成此任务。我使用了覆盖示例作为入门参考。这就是我所做的:
- 在我自己的子类 GameGL 类( GameGL : public QGLWidget )中覆盖 PaintEvent(...)
- 推送 openGL ModelView 矩阵作为当前矩阵
- 启用参数作为 gl_depth_test
- 渲染我的游戏(:: PaintGL1() )
- 禁用模型视图参数
弹出模型视图矩阵
制作QPainter对象
- 调用paint.drawText()
- 使用paint.end()刷新
这与中提到的几乎相同例子。但是,当我运行此代码时,它会出现冻结/闪烁并且高度无响应的情况。有人知道为什么会发生这种情况吗?我真的很感激任何帮助。
代码: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();
谢谢
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于那些仍在为此苦苦挣扎并看到这篇文章的人:这是我解决它的方法::
请按原样遵循覆盖示例。如果您查看示例中的代码,您会注意到在构造函数中,计时器
timeout()
SIGNAL 连接到animate()
SLOT。如果仔细观察 animate() 插槽,它会依次调用update()
又名GLWidget::update()
。如果您遵循 GLWidget::update(); 的文档这又调用paintEvent(...)
。这个背景很重要,是我的问题所缺少的部分。自从我重写了 GLWidget 以来,我之前使用 PaintGL(...) 来绘制场景。为了支持动画或场景更新,我将计时器连接到 updateGL()。这又通过 glDraw() 调用 PaintGL()。这是所有问题的根源。
我编写的代码一次又一次地调用paintGL()。在重绘示例之后,我完全摆脱了paintGL方法并切换到paintEvent(...)渲染方法。因此,为了保持同步,我必须调用 update() (而不是 updateGL() )才能使事情正常工作。当我进行这种转变的那一刻,事情就开始按预期进行。 (
GLWidget::update()
调用paintEvent(...)
)我希望它对您有所帮助。如果它仍然不适合您或需要进一步的解释,请在这里给我留言,我会尽力提供帮助。
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 toanimate()
SLOT. If you look closely at the animate() slot, it in-turn callsupdate()
a.k.aGLWidget::update()
. If you follow the documentation for GLWidget::update(); this in-turn callspaintEvent(...)
.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()
callspaintEvent(...)
)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.