带有std :: vector的VBO

Boj*_*les 36 c++ opengl vector vbo

我用C++和OpenGL编写了一个模型加载器.我用std::vectors来存储我的顶点数据,但现在我想把它传递给它glBufferData(),但是数据类型却截然不同.我想知道如果有之间进行转换的方式std::vector所记录const GLvoid *glBufferData().

顶点类型

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

vector<Vertex> vertices;
Run Code Online (Sandbox Code Playgroud)

glBufferData()调用

glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

我得到以下(预期)错误:

error: cannot convert ‘std::vector<Vertex>’ to ‘const GLvoid*’ in argument passing
Run Code Online (Sandbox Code Playgroud)

如何将矢量转换为兼容的类型glBufferData()

NB.我不关心目前正确的内存分配; vertices.size() * 3 * sizeof(float)很可能是段错误,但我想先解决类型错误.

Lig*_*ica 46

如果你有一个std::vector<T> v,你可以通过T*表达式获得指向连续数据的开头(这是OpenGL之后的内容)&v[0].


在您的情况下,这意味着传递Vertex*glBufferData:

glBufferData(
   GL_ARRAY_BUFFER,
   vertices.size() * sizeof(Vertex),
   &vertices[0],
   GL_STATIC_DRAW
);
Run Code Online (Sandbox Code Playgroud)

或者像这样,这是相同的:

glBufferData(
   GL_ARRAY_BUFFER,
   vertices.size() * sizeof(Vertex),
   &vertices.front(),
   GL_STATIC_DRAW
);
Run Code Online (Sandbox Code Playgroud)

你可以依赖隐式转换Vertex*void const*这里; 这应该不会造成问题.

  • 这将适用于向量,因为向量数据存储是引擎盖下的C数组.这对于没有连续存储数据的许多其他STL容器(如列表集和映射)不起作用 (3认同)
  • @doron:是否使用数组实现`vector`存储是完全未指定的.重要的是保证元素_contiguously_存储.这几乎是一回事,但那里的含义有微妙的差别.(仅供参考,_no_其他标准容器保证连续元素存储,除了`std :: array` of coure) (2认同)

Mar*_*tos 26

这应该做的伎俩:

&vertices[0]
Run Code Online (Sandbox Code Playgroud)

有些人更喜欢&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);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以写:

glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

并且还要避免错误(你的结构大于3 * sizeof(float)).

  • 谢谢马塞洛.`&vertices.front()`是完美的.我不知道你没有将所有数据传递给函数,只是指向第一个元素的指针.全部固定. (2认同)