Про Qt и OpenGL

С помощью профайлера и отладчика узнал прекрасное.

Прекрасное, конечно же, описано в мануале, но кто же их читает:

QGLContext::DefaultBindOption LinearFilteringBindOption | InvertedYBindOption | MipmapBindOption In Qt 4.5 and earlier, bindTexture() would mirror the image and automatically generate mipmaps. This option helps preserve this default behavior.
А я все удивлялся, отчего у меня bindTexture для ~мегапиксельной картинки выполняется миллисекунд 20. Ну конечно, оно переворачивает изображение.

Оторвал. Стало быстрее раз в 10 минимум (на глазок, по профайлеру).

Из другого прекрасного:

  • Если использовать QOpenGLBuffer::bind() и потом, после рисования или заполнения, не сказать ему QOpenGLBuffer::release(), то в QGraphicsView/Scene отваливается отображение элементов, нарисованных стандартным путем (через addItem).
  • Если генерировать структуры руками (glBindTexture/glTexImage2D), но забыть про установку фильтрации, то текстура вовсе не отображается.
Как я уже писал, сколько же есть вещей, которые я предпочел бы не знать.

День прошел не зря.

Comments

Про миррор интересно. Вроде где то всплывало. Думал в матрицах накосячил.

Ну я mirror воспринял как должное. Ну то есть "Y растет вверх" - это я сразу заметил и систему координат перевернул. То что текстуру нужно отдельно переворачивать - воспринял как данность.

А до glBindTexture руками - сначала не добрался т.к. у меня оно не заработало (т.к. я опции для масштабирования не задал). Ну тогда пошел в отладчике чтобы весь gl-код который реально исполняется - просто скопировать. И тут же добрался до прекрасного.

Понятно, если бы у меня ручное glBindTexture перевернуло бы структуру (относительно того, к чему я привык) - я бы насторожился.

При этом, заметим, Qt-шные примеры перевернутую структуру воспринимают как данность и тщательно выписывают перевернутые же текстурные координаты.

Но самое прекрасное - все-таки про буфер. Я вообще не могу представить, отчего такое. Т.е. похоже, там где-то при отрисовке scene items проверяется - а нету ли у нас буфера уже. И если есть - то свой не прицепляется. Но в отладчике туда не пойду.

При этом текстуры, к примеру, отбинживать не надо.

Из недокументированного:
Если хочется всовывать свой opengl код в стандарнтый QML UI, то для этого есть QSGRenderNode, которая только в private APIs и вроде как может поменяться, но т.к. используется в вебките, то скорее всего никуда не уйдёт и сильно меняться не будет. Правда, стандартный QML будет чуть медленнее, т.к. присутствие QSGRenderNode в дереве выключает некоторые отпимизации. Стандартные afterRendering/beforeRendering позволяют отрисовывать свой GL только под QML или поверх него, что не всегда подходит.
Подсмотреть как использовать QSGRenderNode можно здесь: https://svn.webkit.org/repository/webkit/trunk/Source/WebKit2/UIProcess/...

В-общем, пока не надо. И пока desktop components не допилят - буду пользоваться QGrahics* и рисовать на background (отдельные items там тоже можно так рисовать)

Но спасибо, положил в бумарки.

В смысле на background?
Если в GraphicsView высталенв вьюпортом QGLWidget, то в paint любого айтема можно позвать painter->beginNativePainting, а потом painter->endNativePainting, то между ними можно выдавть свой GL код. При этом у меня для простых вещей даже клиппинг с трансформациями работали.

Да, я видел это в примере boxes.
Но пока не вижу, куда я бы мог это применить.

Интересно, кстати, а если nativePainting, то прозрачность (снаружи установленная) работает?

opacity?
По-моему нет. IMHO, нужно с qpainter брать opacity и самому вмешивать в gl код.

Ну я так и думал. Трансформации, поди, так же? Поворачивать и все такое - нужно самому?

В-общем, мне пока не надо.

Угу.
Но с пэйнтера можно вытащить трансформ.

А "на background" - в буквальном смысле.

Мне нужно вывести (здоровый) битмеп, а поверх него всякую ерунду. Проще всего оказалось оный битмеп выводить в QGraphicsScene::drawBackground.

А ерунду - средствами grahics scene