VBOs с std:: вектор

я написал загрузчик моделей на C++ OpenGL. Я использовал std::vectors для хранения данных вершин, но теперь я хочу передать их типы данных сильно отличаются. Я хочу знать, есть ли способ конвертировать между std::vector документально подтвержденным const GLvoid * на glBufferData().

вершина типа

typedef struct
{
    float x, y, z;
    float nx, ny, nz;
    float u, v;
}
Vertex;

vector<Vertex> vertices;

glBufferData() вызов

glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float), vertices, GL_STATIC_DRAW);

я получаю следующую (ожидаемую) ошибку:

error: cannot convert ‘std::vector<Vertex>’ to ‘const GLvoid*’ in argument passing

как преобразовать вектор в тип совместим с glBufferData()?

NB. Меня не волнует правильное распределение памяти на данный момент;vertices.size() * 3 * sizeof(float), скорее всего, будет segfault, но я хочу сначала решить ошибку типа.

2 ответов


если у вас std::vector<T> v, вы можете получить T* указывая на начало непрерывных данных (что является то, что OpenGL после) с выражением &v[0].


в вашем случае, это означает, передав Vertex* to glBufferData:

glBufferData(
   GL_ARRAY_BUFFER,
   vertices.size() * sizeof(Vertex),
   &vertices[0],
   GL_STATIC_DRAW
);

или как это, что то же самое:

glBufferData(
   GL_ARRAY_BUFFER,
   vertices.size() * sizeof(Vertex),
   &vertices.front(),
   GL_STATIC_DRAW
);

вы можете положиться на неявное преобразование из Vertex* to void const* здесь; это не должно представлять проблемы.


это должно сделать трюк:

&vertices[0]

некоторые предпочитают &vertices.front(), но это больше печатать, и я ленивый.

чтобы быть еще ленивее, вы можете перегрузить glBufferData таким образом:

template <class T>
inline void glBufferData(GLenum target, const vector<T>& v, GLenum usage) {
    glBufferData(target, v.size() * sizeof(T), &v[0], usage);
}

тогда вы можете написать:

glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);

а также избегать ошибок (ваша структура больше, чем 3 * sizeof(float)).