Вопросы о glDrawRangeElements()

Я пытаюсь отобразить данные старого уровня с помощью команды glDrawRangeElements(). Мои вершины настроены правильно, мои индексы настроены правильно, но я не могу заставить их отобразиться. Наконец я проверил в Интернете и наткнулся на пример, найденный здесь: http://www.songho.ca/opengl/gl_vertexarray.html

Из примера я думаю, что я делал это неправильно. Очевидно, что начало является значением индекса, а окончание — значением индекса, а не индексом в массиве индексов. Я предположил, что, например, если вы хотите отобразить 10 треугольников, начало будет равно 0, а окончание — 29, а количество — 30. Но я, видимо, ошибаюсь?

Это было бы правильно только в том случае, если бы значение индекса в 0 и 29 было фактически 0 и 29. Таким образом, если бы индексы начинались с 400 и заканчивались на 452, вместо этого вызов того же массива был бы

glDrawRangeElements(GL_TRIANGLES, 400, 452, 29, GL_UNSIGNED_BYTE, indices);

Это правильно? Кто-нибудь еще думает, что это немного нелогично? Любые другие советы о массивах вершин?


person Satchmo Brown    schedule 26.09.2011    source источник


Ответы (1)


Во-первых, давайте поговорим о glDrawElements, потому что версия Range — это просто его модификация. count — это количество индексов, которые нужно извлечь из исходного массива индексов для рендеринга. Каждый извлеченный индекс соответствует вершине. Итак, если ваш count равен «29», то вы пытаетесь отобразить 29 вершин. Это будет отображать только 27 вершин, если вы используете GL_TRIANGLES, поскольку для каждого треугольника требуется три вершины. OpenGL отбросит лишнее.

Поэтому, если вы хотите отобразить 30 индексов, вы вводите 30 в качестве счетчика.

Теперь, когда мы знаем, как использовать glDrawElements, давайте поговорим об glDrawRangeElements. При обычном использовании glDrawElements вы указываете место в массиве исходных индексов, из которого нужно извлечь данные. Параметры indices и count сообщают OpenGL, где искать индексы. Но фактические индексы, извлеченные из этого массива, могут быть где угодно в пределах границ индексов исходного массива вершин.

glDrawRangeElements позволяет указать OpenGL диапазон (включая, потому что это имеет смысл) значений индекса вершины. Вы говорите, что индексы, которые он получает во время этого вызова отрисовки, не превысят этот диапазон. Это может позволить драйверу выполнить полезную оптимизацию. Значение start должно быть наименьшим значением индекса, которое будет получено из массива индексов, а end должно быть самым высоким. Он не должен не быть просто индексом первой и последней вершин.

person Nicol Bolas    schedule 26.09.2011
comment
Вы должны преподавать класс, поскольку вы делаете большую работу по объяснению. Я собираюсь исправить некоторые ошибки в своем коде и попробовать еще раз. - person Satchmo Brown; 26.09.2011
comment
Еще один вопрос для уточнения. Представьте, что у меня есть индексы {2, 11, 6, 4, 0, 3} для двух треугольников, которые я хотел отобразить, и просто для примера я хотел отобразить их двумя партиями. Первый треугольник будет (при условии, что тип индекса byte): glDrawRangeElements(GL_TRIANGLES, 2, 11, 3, GL_UNSIGNED_BYTE, индексы); а вторым будет glDrawRangeElements(GL_TRIANGLES, 0, 4, 3, GL_UNSIGNED_BYTE, индексы + 3); -- Это правильно? Если это так, мне нужно знать самый высокий и самый низкий индекс в каждом пакете рендеринга. - person Satchmo Brown; 26.09.2011
comment
@ Николь Болас Большое спасибо - person Satchmo Brown; 26.09.2011
comment
Неправда, что glDrawElements поднимет INVALID_OP на 29. Он рисует с 27 и отбрасывает последние 2. - person Bahbar; 26.09.2011
comment
Прочитав спецификацию, ваше утверждение о том, что диапазон от start до end является полуоткрытым, кажется неверным. Спецификация говорит, что все вершины, на которые ссылаются индексы, должны лежать между start и end включительно. Поэтому значение end должно быть установлено равным самому высокому значению индекса, на который ссылаются, а не самому высокому значению индекса, на который указывает ссылка + 1. - person Richard Viney; 27.07.2013
comment
Эти два эквивалентны: glDrawElements(mode, end-start, type, data + start) и glDrawRangeElements(mode, start, end, end-start, type, data)? - person Bim; 20.10.2014
comment
@Bim - Судя по предоставленному ответу и документам, они равносильны тому, что оба неверны. Если у вас есть буфер индексов с 3 элементами, и значения индексов, содержащиеся в буфере индексов, равны 200, 201 и 202, правильный вызов будет выглядеть так: glDrawElements(mode, 200, 202, 3, type, data); Он также может выглядеть так: glDrawElements(mode, 100, 500, 3, type, data);, но он не может выглядеть так: например: glDrawElements(mode, 0, 2, 3, type, data); или glDrawElements(mode, 0, 3, 3, type, data);, потому что фактические значения не находятся между 0 и 2 (или 3). - person Marc; 23.10.2014
comment
Я понял, что Range в имени glDrawRangeElements имеет то же значение, что и в Range Query — то есть найти подмножество значений, попадающих в диапазон, а не подмножество индексов которые попадают в диапазон! - person nitroglycerine; 04.10.2017
comment
можно ли glDrawRangeElements(mode, start, end, count, type, data) заменить на glDrawElements(mode, count, type, data) и получить тот же результат рендеринга? - person DeanSinaean; 31.07.2020