указатель на `std :: list` из собственных данных

Я использую двумерный вектор Eigen3 в качестве 2D-точки для рисования OpenGL, сохраняя их в виде списка:

typedef Eigen::Vector2d Vec2D;
std::list<Vec2D> points;

Теперь мне нужен массив GLfloat для передачи всей структуры данных необработанного значения с плавающей точкой на графическую карту:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

_vertex = new GLfloat[points.size()*2];
_colors = new GLfloat[points.size()*4];

std::list<Vec2D>::const_iterator it;
int i=0, j=0;
for(it=points.begin(); it!=points.end(); ++it) {
_vertex[i] = it->x()+2;
_vertex[i+1] = it->y()+2;
i+=2;

_colors[j] = getRed(j/4.0f, it);
_colors[j+1] = getGreen(j/4.0f, it);
_colors[j+2] = getBlue(j/4.0f, it);
_colors[j+3] = getAlpha(j/4.0f, it);
j+=4;
}

glColorPointer(4, GL_FLOAT, 0, _colors);
glVertexPointer(2, GL_FLOAT, 0, _vertex);
glDrawArrays(GL_LINE_STRIP, 0, points.size());

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

delete _vertex;
delete _colors;

Есть ли более эффективный способ создания массивов для передачи на графические карты? как пройти points.begin() и выяснить, что такое смещение и избежать перебрать все точки?

Я имею в виду .. в памяти координаты х и у Eigen::Vector2d должен храниться в некотором последовательном пространстве … так что … я думаю, что могу передать его непосредственно на графическую карту … но я не могу понять, как.

2

Решение

std :: list не хранит свои данные в непрерывной памяти, для этого вам нужен std :: vector (или std :: array, если вы знаете размер во время компиляции, но, вероятно, нет). В Vector есть метод data (), который возвращает указатель на базовые данные. Однако, если вы храните Eigen :: vec2d внутри, вы не можете передать его openGl, так как это динамическая структура, и ваши данные будут по всей вашей памяти. Вам нужна структура, которая хранит данные на месте (а btw более читабелен, чем vec2d, что довольно странно в этом контексте). Например:

struct VertexData
{
GLfloat x;
GLfloat y;
GLfloat red;
GLfloat green;
GLfloat blue;
GLfloat alpha;
}

А затем используйте glVertexPointer, чтобы передать его openGL, используя sizeof (VertexData) в качестве шага

Для удаления новых массивов вам нужно использовать

delete [] _vertex;

нормальное удаление освободит только первый элемент. Или даже лучше, вы можете использовать умные указатели, std :: unique_ptr будет лучше в этом случае

std::unique_ptr<GLfloat[]> _vertex(new GLfloat[points.size() * sizeof(GLfloat)]);

Он автоматически освободит память, когда выйдет из области видимости (в конце блока)

4

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

points это std::list поэтому он не содержит непрерывный массив данных.

Если вы используете std::vector однако вместо этого в C ++ 11 вы можете получить доступ к массиву, используемому внутри points.data(), Это означает, что вам не нужно _vertex больше.

Знайте, что, в качестве альтернативы, вы можете даже пойти дальше и иметь класс (названный, например, Vertex), который содержит положение вершины и ее цвет, а затем использовать data() метод на вашем std::vector<Vertex> в комбинации с glInterleavedArraysstride=sizeof(Vertex)).

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector