【发布时间】:2020-05-12 08:34:03
【问题描述】:
我想在QOpenGLWidget中绘图,处理数据并在mousePressEvent()函数中调用repaint():
QPoint point[2];
QImage img=QImage(1000,800,QImage::Format_Grayscale8);
void Widget::mousePressEvent(QMouseEvent *event)
{
point[0]=event->pos();
point[1]=point[0]+QPoint(10,10);
repaint();
}
现在在paintGL() 中重新绘制小部件:
void Widget::paintGL()
{
vao->release();
vbo->release();
QPainter painter;
painter.begin(image);
painter.drawLine(point[0],point[1]);
painter.end();
painter.begin(this);
painter.drawImage(0,0,*del->tmpImages[1]);
painter.beginNativePainting();
vao->bind();
vbo->bind();
glViewport(0,0,200,200);
glDrawArrays(GL_TRIANGLE_STRIP,0,8);
painter.endNativePainting();
painter.end();
}
我有三个问题。
为什么我必须释放 vao 和 vbo 才能在 paintGL() 中使用 QPainter 绘制小部件,如果没有,Qpainter 将不起作用。
同时使用 QPainter 和 OpenGL API 时,widget 无法在 paintGL() 中绘制纹理。直接调用OpenGL API就可以了。
当我频繁重绘小部件时(频繁点击小部件,调用mousePressEvent()和repaint()),Qt忽略了一些重绘事件。如果调用repaint(),QWidget会立即重绘,所以我该如何强制Qt重绘QOpenGLWidget就像调用repaint()重绘QWidget一样?
【问题讨论】:
-
不是 Qt OpenGL 大师,但我认为您需要在函数结束时在
vao和vbo上调用release。 -
我试过了,如果最后调用释放,所有的 OpenGL API 都不起作用。如果在开始时调用 release,则只有纹理不显示。
-
关于 (3.):为什么要立即重绘?通常,it's better to call
QWidget::updatethanQWidget::repaint(see also this one)。如果您想存储渲染的纹理并且需要所有帧(在屏幕上不可见),您可能更喜欢一些离屏渲染解决方案。