@black_list_man

Как правильно управлять OpenGL ресурсами в Qt приложении?

До этого использовал QPainter API, и таких вопросов не возникало. Выделял ресурсы в конструкторе, удалял в деструкторе. Решил перейти на OpenGL и столкнулся с тем, что работа с ресурсами возможна только в потоке отрисовки. Рисую под QML, по событию
QQuickWindow::beforeRendering
Сейчас у всех объектов, владеющих ресурсами есть метод init, и флаг isReady, и при каждом вызове отрисовке приходится проверять был ли он уже инициализирован или нет. Либо создавать объекты в нужном потоке, и каждый раз проверять был ли он уже создан. С удалением пока вообще не решил как быть. При нажатии кнопки, отвечающей за смену стиля, я раньше мог просто заменить все битмапы на другие, непосредственно в обработчике нажатия. А теперь нужно взводить флаг isDirty и ждать вызова отрисовки, чтобы обновить/удалить текстуры, и флаг при каждом кадре нужно проверять. Приходится проверять был ли буфер уже инициализирован, или только ждет нужного потока для инициализации. Очень много оверхэда и как-то все неудобно и нелогично выглядит. Я чего-то не понимаю, и другого пути действительно нет? Очень хочется управлять ресурсами тогда, когда мне удобно, а не ждать нужного потока. Это вообще возможно? Есть какая-то практика?
Даже в официальных примерах все пронизано проверками, чтобы создавать объекты непосредственно в потоке отрисовке, вот например:
void SquircleRenderer::paint()
{
if (!m_program) {
        initializeOpenGLFunctions();

        m_program = new QOpenGLShaderProgram();
	...

	...
}
}


Вот например, у меня картографическое приложение, отображающее растровые тайлы. В обработчике события мыши или изменения размера экрана (в общем, когда изменилась видимая область карты) мне нужно пересчитать какие тайлы нужно загрузить и какие можно удалить. Но я не могу просто удалить тайл в этом потоке, потому что он содержит текстуру. А когда изображение для тайла загрузится, мне нужно создать новую текстуру и поместить его туда. Но я опять же не могу этого сделать, ведь загрузка тайла асинхронная и в этом потоке контекст не активен. Приходится хранить флаг isLoaded и уже в потоке отрисовке проверять его, и если нужно загружать текстуру. А это в свою очередь, пусть и не сильно, но влияет на отзывчивость. Логично было бы в фоновом потоке инициализировать все ресурсы, а в потоке отрисовки только рисовать.
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 1
Zifix
@Zifix Куратор тега Qt
Barbatum
А вам точно стандартный компонент карты не подойдет, и нужно изобретать велосипеды?

Есть ещё QQuickPaintedItem, в который можно рисовать как угодно, а ещё, QPainter можно ускорить через OpenGL.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы