1

我有以下结构来存储我的顶点数据。

struct Rz3DContourNode {
  float x; //pos x
  float y;   //pos y
  float z;  //pos z
  float nx;  //normal x
  float ny;  //normal y
  float nz;  //normal z
};

我将顶点列表存储在 STL 向量中,如下所示:

std::vector < Rz3DContourNode >  nodes;

当我尝试将其用作 OPEGL 中的顶点数组时,in 不会正确渲染。

glVertexPointer(3, GL_FLOAT, 12, &nodes[0]);
glDrawArrays(GL_POINTS,0,nodes.size());

因此,我尝试使用指针算法(假设这就是 OPENGL 处理数据的方式)来确认这些值,如下所示:

float *ptr=(float*) &nodes[0];

for(int i=0;i<nodes.size();i++)
{

   Rz3DContourNode confirmNode=nodes[i];  

  float x=*ptr;
    ptr++;

  float y=*ptr;
    ptr++;

  float z=*ptr;
     ptr++;


  //Confirm values !!! Do not equal ??
  qDebug("x=%4.2f  y=%4.2f z=%4.2f  | nx=%4.2f ny=%4.2f nz=%4.2f
        ",confirmNode.x,confirmNode.y,confirmNode.z,x,y,z);



  //Skip normal positions
  ptr++;
  ptr++;
  ptr++;

}

如果我直接从结构访问值,则值不相等。

这是否意味着 struct 不会连续保存值?

[编辑] 我刚刚注意到使用 sizeof() 而不是 12 可以解决以下问题:

glVertexPointer(3, GL_FLOAT, sizeof(Rz3DContourNode), &nodes[0]);

但是我仍然很困惑为什么我的 hack 没有在内存中正确遍历?(为什么 qDebug 不打印相同的值?)

4

1 回答 1

3
sizeof(Rz3DContourNode) == 6*4 = 24 bytes ... not 12!

步幅是每个顶点开始之间的字节数,而不是填充。虽然 0 是一个特殊值,表示数据紧密打包。

因此,如果您使用 3 个浮点数作为顶点数据,则步长 0 和 12 之间没有区别(因为 3 个浮点数是 12 个字节)。在你的情况下,你的结构是 24 个字节,所以你应该放那个。

这种约定(步幅 = 步长,而不是填充)允许简单地使用 sizeof,因此您最终直观地做了正确的事情。这对你来说是很好的 API 设计。:)

请参阅glVertexPointer 文档

大步

指定连续顶点之间的字节偏移量。如果 stride 为 0,则顶点被理解为紧密排列在数组中。初始值为 0。

于 2011-09-05T07:07:37.223 回答