这是我在编写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中定义的结构,如果有人好奇的话)。
答案 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]
不幸的是,名称x
,y
和z
可能会成为像这样定义宏的问题。这就是许多经典C结构为结构元素使用前缀名称的原因之一,例如st_dev
,tv_sec
,si_uid
等......