Предположим, у меня нарисована 3D-сцена, glDrawArrays(...)
и я хочу сделать что-то простое, например, 2D-наложение. Было бы плохой идеей использовать немедленный режим для такой вещи, вместо настройки 2D-рендеринга с сохраненным режимом?
Пример:
void Draw()
{
// Draw the 3D scene:
// *does stuff*
glDrawArrays(...);
// *some other stuff*
// Setup a quad with immediate mode (for something like a vignette overlay)
glBegin(GL_QUADS);
glTexCoord2f(...); glVertex2f(...);
glEnd();
}
Ответы:
Это плохая идея, поскольку это бессмысленно. Нет ничего для «настройки», которую вы еще не сделали, за исключением матрицы ортопроекции (что вам придется делать в любом случае).
Переносимость, вероятно, не является проблемой, хотя и должна быть. IHV, похоже, очень неохотно отказываются от поддержки немедленного режима в обозримом будущем (кажется, что он «работает» даже в основных профилях), поэтому, хотя немедленный режим должен был давно исчезнуть, он, вероятно, останется навсегда. Производительность это другая история. Вы действительно хотите, чтобы что-то, что составляет 0,1% сложности сцены, занимало 15-20% процессорного времени - вызовы GL относительно легки по сравнению, например, с DX, но они не бесплатны - и 15-20% реальное время кадра из-за остановки трубопровода? Вы можете даже позволить себе это с вашим временным бюджетом? Большинство игр не могут.
И, конечно, причуды. О, причуды. Очевидная красота немедленного режима заключается в том, что (на первый взгляд) легко и просто сделать что-то вроде быстрого рисования пары четырехугольников. В действительности немедленный режим может быть такой болью в тылу, он полон неочевидных ловушек.
С другой стороны, так же просто (и более просто, если вы спросите меня!) Просто написать небольшую функцию 5-LOC,
DrawQuad
которая при вызове добавляет координаты вершины и индексы в буфер памяти и увеличивает счетчик. Который, к удивлению, вы можете затем нарисовать,glDrawArrays/Elements
и который вы можете использовать повторно (копию GPU, а не только копию пользовательской области!) В следующем кадре, пока ничего не изменилось.Непосредственный режим должен, иначе нет, выделить буфер и каждый раз выполнять передачу PCIe. Или что-то эквивалентное по задержке (GPU читает основную память по шине, что угодно). Драйвер не может знать (или предполагать), что данные остались в точности такими же, как в предыдущем кадре.
Передача данных в графический процессор - это высокоскоростная, но также высокопроизводительная операция. Перенос по шине сам по себе является сложным протоколом с высокой задержкой (несколько уровней протоколов, пакетирование, подтверждения и т. Д.), Но также не все графические процессоры способны даже передавать и рисовать одновременно или если они могут это делать они могут быть не в состоянии все время переключаться или инициировать новые операции свободно, делая что-то другое. Читайте как: Ты не будешь переносить напрасно .
источник
intel
драйвер), а также чипы NVidia и AMD при использовании драйверов с открытым исходным кодом (nouveau
иamdgpu
соответственно). Аналогично, в MacOS у вас также нет профиля совместимости с OpenGL> 2.1.glDrawArrays
. Таким образом, есть все, что нужно сделать, чтобы сделать еще один вызовglDrawElements
(или Array, в зависимости от того), чтобы нарисовать все квады для GUI (после записи вершин в буфер). Функции загружены, у вас есть структура для распределения буферов и т. Д. Ничего особенного не нужно делать с пакетированием графического интерфейса, на самом деле. Просто свяжите (или нет, если у вас осталось достаточно TU, чтобы оставить его связанным) с текстурой GUI, установите орто-матрицу и выполните один дополнительный вызов отрисовки. Как вы хотите выпечки лучше?Лично я считаю это плохим по двум причинам:
Но, если это работает, и производительность не будет проблемой, и если для вас не проблема использовать устаревшие функции OpenGL в вашей программе, то я думаю, что вы могли бы это сделать. Это будет медленнее иметь TONS и TONS GUI, но если это не так много, опять же, пойти на это.
Пойми это, хотя. Что в конце дня OpenGL делает то же самое; рисование на экране. Немедленный режим просто намного медленнее, если вы обрабатываете много вещей. Итак, вы должны выбрать, что является наиболее полезным для задачи, которую вы имеете в виду. Надеюсь, что это помогает вам!
источник
Другим недостатком является то, что он делает ваш код менее переносимым. Некоторые варианты OpenGL вообще не поддерживают непосредственный режим, например, OpenGL ES. (и по мере того, как устройства на базе Android более крупного калибра, такие как планшеты, приобретают все большую популярность, это может стать важным)
источник
Использование немедленного режима совершенно не нужно для работы с графическим интерфейсом.
Чтобы создать простой элемент графического интерфейса, скажем, кнопку:
Таким образом, вы можете просто написать простой сквозной шейдер, который игнорирует соображения освещения, и вы просто масштабируете элемент графического интерфейса до пиксельного масштаба или некоторого процента окна, а затем выполняете алгоритм рисования для рисования.
Таким образом, вы можете создать полноценную систему пользовательского интерфейса со всеми преимуществами производительности в сохраненном режиме.
источник