openGL и STL?

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

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

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

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

спасибо

4 ответов


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

&vertices[0]

здесь vertices ваш вектор.


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());

vector<int> array;
.....
functionThatAcceptsArray(&array[0]); // yes, this is standard

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