假设传递给 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));
sizeof
和 offsetof
都会考虑可能发生的任何填充。
如果您想对实际布局有更多控制,您当然也可以使用 #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
。
我正在看一个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));
sizeof
和 offsetof
都会考虑可能发生的任何填充。
如果您想对实际布局有更多控制,您当然也可以使用 #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
。