【问题标题】:C++ struct memory layout and OpenGL glVertexPointer?C++结构内存布局和OpenGL glVertexPointer?
【发布时间】:2011-09-05 06:26:13
【问题描述】:

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

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 不打印相同的值?)

【问题讨论】:

  • 虽然您尝试使用的技术在形式上是“hack”,但它应该在实践中“工作”。你有没有机会对你的结构类型强制一些过度的对齐要求?如果不是,那么问题出在您没有向我们展示的东西上。是否所有节点的所有值(x、y 和 z)都不同?
  • 嗨,我刚刚注意到使用 glVertexPointer(3, GL_FLOAT, sizeof(Rz3DContourNode), &nodes[0]);解决问题!!!
  • @AndreyT:IIRC,标准应该确保std::vector 在内存中应该是连续的。我看不出这有什么特别之处。正如你所说,对齐可能是一个问题。
  • @Mike Bantegui:这与向量无关。在这种情况下,黑客尝试将 6 个连续浮点数的结构重新插入为数组float[6]。在 OpenGL 中,顶点由坐标的数组 表示。出于某种原因,人们坚持在他们的用户代码中将它们表示为 structs,然后在传递给 OpenGL 函数之前将这些结构重新解释为数组,这是一种 hack。
  • @umanga:你当初为什么说1212 代表什么?

标签: c++ opengl pointers memory-management vertex-array


【解决方案1】:
sizeof(Rz3DContourNode) == 6*4 = 24 bytes ... not 12!

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

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

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

glVertexPointer docs:

步幅

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2022-12-05
    • 2015-06-30
    相关资源
    最近更新 更多