一组结构的平面数组?

时间:2011-04-17 21:49:24

标签: c++ c opengl

嘿伙计们。谢谢你点击。

这是我在编写OpenGL时遇到的一个问题,但这是一个非常普遍的问题 - 所以没有图形特定的。

我有一个结构(不是一个类,只是一个简单的结构),粒子。

typedef struct
{
    float x;
    float y;
    float z;
}float3;

typedef struct
{
   float3 position;
   float3 velocity;
   //...other stuff
}Particle;

我正在使用一堆粒子(粒子*粒子[]),但我有一个函数需要以x,y,z顺序打包的位置的浮点*。

因此我的问题摘要:

我的数据:

//I have this in a bunch of encapsulated structs
[... {1.0f, 2.0f, 3.0f,} ... {4.0f, 5.0f, 6.0f} ...]

//I want...
[1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f]

我的问题是......我已经掌握了所有数据!我不想再次使用malloc / memcpy了。有没有办法使用已存在的数据?任何C指针杂技?我也担心对齐/填充等问题。

(float3是CUDA中定义的结构,如果有人好奇的话)。

4 个答案:

答案 0 :(得分:6)

glVertexAttribPointer有一个stride参数,专为此情况而设计。

通常,您会将一个Particle个对象数组加载到VBO中,然后使用VBO绑定:

glVertexAttribPointer(shader_arg_position, 3, GL_FLOAT, GL_FALSE, sizeof (Particle), offsetof(Particle, position));

答案 1 :(得分:0)

我的解决方案更倾向于C。

带指针的东西,你可以使用它们从一个内存地址自由地走到另一个内存地址的想法“不关心那里有什么数据”。结合这一事实,当你分配结构时,它们按照它们被声明的顺序排列,你可以自己轻松地访问数据,而不会有太多的麻烦。

只需让float* index指向矢量结构的开头,即可保存所有点。现在使用index可以随心所欲地遍历它,然而在指针移动停止的地方要小心。


解释一下:

struct {
  float3 position;
  float3 velocity;
  float3 more_data;
} Particle;

分配此结构时,内存将如下所示:

3 floats for position || 3 floats for velocity || 3 floats for whatever data

在地址float*处取position.x,并在考虑到您要处理的数据(位置,速度等)时通过粒子递增。

关于对齐,它取决于您希望结构具有哪种对齐方式。

答案 2 :(得分:-1)

在这里重新诠释演员和很多关心怎么样?

Particle* pP[];
// Fill your array of particles
// And now at your own risk (memory accesses and so on... :)
float* pF = reinterpret_cast<float*>(&pP[0]);
float x = pF[0];
float y = pF[1];
float z = pF[2];
pF = reinterpret_cast<float*>(&pP[1]);
// ..

如果你有你的Particle *数组,但你想使用它就好像它是一个浮点数组,你可以写这样的东西:

float getNthFloat(size_t n)
{
  size_t i = n / 3;
  size_t j = n % 3;
  float* pF = reinterpret_cast<float*>(&pP[i]);
  return pF[j];
}
// This would get 6th element in your virtual float array
// That is, second z position
size_t foo = 5;
float blah = getNthFloat(5);

更进一步;你可以重写这个,所以它实际上看起来像访问一个数组而不是调用一个函数。

答案 3 :(得分:-4)

理想的解决方案是解雇任何设计float3的人,并用简单的阵列替换这个结构。

如果你不能这样做,你可以尝试简单地转换指针,但是你可能会发现你的编译器拒绝生成工作代码,因为这违反了别名规则。

还有一个解决方案:

typedef struct {
    float elem[3];
} float3;
#define x elem[0]
#define y elem[1]
#define z elem[2]

不幸的是,名称xyz可能会成为像这样定义宏的问题。这就是许多经典C结构为结构元素使用前缀名称的原因之一,例如st_devtv_secsi_uid等......