C 语言中的 offsetof 意义及理解 使用例子

在学习VBO的时候,有这样的问题:

顶点数据是以下面的 Class 结构存储

class Vertex
{
public:
	glm::vec3 Position;
	glm::vec4 Color;
};

三个顶点的数据 push_back 到 Vector 中

std::vector vertices;

Vertex v;
v.Position = glm::vec3(-5.0f, -5.0f, 0.0f);
v.Color = glm::vec4(1, 0, 0, 1);
vertices.push_back( v);

v.Position = glm::vec3(5.0f, -5.0f, 0.0f);
v.Color = glm::vec4(0, 1, 0, 1);
vertices.push_back( v);

v.Position = glm::vec3(0.0f, 5.0f, 0.0f);
v.Color = glm::vec4(0, 0, 1, 1);
vertices.push_back( v);

创建一个 VBO 用来存放上面的顶点属性数据

glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);

在 传递顶点数组指针的时候就有疑问了,因为 Position 是 0 ,对于 Color 属性数据,要计算偏移。

这个时候就可以用 offsetof 来帮忙了。

glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]);
glVertexAttribPointer(m_program.m_position, 3, GL_FLOAT, false, sizeof(Vertex),(GLvoid*)0);
glVertexAttribPointer(m_program.m_color, 4, GL_FLOAT, false, sizeof(Vertex), (GLvoid*)offsetof(Vertex,Vertex::Color));


offsetof 是一个宏,在 stddef.h 中定义

#define offsetof(struct_t,member) ((size_t)(char *)&((struct_t *)0)->member)

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn


对于 offsetof 的解释:

(struct_t *)0是一个指向struct_t类型的指针,其指针值为 0,所以其作用就是把从地址 0 开始的存储空间映射为一个 struct_t 类型的对象。

((struct_t *)0)->member 是访问类型中的成员 member,相应地 &((struct_t *)0)->member) 就是返回这个成员的地址。

由于对象的起始地址为 0,所以成员的地址其实就是相对于对象首地址的成员的偏移地址。然后在通过类型转换,转换为 size_t 类型(size_t一般是无符号整数)。

所以,offsetoff(struct_t,member)宏的作用就是获得成员member在类型struct_t中的偏移量。



你可能感兴趣的:(C++)