Найшвидший спосіб намалювати квадратики в OpenGL ES?


22

Я використовую OpenGL ES 2.0 У мене є купа квадратиків, які потрібно намалювати, я хотів би мати можливість проходити лише 4 вершини на квадратик, як якщо б я використовував GL_QUADS, але в основному я просто хочу знати найкращий спосіб намалювати креслення купу окремих квадроциклів.

Поки що я міг зробити: -GL_TRIANGLES (6 вершин на квадратик) -Зробити GL_TRIANGLE_STRIP (6 вершин на квадратик)

Можливості, які я знайшов: -GL_TRIANGLE_STRIPS зі спеціальним значенням індексу, яке скидає квадратичну смужку (це означало б 5 індексів на квадратик, але я не думаю, що це можливо - OpenGL ES 2.0)

Відповіді:


33

Просто використовуйте буфер індексів та GL_TRIANGLES. У цьому випадку вам потрібно 4 вершини + 6 індексів на квадратик (6 додаткових індексів можуть здатися великими накладними, але насправді це не так - як тільки ви сконструювали свій індексний буфер, вам більше не доведеться його торкатися). Дивіться цю сторінку для отримання додаткової інформації (пошук glDrawElements)

Простий код прикладу:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Крім того, якщо ви малюєте лише один квадроцикл, вам потрібно лише 4 вершини, щоб намалювати його трикутними смужками ( як показано у вікіпедії ), але я думаю, ви це вже знали.


Традиційним трюком для об’єднання декількох смуг трикутника в одну смужку є "вироджене трикутники": Повторення останнього елемента однієї смужки та першого елемента наступної смуги створює 2 трикутники з нульовою площею, які таким чином нічого не малюють. Розглянемо другі квадратичні індекси (4, 5, 6, 7). Буфер індексів для GL_TRIANGLE_STRIP двох квадратиків може бути: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Вироджені трикутники - це 3,3,4і 3,4,4. Чи варто це робити? Ні, якщо тільки ваші квадроцикли не мають пар (або більше) із загальними краями. Якщо 2-й квадратик дорівнює {3, 2, 4, 5}, то смужка є {0,1,3,2,5,4}.
ToolmakerSteve

8
І щоб зробити це зрозумілим для всіх, хто приходить разом і йому потрібно намалювати купу квадроциклів: Для продуктивності НЕ копіюйте вищевказаний код, а зробіть дзвінок glDrawElements ОДНІ ДЛЯ КОЖНОГО КВАДУ . Натомість створити ОДИН вершину масив та ОДИН масив індексів, який включає ВСІ квадратики, які потрібно намалювати. Використовуючи GL_TRIANGLES, два квадратики можуть мати показники {0,1,2, 0,2,3, 4,5,6, 4,6,7}або однаково добре {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Хороший клас , щоб допомогти це glText-Android / SpriteBatch
ToolmakerSteve

6

Використання буферів індексів не обов'язково швидше, як зазначено в документах Apple, "Для найкращої продуктивності ваші моделі повинні бути представлені у вигляді однієї невкладеної трикутної смужки за допомогою glDrawArrays" .

Отже, хоча а GL_TRIANGLE_STRIPбуде робити це у 4 вершинах, не потребуючи буфера індексів, і ви можете використовувати індексний буфер, це досить кульгаво, щоб спробувати "зберегти" повторення 2 вершин . З цієї причини я б запропонував намалювати 2 окремо GL_TRIANGLESі повторити 2 вершини по діагоналі .


8
Гм, ні. Що говорить цей документ, це те, що ваші моделі подаються у вигляді однієї трикутної стрічки INDEXED. І вже наступне речення: "Щоб уникнути вказівки даних для однієї вершини кілька разів у вершинному буфері, використовуйте окремий індексний буфер та намалюйте трикутникову смужку за допомогою функції glDrawElements". Це саме те, що ви вирішили "кульгавим".
davidf2281

3
Зважаючи на те, що параметр doc тепер стосується glDrawElements, а не glDrawArrays, він, ймовірно, був переписаний з цієї відповіді. Тим не менш, доктор робив те, що для продуктивності постачання однієї смуги (а не декількох смужок, отже, безліч дзвінків на gl). В цій ситуації я вважаю, що різниця між використанням індексів чи ні є незначною ; Що важливо - це об'єднати все в один вершиновий масив (плюс необов'язковий масив індексів), щоб ви могли зробити один дзвінок gl.
ToolmakerSteve

0

Великий виграш на робочому столі - це переміщення даних у GL_STATIC_DRAW VBO. Імовірно, це стосується і MBX GPU iPhone iPhone.


-2

Використання GL_TRIANGLE_FANдля четвернога використовує 4 вершини, а не 6.


Так, але так GL_TRIANGLE_STRIP, як уже вказували інші відповіді.
Анко

@Містер. Blah - Ви пропустили пункт питання, який полягає в тому, як ефективно зробити купу квадроциклів. Не слід робити дзвінок gl для кожного квадратика, а скоріше поєднувати багато квадратиків в одному масиві, який можна намалювати одним викликом gl. GL_TRIANGLE_FAN не допоможе в цьому, тому рідко корисний при високоефективній візуалізації.
ToolmakerSteve
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.