VBOs с std:: вектор
я написал загрузчик моделей на C++ OpenGL. Я использовал std::vector
s для хранения данных вершин, но теперь я хочу передать их типы данных сильно отличаются. Я хочу знать, есть ли способ конвертировать между 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)
).