简而言之:打开gl绘图
QOpenGLWidget
应该发生在
QOpenGLWidget::paintGL()
.
当调用opengl命令时,一个先决条件是resp。OpenGL上下文以前已激活。这是什么
QOpenGLWidget::paintGL()
确保:
不用打电话
makeCurrent()
因为在调用此函数时已经执行了此操作。
在调用此函数之前,将绑定上下文和帧缓冲区,并通过调用glviewport()来设置视口。
另外一个先决条件是opengl上下文已经创建完毕。
为了找到更多关于这个的信息,我深入了一点
QOpenGLWidget::paintEvent()
(在woboq.org上):
void QOpenGLWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
Q_D(QOpenGLWidget);
if (!d->initialized)
return;
if (updatesEnabled())
d->render();
}
-
只要尚未完成初始化,paint事件就不会执行任何操作。(我没有深入研究,但我确信初始化涉及调用
QOpenGLWidget::initializeGL()
)
-
绘制事件请求渲染。
用眼睛看代码(严格地说:鼠标点击)。
d->render()
电话
QOpenGLWidgetPrivate::render()
最后又来了电话
QOpenGLWidgetPrivate::invokeUserPaint()
我们在这里:
void QOpenGLWidgetPrivate::invokeUserPaint()
{
Q_Q(QOpenGLWidget);
QOpenGLContext *ctx = QOpenGLContext::currentContext();
Q_ASSERT(ctx && fbo);
QOpenGLFunctions *f = ctx->functions();
QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbo->handle();
f->glViewport(0, 0, q->width() * q->devicePixelRatioF(), q->height() * q->devicePixelRatioF());
inPaintGL = true;
// vvvvvvvvvvvv
q->paintGL();
// ^^^^^^^^^^^^
inPaintGL = false;
flushPending = true;
QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = 0;
}
(评论是我的。)
所以,如果
QoPenglWidget::paintEvent()
是重载的,那么它应该调用
paintEvent()
基本阶级的。(否则,opengl渲染肯定会中断。)
最后,当我改变几何图形时,如何强制重新提交图形?我应该调用什么方法?
这实际上在上的描述中得到了回答
Qopenglwidget酒店
:
如果需要从paintgl()以外的位置触发重绘(典型的例子是使用计时器设置场景动画),则应该调用小部件的
update()
函数来计划更新。
万一,我误解了OP的意图,实际的问题是放在哪里
QPainter
并入
Qopenglwidget酒店
–我曾经给
SO: Paint a rect on qglwidget at specifit times
关于混合opengl命令和
Q画师
并入
paintGL()
.