OpenGL

Q: Qt, Dynamic OpenGL, OES/ARB extensions

Вот что-то наткнулся и смотрю как на новые ворота.

Преамбула:

  1. Вот есть такой Qt, в нем есть работа с OpenGL
  2. У кого OpenGL нету или кривой - есть библиотека ANGLE, которая эмулирует OpenGL ES2 (или 3) поверх DirectX 9 (или, соответственно, 11).
  3. OpenGL ES от простого отличается, в числе прочего, названиями extensions. Ну, к примеру, GL_OES_get_program_binary у ES/GL_ARB_get_program_binary у обычного.
  4. У Qt 5.4 (под Windows) появилась возможность динамической загрузки имплементации OpenGL. До инициализации QApplication говоришь что хочешь, а дальше
  5. ...

Немого кино уже нет, звукового кино еще нет....

Вот есть некая программа, которая активно использует OpenGL.

Используется Qt5 и все было бы хорошо, если бы не моментики:

  • QWidget::showFullScreen() не работает на Mac OS X 10.6
  • Курсор в форме руки - остается таковым и при выносе мыши за окно программы (тоже на Mac, на винде все нормально).
По первому случаю - я засабмитил баг, прямо вот 1-го января. Но он все еще в состоянии Not Evaluated (что неудивительно, если посмотреть на график количества багов в Qt за последние 30 дней). По второму - вроде нашел багрепорт, им как-то занимаются.

Ладно, у меня ничего специфического от Qt5 нету, собираем все то же самое на Qt 4.8.4. Работает (ну, пришлось поменять QOpenGLProgram на QGLProgram и так далее в том же духе, но изменений - мало).

Но:

На операционках, запущенных под VMWare (и Windows и Mac) - валится в QGLFunctions::initializeGLFunctions(), судя по отладчику - GL-контекст в этом месте нехорош, дальше не разбирался).

При этом, Qt5 на этих же виртуальных машинах - работает, возможностей тамошнего OpenGL вполне хватает.

На настоящих железных компьютерах с настоящим OpenGL - версия собранная с 4.8 - работает, а неприятные мне баги на маках - отсутствуют. Фулскрин работает, курсор меняет форму как надо.

Ну и как с ними жить? Баги Qt5 явно быстро не починят. Багу Qt 4.8 - скорее всего тоже не починят. Не, ну я могу gl....() сам порезолвить, но обидно же ж.

Q: "OpenGL на CPU"?

Преамбула

Несмотря на долбанутость OpenGL-ного API (и, как следствие, огромное количество глупых ньюбских ошибок, которые я допустил), сам OpenGL мне очень понравился.

Вот, к примеру, код в RawDigger, который занимается визуализацией, это 500+ строк довольно нетривиального кода которые делают:

  • Raw Composite
  • Поканальный показ
  • Overexposure/Underexposure
На OpenGL шейдер, который делает ровно то же самое (ну, да, немножко поменьше, в RD есть всякие режимы 2x2 pixels) - это 11 строк кода, несколько строк определения переменных, ну и, да,...

Хозяйке на заметку: Qt, OpenGL и PBO

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

Вот есть QGraphicsView, направленный в QGLWidget. Есть еще QGraphicsScene, у которой с помощью drawBackground() рисуем нужное нам (картинку).

Этот самый drawBackground() использует текстуры, одну или много, текстуры залиты через PBO.

Дальше - пытаюсь вывести на эту Scene другие объекты. Ну, как в документации написано, к примеру так:

QLabel *label =
...

Qt+OpenGL benchmarking Q

А вот, я извиняюсь, такой вопрос.

Есть QGrahicsScene (унаследованное от нее) в которой я в drawBackround вывожу OpenGL-ем нечто.

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

Но как?

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

for(.....){
myview->setZoom(...);
QApplication::processEvents();
}

Но получается вот что:

  • FPS-ов ровно 60 (2000 итераций за 34 секунды), OGLFormat::setSwapInterval(0) не помог.
  • Одно ядро процессора полностью загружено.
  • По профайлеру, загружено оно QWindowsWindow::raise() (~70% по профайлеру), вообще весь прочий код занимает остальные 30% CPU, моего кода вовсе не видно.

Так слона не продать.

Ну то есть понятно, можно в OpenGL-рисовалке рисовать одно и то же 10 (100,1000) раз подряд, но вопрос заключается в том, нет ли более прямого пути, который позволяет Qt-GUI программы побенчмаркать попроще?

Update: если вдруг кому интересно, то проблема решилась глобальным выключением VSync в настройках драйвера (NVidia). FPS-ы сразу сильно выросли, а профайл исполнения стал похож на настоящий.

Про 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), но забыть про установку фильтрации, то текстура вовсе не отображается.
Как я уже писал, сколько же есть вещей, которые я предпочел бы не знать.

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

OpenGL Qs

Сразу предупреждаю: с OpenGL я пытаюсь работать всего неделю (был еще подход к снаряду, но началось лето и я переключился на МонголиеКарелии), поэтому вопросы у меня, вероятно, глупые и вообще про разное.

Вопросов, собственно, три:

1. Допустим, у меня очень простая сцена, два треугольника, образуют прямоугольник, на них натягиваю текстуру (собственно, картинку, которую хочу показать).

Вопрос: есть ли смысл связываться с VBO или 6 пар вызовов glTexCoord2f()/glVertex2f() не будут заметно медленнее? А если прямоугольник не один, а, к примеру, 64 (картинка 8000x8000, а на предельный размер текстуры я заложусь как 1024x1024), будет ли заметный выигрыш, если загнать все в буфер(ы) и дергать рисование меняя только индексы?

Это мне больше для понимания, понятно что как только захочется что-то нарисовать шейдером, так сразу VBO понадобятся.

2. В Qt5 есть (старые) QGL*-объекты, есть новые QOpenGL*.

Кто бы рассказал, в чем разница....

3. Ну и вообще, Qt-шные примеры, что из комплекта, что найденные в сети, какие-то частично безумные. То слишком простые, то вроде простой - а шейдеры там внезапно "#version 330", то - очень хороший пример boxes из поставки - но переусложненный, начинаешь от него куски отпиливать и все разваливается.

Нет ли каких-то Qt-OpenGL tutorials, которые бы с одной стороны были бы "современными" (в смысле используемых Qt-интерфейсов), интересными (не банальный QGLWidget::paintGL()), но и не слишком сложными.

A: OpenGL book Q: OpenGL compatibility

Отвечаю сам себе, вдруг кому-то еще интересно.

  1. Из всех просмотренных книжек больше всего показалась Learning Modern 3D Graphics Programming, потому что она от fixed pipeline полностью отвязана. Только OpenGL 3+, только хардкор (хотя CoreProfile в Qt и не работает нормально, текстуры не аплоадятся).

    PDF-ная версия и примеры берутся отсюда.

    Буду теперь ея читать.

  2. Вообще, оно (OpenGL) отвратительное. Вот, например:
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
    glEnableVertexAttribArray(
  3. ...

Q: OpenGL book

Вот смотрю я на профили исполнения RawDigger и вижу, что на отрисовку пиксельного буфера там уходит заметное время. Особенно заметное, если картинка здоровая, а кроме перерисовки - ничего не происходит (скажем, каналы RAW переключаются).

Решение, казалось бы, очевидное: загнать это самое RAW в виде текстуры в видеокарту и рисовать дальше уже средствами видеокарты же. Пиксельные шейдеры и все такое. Короче, OpenGL.

Разглядывание (несколько дней на даче сидел и разглядывал) всяких простых OpenGL-ных примеров навело меня на очевидную мысль - я нихрена в этом не понимаю совсем. А пора бы уже.

Отсюда вопрос: какую книжку "OpenGL для чайников за 21 день" вы бы мне посоветовали? На басурманском бегло читаю, наверное надежнее читать исходник, а не перевод.

От OpenGL мне, по большому счету, нужно банальное 2D: показ двумерной картинки, с зумированием (и показ участка), может быть наложение в 2D нескольких слоев с регулируемой прозрачностью. Идеальным был бы tutorial именно в этом вот духе.

Subscribe to OpenGL