假设传递给 OpenGL 的结构数组的内存布局可能会出错

Potential error by assuming memory layout of struct array passed to OpenGL

我正在看一个OpenGL教程,其中,将网格数据传递给显卡所做的基本上如下:

#include <GL/glew.h>
#include <glm/glm.hpp>

struct Vertex {
    ...
private:
    glm::vec3 pos;
    glm::vec2 texCoord;
    glm::vec3 normal;
};

Mesh::Mesh(Vertex * vertices, unsigned int numVertices) {
    ...
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);
    ...
}

但是,我觉得这可能会导致问题,因为假设顶点将被完美布局。还是保证顶点字段的放置没有填充并按该顺序放置?另外,我不知道 glm::vec* 类型的布局或大小是什么。

我怀疑这可能会导致问题吗?

应该怎么做?

什么会影响结构的布局?

如果您指定了正确的属性指针,这种方法没有任何问题,例如:

glVertexAttribPointer( ..., 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, pos));
glVertexAttribPointer( ..., 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texCoord));
glVertexAttribPointer( ..., 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, normal));

sizeofoffsetof 都会考虑可能发生的任何填充。

如果您想对实际布局有更多控制,您当然也可以使用 #pragma pack,它不是任何 C/C++ 标准的一部分,但所有主要编译器都能理解。实际上,在存在 OpenGL 实现的平台上,没有任何真实世界的编译器会为您的原始结构布局添加任何填充,因此这可能是一个有争议的问题。

Also, I don't know what the layouts or sizes of the glm::vec* types are.

GLM 向量和矩阵是各自基本类型的紧密排列数组,特别是 float[N] 用于 glm::vecN