Получить только один QOpenGLContext для разных виджетов QT

У меня следующая проблема:

Я хочу получить приложение, состоящее из множества представлений, которые отображают общую сцену OpenGL с другой точки зрения, освещения и других параметров.

По сути, мой вопрос: как лучше всего это сделать с помощью qt?

Моей первой попыткой было создать несколько QOpenGLWidget и получить общий QOpenGLContext, где я хранил текстуры, а также сетки и шейдеры.
Но это не сработало для мешей, потому что объекты Vertex Array, кажется, не могут использоваться совместно.
После многих попыток возможное решение — сохранить один VAO для каждого виджета, которому нужна сетка, но это выглядит ужасно.

Итак, мне интересно, есть ли хорошая альтернатива для такого рода проблем, или, может быть, хорошая документация, чтобы понять, как работают эти QOpenGLContext.

Самая простая идея, которую я себе представил, — создать только один QOpenGLContext и использовать его в разных виджетах. Но я не знаю, как просто создать QOpenGLContext в одиночку, и какой QWidgets может отображать эти визуализации.

Это мой первый пост, поэтому я не знаю, достаточно ли он ясен или мне нужно описать всю мою архитектуру.

2

Решение

Вы уже пробовали, поэтому я передаю слово об общих контекстах.

Контекст OpenGL привязан к окну: если вам нужен только один контекст, прямой ответ — иметь только одно окно.

Используя модуль виджетов, вы можете иметь несколько видов одной и той же сцены, используя несколько окон просмотра в одном QOpenGLWidget. Что-то вроде:

void myWidget::paintGL() {
//...

glViewport(
0, 0,
this->width()/2, this->height()/2
);

// draw scene from one point of view

glViewport(
this->width()/2, this->height()/2,
this->width()/2, this->height()/2
);

// draw scene from an other point of view

//...
}

Вам, вероятно, следует разработать класс видового экрана для хранения и управления параметрами рендеринга для каждого видового экрана.

Недостатком является то, что вам придется определять, в каком окне просмотра пользователь щелкает для обработки взаимодействий: какой-то вид if event.pos.x is between 0 and this->width()/2 ...,


Другим способом может быть отключить модуль виджетов и использовать Qt Quick и QML: быстрое окно объявляет уникальный контекст OpenGL, где каждый быстрый элемент похож на область просмотра, но инкапсулирован в своем собственном объекте, поэтому вам не нужно думать о том, где пользователь взаимодействует.

Унаследуйте QQuickItem вместо QOpenGLWidget и экспортируйте свой класс в QML с помощью макроса qmlRegisterType (). Затем вы можете создать QQuickView в своей программе для загрузки кода QML, в котором вы декларируете свои элементы. Пример из документации Qt Вот.

-1

Другие решения

Я думаю, так как несколько представлений могут быть обновлены независимо, к сожалению, невозможно иметь один единственный QOpenGLContext, который выполняет эту работу. И у обмена контекстами есть ограничение, которое вы уже указали в своем вопросе.

QOpenGLContext может быть перемещен в другой поток с помощью moveToThread ().
Не вызывайте makeCurrent () из другого потока, чем тот, который
которому принадлежит объект QOpenGLContext. Контекст может быть только текущим
в одну нить и против одной поверхности за раз, и нить имеет только
один контекст, текущий за один раз.

Ссылка на сайт : http://doc.qt.io/qt-5/qopenglcontext.html

Таким образом, один из способов заставить его работать, — это иметь независимые обновления ваших представлений в последовательном порядке и делать контекст текущим по одному и отображать его перед переходом к следующему представлению. Это гарантирует, что контекст актуален только в одном представлении в любой момент времени. Возможно, используйте QMutex для сериализации обновлений.

В качестве альтернативы вы также можете передавать контекст между потоками и сериализовать их обновления, но это плохой подход.

-1

По вопросам рекламы [email protected]