openGL и STL? - PullRequest
       44

openGL и STL?

6 голосов
/ 20 сентября 2009

Я использую openGL и в настоящее время передаю ему массив вершин. Проблема в том, что мне нужно создать много вершин и добавить их между собой (по порядку). Это означает, что использование обычного массива довольно раздражает / неэффективно.

Я хочу использовать структуру данных из STL, чтобы я мог эффективно (и легко) помещать новые вершины в любой индекс. Проблема в том, что openGL ожидает регулярный массив.

Кто-нибудь знает, как это сделать? Есть ли простой способ преобразовать вектор STL в массив?

Я использую openGL 1.1

Спасибо

Ответы [ 4 ]

15 голосов
/ 20 сентября 2009

Вы можете использовать указатель на первый адрес вектора в качестве указателя массива. Векторы STL гарантированно сохраняют свои элементы в непрерывной памяти. Так что вы можете просто сделать что-то вроде:

&vertices[0]

где vertices - ваш вектор.

3 голосов
/ 20 сентября 2009

OpenGL требует непрерывного массива элементов. По понятным и понятным причинам, эффективный способ вставить один элемент в непрерывный массив отсутствует. Это обязательно не менее O (N).

Однако вы потенциально можете добавить N элементов меньше, чем O (N ^ 2), которое вектор достигает для N случайных вставок.

Например, если вы на самом деле не добавляете новые вершины «по любому индексу», но всегда близки к предыдущему, вы можете добавить все элементы в std :: list (O (1) для каждого элемента, O (N) всего), затем скопируйте список std :: list в вектор std :: vector. На самом деле это не обязательно должен быть предыдущий элемент , просто a предыдущий элемент, поэтому, если порядок основан на рекурсивном обходе некоторого дерева, вы все равно сможете сделай это.

Если новые вершины добавляются по индексу, определяемому линейным порядком, добавьте все элементы в std :: map или std :: multi_map (O (log N) на элемент, всего O (N log N)) , затем скопируйте это в вектор.

Таким образом, самый простой способ сделать это зависит от того, как определяется порядок. Являются ли эти решения с более низкой сложностью на самом деле быстрее , чем вектор, зависит от N. У них гораздо более высокие издержки (O (N) распределения вместо O (log N) для вектора), поэтому N, возможно, придется быть довольно большим, прежде чем начнется асимптотическое поведение.

Если вы используете любое из описанных мной решений, простой / эффективный способ скопировать список или карту в вектор выглядит так:

std::vector<glVertex3f> vec;
vec.reserve(listormap.size());
vec.insert(vec.begin(), listormap.begin(), listormap.end());
1 голос
/ 23 сентября 2009

Это зависит от того, насколько вам нужен контроль над вашими промежуточными представлениями данных и насколько вы можете рассчитать.
Чтобы найти компромисс между свободой и использованием памяти, прочитайте о структуре данных Winged Edge. Структура обеспечивает быстрый доступ и обход между вершинами, ребрами и гранями и работает как двойной связанный список. Если вы реализуете концепцию и создаете для нее реализацию итератора, вы можете использовать std :: copy для копирования данных в любой контейнер STL.
Как уже упоминали остальные, используйте std :: vector в качестве окончательного представления, когда OpenGL нужны данные. И наконец:
Не бойтесь иметь несколько экземпляров одних и тех же данных!

1 голос
/ 20 сентября 2009
vector<int> array;
.....
functionThatAcceptsArray(&array[0]); // yes, this is standard
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...