带有std :: vector的VBO

时间:2011-08-24 09:55:03

标签: c++ opengl vector vbo

我用C ++和OpenGL编写了一个模型加载器。我已经使用std::vector来存储我的顶点数据,但现在我想将它传递给glBufferData(),但数据类型却截然不同。我想知道是否有办法将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)很可能是段错误,但我想先解决类型错误。

2 个答案:

答案 0 :(得分:45)

如果你有一个std::vector<T> v,你可能会得到一个T*指向连续数据的开头(这是OpenGL所追求的),表达式为&v[0]


在您的情况下,这意味着将Vertex*传递给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*void const*的隐式转换;这不应该造成问题。

答案 1 :(得分:26)

这应该可以解决问题:

&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))。