B
B
black_list_man2021-02-27 16:58:43
Qt
black_list_man, 2021-02-27 16:58:43

How to properly manage OpenGL resources in a Qt application?

Before that, I used the QPainter API, and there were no such issues. Allocate resources in the constructor, delete them in the destructor. I decided to switch to OpenGL and faced the fact that working with resources is possible only in the rendering thread. I draw under QML, by event

QQuickWindow::beforeRendering
Now all objects that own resources have an init method and an isReady flag, and on each draw call it has to check whether it has already been initialized or not. Either create objects in the desired thread, and each time check whether it has already been created. With the removal has not yet decided what to do. When clicking the button responsible for changing the style, I used to be able to simply replace all the bitmaps with others, directly in the click handler. And now we need to cock the isDirty flag and wait for the draw call to update / delete the textures, and the flag needs to be checked every frame. We have to check whether the buffer has already been initialized, or is just waiting for the right thread to be initialized. There is a lot of overhead and somehow everything looks uncomfortable and illogical. Am I missing something and is there really no other way? I really want to manage resources when it's convenient for me, instead of waiting for the desired flow. Is it even possible? Is there any practice?
Even in the official examples, everything is riddled with checks to create objects directly on the rendering thread, for example:
void SquircleRenderer::paint()
{
if (!m_program) {
        initializeOpenGLFunctions();

        m_program = new QOpenGLShaderProgram();
  ...

  ...
}
}


For example, I have a mapping application that displays raster tiles. In the mouse event handler or screen size change (in general, when the visible area of ​​the map has changed), I need to recalculate which tiles need to be loaded and which can be deleted. But I can't just delete a tile in that stream because it contains a texture. And when the image for the tile is loaded, I need to create a new texture and place it there. But again, I can’t do this, because the loading of the tile is asynchronous and the context is not active in this thread. You have to store the isLoaded flag and check it already in the rendering thread, and if you need to load the texture. And this, in turn, albeit not much, but affects responsiveness. It would be logical to initialize all resources in the background thread, and only draw in the rendering thread.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
Jacob E, 2021-02-28
@Zifix

Are you sure the standard map component will not work for you, and you need to reinvent the wheel?
There is also QQuickPaintedItem , in which you can draw as you like, and also, QPainter can be accelerated through OpenGL .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question