Hello everyone, I use c++17, ubuntu 20.04 and qt 5.12. I have a project where I use QGraphicsView, QGraphicsScene and QGraphicsItem. To increase performance, I switched to OpenGL render . So QGraphicsView 's viewport is plain QOpenGLWidget :
std::unique_ptr<GraphicsView> _view;
std::unique_ptr<QOpenGLWidget> _glViewport;
// ......
_view->setViewport(_glViewport.get());
std::unique_ptr<GraphicsView> _view;
std::unique_ptr<QOpenGLWidget> _glViewport;
// ......
_view->setViewport(_glViewport.get());
To copy to clipboard, switch view to plain text mode
And I also use OpenGL inside QGraphicsItem:
aint() method:
{
painter->beginNativePainting();
initializeOpenGLFunctions();
std::call_once(_onceFlag, &GLitem::initStuff, this);
// draw stuff
_vao.release();
_shaders.release();
painter->endNativePainting();
}
void GLitem::UploadGeometry()
{
// here i create VAO, VBO and shaders
// this function is called only once in a valid context, 'cause std::call_once
// QOpenGLVertexArrayObject _vao;
// QOpenGLBuffer _vbo;
}
void GLitem::paint(QPainter *painter,
const QStyleOptionGraphicsItem * option,
QWidget * widget)
{
painter->beginNativePainting();
initializeOpenGLFunctions();
std::call_once(_onceFlag, &GLitem::initStuff, this);
// draw stuff
_vao.release();
_shaders.release();
painter->endNativePainting();
}
void GLitem::UploadGeometry()
{
// here i create VAO, VBO and shaders
// this function is called only once in a valid context, 'cause std::call_once
// QOpenGLVertexArrayObject _vao;
// QOpenGLBuffer _vbo;
}
To copy to clipboard, switch view to plain text mode
So the problem is, that when I close this program, it crashes. And the problem is in GLitem D-tor:
~GLitem()
{
if (_vao.isCreated())
_vao.destroy();
if (_vbo.isCreated())
_vbo.destroy();
if (_shaderProgram->isLinked())
_shaderProgram->removeAllShaders();
}
~GLitem()
{
if (_vao.isCreated())
_vao.destroy();
if (_vbo.isCreated())
_vbo.destroy();
if (_shaderProgram->isLinked())
_shaderProgram->removeAllShaders();
}
To copy to clipboard, switch view to plain text mode
I've read in the documentation, that you need
void QOpenGLVertexArrayObject::destroy()
Destroys the underlying OpenGL vertex array object. There must be a valid OpenGL context that supports vertex array objects current for this function to succeed.
QOpenGLVertexArrayObject QOpenGLBuffer
So I need QOpenGLContext, but I don't create it explicitly anywhere in my program. And I tried to create it in D-tor but it did not help. I also figured out, that since I use QGraphicsView, then my Context is viewport and I tried to work with that, but it also didn't help. So the main problem is that my program crashes when D-tor is getting called. I don't know how to fix this. I know, that it's not the best approach in Qt+OpenGL, but I can't switch to the better method (like defining my own QOpenGLWidgets)
One caveat is that I initialize vao, vbo and shaders inside member function using std::call_once inside paint() method, so with that I can be assured that all that stuff is going to be created during a valid context, I don't think that it is a good approach, but I don't know how to do it otherwise.
Bookmarks