Чому OpenGL> = 3 дозволяє лише VBO?


21

Я бачу, що версії 3 та новіші версії OpenGL усувають використання візуалізації на стороні клієнта. Негайний режим було усунено, а вершинні масиви, здається, застаріли. Натомість, якщо я правильно розумію, VBO - це основний спосіб надання вершин.

Хоча я бачу логіку, що має єдиний спосіб візуалізації всього, чи це так, що VBO не мають серйозних недоліків над масивами вершин? Я думав, що VBO повинні бути великими буферами, що містять> 1 Мб даних, як правило. Що робити, якщо у мене є сцена, яка має багато меншої геометрії? У мене є графік сцени з великою кількістю вузлів, кожен з яких потребує власного перетворення тощо. Кожен вузол також повинен бути в змозі видалити окремо, додати його окремо тощо. Я раніше використовував вершинні масиви. Отже, моє перше питання полягає в тому, що, якщо я перейду до VBO, буде більше великих накладних витрат на об'єкти моєї графіки сцени, оскільки VBO потрібно виділити для кожного об'єкта.

Інша стурбованість полягає в тому, що геометрія, яку я надаю, може бути дуже динамічною. У гіршому випадку, можуть бути випадки, коли всю геометрію потрібно буде відрегулювати кожен кадр протягом певного періоду часу. Чи будуть у цьому випадку використання VBO гірші за продуктивність, ніж вершинні масиви, або ж VBO в гіршому випадку виконувати так само роботу, як і вершинні масиви, але не більше?

Отже, у більш стислому форматі мої запитання:

1) Чи є суттєві накладні витрати на розподіл / розміщення VBO (я маю на увазі простий акт налаштування буфера)?

2) Якщо я оновлюю дані з центрального процесора кожен кадр, чи може це бути значно гірше, ніж якби я використовував вершинні масиви?

І нарешті, я хотів би знати:

3) Якщо відповідь на будь-яке з вищезазначених питань "так", навіщо зневажити інші способи візуалізації, які можуть мати переваги перед VBO? Щось тут мені не вистачає, як методи, які я повинен використовувати для зменшення деяких з цих потенційних витрат на розподіл тощо?

4) Чи суттєво змінюються відповіді на будь-яке з цих питань залежно від того, яку версію OpenGL я використовую? Якщо я перефактуюю свій код на OpenGL 3 або 4, сумісний вперед, використовуючи VBO в спосіб, який є ефективним, чи будуть ті самі методи, які будуть ефективнішими з OpenGL 2, чи, ймовірно, що деякі методи набагато швидше з OpenGL 3 + та інші з OpenGL 2?

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


1
Чому голосування закрити? Це дубль? Якщо так, чи можу я побачити посилання, щоб я міг отримати користь від нього?
Гравітація

Відповіді:


23

Чи є суттєві накладні витрати на розподіл / розміщення VBO (я маю на увазі простий акт налаштування буфера)?

Визначте "істотний". Як правило, розумно не створювати їх посеред кадрів; їх слід встановлювати під час ініціалізації чи де завгодно. Але це стосується більшості об'єктів OpenGL, таких як текстури, рендербуфери або шейдери.

Якщо я оновлюю дані з центрального процесора в кожному кадрі, чи може це бути значно гірше, ніж якби я використовував вершинні масиви?

Чи може це? Так. OpenGL визначає функціональність, а не продуктивність . Ви дійсно можете зробити все набагато повільніше. Або ви можете зробити все швидше. Все залежить від того, як ви ним користуєтесь.

У OpenGL Wiki є хороша стаття про те, як правильно передавати дані .

Якщо відповідь на будь-яке з перерахованих вище питань "так", навіщо зневажити інші способи візуалізації, які можуть мати переваги перед VBO? Щось тут мені не вистачає, як методи, які я повинен використовувати для зменшення деяких з цих потенційних витрат на розподіл тощо?

По-перше, вони були не просто застарілими. Депресія означає позначення чогось "видалити" в наступних версіях. Вони застаріли в 3,0 та вилучені в ядрі 3,1 та вище.

По-друге, ARB загалом пояснила причину видалення матеріалів з OpenGL. Це робить специфікацію меншою та простішою. Це робить API меншим і спрощеним. Це полегшує розуміння, які API ви повинні використовувати; 2.1 було чотири способи надання вершинних даних; 3.1+ має 1. Це позбавляється від багато суворого. І т.д.

Чи суттєво змінюються відповіді на будь-яке з цих питань залежно від того, яку версію OpenGL я використовую? Якщо я перефактуюю свій код на OpenGL 3 або 4, сумісний вперед, використовуючи VBO в спосіб, який є ефективним, чи будуть ті ж методи, які будуть ефективнішими з OpenGL 2, або, ймовірно, що деякі методи набагато швидше з OpenGL 3 + та інші з OpenGL 2?

Більш-менш ні. Тільки на MacOSX очевидно різниця між версіями 3.1 + core та pre-3.0. Профіль сумісності реалізований усіма драйверами для Linux та Windows, тому ви можете припустити, що основний профіль цих драйверів насправді лише додає чеки, щоб запобігти виклику функцій сумісності.

В Mac OSX 10.7 доступний ядро ​​GL 3.2, але не профіль сумісності. Це не обов'язково означає що-небудь для методів виконання одних проти інших. Але це означає, що якщо є відмінності, це платформа, на якій ви їх побачите.


1
Оскільки ви просто перекреслили це запитання , я просто перекладу свою відповідь.
Ніколь Болас

Ще одна перевага збереження стислості API полягає в тому, що це робить API OpenGL простішим у застосуванні. Це було великою увагою в оригінальній специфікації OpenGL ES.
notlesh

@stephelton: Має сенс. Моє питання "чому зневажити все, окрім VBO", грунтувалося на думці, що, хоч і має ідеальний сенс тримати API нежиттю, не має сенсу знецінювати функції, які можуть бути кращими за VBO для багатьох випадків використання. Як я чую, здається, що використання VBO не має недоліків, тому тоді є цілком сенс знецінити все інше.
Гравітація

@gravity Не потрібно використовувати VBO. Ви також можете використовувати масив вершин.
Нотлеш

18

Те, як працює OpenGL, коли ви використовуєте дані, що не належать до VBO, драйверу доводиться робити його копію - на практиці створюючи тимчасовий VBO - оскільки нічого не спонукає вас змінювати голі масиви вашого простору користувача між викликами на OpenGL.

Можливо, є хитрість на стороні драйвера, щоб швидше розподілити темп, але ви нічого не можете зробити, щоб уникнути копіювання.

Так що, поки ви - і розробники драйверів - все робите правильно, VBO повинні завжди (tm) завжди просто прискорювати роботу.


6
Мені подобається ця відповідь краще. Це коротше і більше до суті, imo.
TravisG

@JariKomppa: Це звучить як дуже розумне пояснення. У мене все ще є одна стурбованість: VBO мають бути досить великими об'єктами, які часто виділяються як буфери 1 Мб - 4 Мб востаннє, коли я перевіряв. Що робити, якщо мої об’єкти геометрії не такі великі, але я все одно переймаюся продуктивністю, тому що в мене дуже багато об'єктів? Я переживаю, що VBO можуть бути просто іншими випадками використання, ніж у мене. Чи слід об'єднувати кілька об'єктів разом в одному VBO, а потім використовувати glDrawRangeElementsдля малювання кожного окремого об'єкта, або це неефективно, як вершинні масиви?
Гравітація

Я сумніваюся, що це матиме значення, але якщо ви відчуваєте, що це турбує, орієнтуйтеся на це.
Jari Komppa

@JariKomppa: Що ви сумніваєтеся, чи змінить це? Використання glDrawRangeElementsдекількох разів на кожному VBO з кількома VBO, а не надання кожному об'єкту власного VBO?
Гравітація

1
Саме так. Я сумніваюся, що ви побачите велику різницю там, але профілювання деяких тестових випадків повинно дати вам більше інформації. Я також не переймаюся цим питанням, оскільки такі зміни можна буде застосувати пізніше, якщо це буде потрібно.
Jari Komppa

9

а вершинні масиви здаються застарілими. Натомість, якщо я правильно розумію,

Не зовсім. Вершинні масиви є основою для об'єктів вершинних буферів. З клієнта на сторону сервера переміщено лише сховище.

Що робити, якщо у мене є сцена, яка має багато меншої геометрії?

Об'єднайте менші набори геометрії в більші VBO. Немає необхідності мати одне VBO на партію геометрії. Ви можете ідеально адресувати підмножини VBO для візуалізації. Використовуйте незеро зміщення для параметра gl… Покажчик даних.

2) Якщо я оновлюю дані з центрального процесора кожен кадр, чи може це бути значно гірше, ніж якби я використовував вершинні масиви?

Для цього існують прапори використання буфера GL_DYNAMIC_DRAW та GL_STREAM_DRAW.

Якщо відповідь на будь-яке з вищезазначених питань "так", навіщо зневажити інші способи візуалізації, які можуть мати переваги перед VBO?

Тому що переваг немає. Дані геометрії повинні бути передані в GPU у будь-якому випадку. Використання звичайного вершинного масиву на стороні клієнта все одно спричинить передачу DMA в GPU, і негайний режим створить пакет для передачі також спочатку.

Немає абсолютно ніякої користі від використання VBO.


Отже, моя ефективність, як правило, не повинна бути гіршою з VBO, ніж з вершинними масивами, але тільки якщо я правильно встановив режим GL_STREAM_DRAW?
Гравітація

@ Гравітація: Дійсно. Однак режим буфера - це лише натяк на очікуване використання, але, звичайно, цей натяк повинен відповідати тому, що ви збираєтеся робити. Також не забувайте, що ви можете відображати буфери в адресному просторі процесу для оновлень (glMapBuffer, glUnmapBuffer).
datenwolf

але тоді буфер не міг бути в VRAM, правда? Або все-таки це буде в VRAM, але тільки адресовано через адреси простору процесу? Чи буде випадковий доступ дешевим за допомогою цієї методики, або я все ж намагаюся оновити лише невелику кількість суміжних діапазонів?
Гравітація

@ Гравітація: буфер може бути відображений лише для читання, запису чи читання. Для оновлень слід вибрати лише запис. Тепер важливо знати, як сучасні ОС управляють віртуальним адресним простором, а саме за допомогою підкаченої пам'яті. У випадку з картою лише для запису ви зіставили фрагмент пам'яті передачі DMA, і ваше записування до цього відображеного діапазону перейде в пам'ять GPU більш-менш безпосередньо (вміст спочатку записується в оперативну пам'ять процесора, але потім передається в GPU DMA передача). Важливо, що це більш прямий шлях, ніж якщо дані проходять через вершинний масив клієнтської сторони: Регулярна оперативна пам'ять не підходить для DMA
datenwolf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.