OpenGL — индексированные чертежи с glDrawElements

У меня есть пара вопросов о том, как OpenGL обрабатывает эти операции рисования.

  1. Допустим, я передаю OpenGL указатель на мой массив вершин. Тогда я могу вызвать glDrawElements с массивом индексов. Это будет рисовать запрошенные фигуры, используя эти индексы в массиве вершин правильно?

  2. После этого вызова glDrawElements я мог тогда сделать другой вызов glDawElements с другим набором индексов? Будет ли тогда нарисовать новый индексный массив с использованием исходного массива вершин?

  3. Сохраняет ли OpenGL мои данные вершин для следующего кадра, когда я повторяю все эти вызовы? Таким образом, следующий вызов указателя вершины будет намного быстрее?

  4. Предполагая, что ответ на последние три вопроса — да, что, если я хочу сделать это для нескольких массивов вершин в каждом кадре? Я предполагаю, что выполнение этого с более чем одним массивом вершин приведет к тому, что OpenGL удалит последний использованный массив из графической памяти и начнет использовать новый. Но в моем случае массивы вершин никогда не изменятся. Итак, я хочу знать, поддерживает ли opengl мои вершинные массивы в случае, когда в следующий раз, когда я отправлю ему данные вершин, это будут те же данные? Если нет, то есть ли способ оптимизировать это, чтобы позволить что-то подобное? По сути, я хочу рисовать процедурно между вершинами, используя индикаторы, не обновляя данные вершин, чтобы уменьшить накладные расходы и ускорить сложный рендеринг, который требует постоянных процедурно изменяющихся фигур, которые всегда будут использовать вершины из исходного массива вершин. Это возможно или я просто фантазирую?

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

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

0

Решение

1. Допустим, я передаю OpenGL указатель на мой массив вершин. Тогда я могу вызвать glDrawElements с массивом индексов. Это нарисует
запрошенные фигуры, использующие эти индексы в массиве вершин, верны?

Да.

2.После того вызова glDrawElements я могу затем сделать еще один glDawElements
звонить с другим набором индексов? Будет ли тогда нарисовать новый индекс
массив с использованием исходного массива вершин?

Да.

3. Сохраняет ли OpenGL мои данные вершин для следующего кадра, когда я повторяю
все эти звонки? Так что следующий вызов указателя вершины будет много
быстрее?

Ответить на это немного сложнее, чем вы могли бы. То, как вы задаете эти вопросы, заставляет меня предположить, что вы используете клиентские вершинные массивы, то есть, у вас есть массивы в системной памяти, и ваши указатели vertes указывают прямо на них. В этом случае ответ no, GL не может «кэшировать» эти данные любым полезным способом. После того, как вызов отрисовки завершен, он должен предположить, что вы можете изменить данные, и ему придется сравнивать каждый бит, чтобы убедиться, что вы ничего не изменили.

Однако клиентские виртуальные машины — не единственный способ иметь виртуальные машины в GL — на самом деле они полностью устарели, устарели с момента появления GL3.0 и были удален из современных версий OpenGL. Современный способ сделать это использует Объекты буфера вершин, которые в основном являются буферами, которые управляемый GL, но манипулируется пользователем. Буферные объекты — это просто кусок памяти, но вам понадобятся специальные вызовы GL для их создания, чтения или записи или изменения данных и так далее. И буферный объект вполне может храниться не в системной памяти, а непосредственно в VRAM, что очень полезно для статических данных, которые используются снова и снова. Посмотри на спецификация расширения GL_ARB_vertex_buffer_object, который первоначально ввел эту функцию в 2003 году и стал ядром в GL 1.5.

4. Если я отвечу на три последних вопроса, да, что если я захочу
сделать это на нескольких массивах вершин в каждом кадре? Я предполагаю делать
это больше, чем на одном массиве вершин, заставит OpenGL отбросить
последний использованный массив из графической памяти и начать использовать новый. Но
в моем случае массивы вершин никогда не изменятся. Так чего я хочу
знать, действительно ли opengl хранит мои вершинные массивы в следующем случае
Я отправляю ему данные вершины, это будут те же данные? Если нет, есть ли способ
Я могу оптимизировать это, чтобы позволить что-то подобное? В основном я хочу
рисовать процедурно между вершинами, используя индикаторы без обновления
данные вершин, чтобы уменьшить накладные расходы и ускорить сложный
рендеринг, который требует постоянного процедурного изменения форм, которые
всегда будет использовать вершины из исходного массива вершин. Это
возможно или я просто фантазирую?

ОБВ именно то, что вы ищете, здесь.

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

Вы также можете обновить только части VBO. Однако, это может стать неэффективным, если у вас есть много мелких частей, которые случайно распределены в вашем буфере, будет более эффективно обновлять непрерывные (суб) области. Но это отдельная тема.

2

Другие решения

  1. да
  2. да
  3. Нет. Как только вы создадите объект Vertex Buffer (VBO), он останется в памяти GPU. В противном случае векторные данные должны быть перенесены повторно (старый способ избежать этого — списки отображения). В обоих случаях производительность последующих кадров должна оставаться одинаковой (но намного лучше при использовании метода VBO): вы можете создавать и загружать VBO перед рендерингом первого кадра.
  4. VBO был введен, чтобы предоставить вам именно эту функциональность. Просто создайте несколько VBO. Однако все становится не так, когда вам нужно больше памяти, чем доступно.
  5. VBO все еще ответ, и посмотрим Изменение только определенного типа элемента данных буфера VBO?
1

Похоже, вы должны попробовать что-то под названием Vertex Buffer Objects. Он предлагает те же преимущества, что и массивы вершин, но вы можете создать несколько буферов вершин и хранить их в «именованных слотах». Этот метод имеет гораздо лучшую производительность, поскольку данные хранятся непосредственно в памяти графической карты.

Вот хороший учебник по C ++ для начала.

0
По вопросам рекламы [email protected]