我正在编写一个用于学习C ++和3D的小程序。
我已经用有用的方法编写了一个顶点类。 (如Dot,Cross等......)
class cVector {
...
float x, y, z;
...
float dot(cVector& v);
cVector cross(cVector& v);
...
}
现在我意识到OpenGL需要缓冲区,其中元素更像是一个struct(VBO)。
struct sVector {
float x, y, z;
}
所以我的顶点类不再无用,因为如果我想操纵缓冲区中的数据:
1 - 我需要提取缓冲区中元素的数据
2 - 使用数据创建顶点类的临时实例
3 - 使用顶点类方法。 (点,十字等......)
4 - 将数据放回缓冲区
这不是很有效:(。
我想知道是否不应该使用结构来组织我的向量并创建全局函数,这些函数将指向结构的指针作为参数。 我可以更有效地处理数据缓冲区(只是移动指针),但我觉得我会失去C ++的“方便能力”。
在我看过的每个3D C ++源代码中,都使用了顶点类,但我不明白它们如何在“类似结构”的缓冲区中操作大量的顶点。
你能帮我理解吗?什么是最好的方法?答案 0 :(得分:2)
像C ++这样的语言中最常见的方法实际上都不是这些。
struct Vector3 {
union {
struct {
float x,y,z;
};
float v [3];
};
...
Vector3 (float x_, float y_, float z_) : x (x_), y (y_), z (z_) { };
float Norm (void) { return sqrt ((x * x) + (y * y) + (z * z)); }
void Normalize (void) {
float norm = Norm ();
v [0] /= norm;
v [1] /= norm;
v [2] /= norm;
}
};
原因是因为使用匿名联合和结构,您可以将数据视为 浮点数组(v [...]
)或引用各个组件的名称(x
,y
,z
)没有太多麻烦或大惊小怪。通过更智能地使用语言,您可以获得两全其美的效果。
至于在这种特殊情况下struct
和class
之间的差异,从内存表示的角度来看,没有。 C ++中class
和struct
之间的唯一真正区别是默认访问; struct
默认情况下具有 公开 访问权限。
当GL需要访问对象的内部存储器时,您可以通过传递指针:Vector3::v
或单个组件来完成此操作,具体取决于特定的功能。
Vector3 vec (1.0f, 2.0f, 3.0f);
---------------------------------
glVertex3fv (vec.v);
and
glVertex3f (vec.x, vec.y, vec.z);
are equivalent
另一方面,匿名结构是C ++的非标准扩展,但几乎支持所有地方。如果您的编译器不支持它们,则可能必须通过为x
提供名称来限定对y
,z
和struct
的访问权限。
struct Vector3 {
union {
struct {
float x,y,z;
} s;
float v [3];
};
};
如果你用这种方式编写结构,那么:
Vector3 vec;
assert (vec.v [0] == vec.s.x);
以这种方式限定x
是很麻烦的(使用匿名结构,你可以使用vec.x
)。
答案 1 :(得分:0)
struct
和class
之间只有一个区别:对于class
,默认范围为private
,而对于struct
,public
为class cVector {
...
float x, y, z; // data
...
float dot(cVector& v); // just a function
cVector cross(cVector& v); // just a function
...
}
}。
所以
struct sVector {
float x, y, z; // data
}
和
x,y,z
具有完全相同的内存布局(假设cVector
是&v.x
的唯一成员变量)。
您可以使用(x,y,z)
为OpenGL获取指向glVertex3f(&v.x);
的指针,例如std::vector<cVector> vertices(100);
const float* data = &(vertices[0].x);
。
您甚至可以执行以下操作来获取指向连续顶点序列的指针以供OpenGL使用:
{{1}}