C++ C++;结构内存布局和OpenGL glVertexPointer?
我有以下结构来存储我的顶点数据C++ C++;结构内存布局和OpenGL glVertexPointer?,c++,opengl,pointers,memory-management,vertex-array,C++,Opengl,Pointers,Memory Management,Vertex Array,我有以下结构来存储我的顶点数据 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; 因此,我
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;
因此,我尝试使用指针算法(假设这是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++;
}
但我仍然感到困惑,为什么我的黑客没有在内存中正确遍历?(为什么qDebug不打印相同的值?)
步长是每个顶点开始之间的字节数,而不是填充。尽管0是一个特殊值,表示数据紧密压缩
因此,如果使用3个浮点作为顶点数据,0和12的跨距之间没有区别(因为3个浮点是12字节)。在你的例子中,你的结构是24字节,所以你应该把它
这种约定(步幅=步长,而不是填充)允许简单地使用sizeof,因此您最终直观地做了正确的事情。这是一个很好的API设计
见:
跨步
指定连续顶点之间的字节偏移量。如果大步
如果为0,则表示顶点在数组中紧密排列。
初始值为0
虽然您尝试使用的技术在形式上是一种“黑客”,但它应该在实践中“起作用”。您是否有可能对结构类型强制执行过多的对齐要求?如果不是,那么问题在于你没有向我们展示的东西。所有节点的所有值(x、y和z)都不同吗?嗨,我刚刚注意到使用glVertexPointer(3,GL_FLOAT,sizeof(rz3dcournode),&nodes[0]);解决问题@AndreyT:IIRC,标准应该确保
std::vector
在内存中是连续的。我看不出这有什么不好。正如你所说,对齐可能是个问题。@Mike Bantegui:这与向量无关。本例中的黑客攻击是试图将一个包含6个连续浮点的结构重新插入为数组float[6]
。在OpenGL中,顶点由坐标数组表示。出于某种原因,人们坚持在用户代码中将它们表示为结构,然后在传递给OpenGL函数之前将这些结构重新解释为数组,这是一种黑客行为。@umanga:你最初为什么说12
?12
代表什么?
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++;
}
glVertexPointer(3, GL_FLOAT, sizeof(Rz3DContourNode), &nodes[0]);
sizeof(Rz3DContourNode) == 6*4 = 24 bytes ... not 12!