【发布时间】:2014-01-27 22:36:50
【问题描述】:
我需要实现一个按属性存储顶点的结构。例如,每个顶点都有一个属性,如“Normals”或“Position”、“Colors”等,并且可以通过它们的名称访问它们。
VertexStructure vstruct;
AttribStream posStream = vstruct.CreateNewAttributeStream("Position",Vec3<double>);
posStream.push_back(Vec3<double>(23.5,12.5,11.3));
AttribStream normalStream = vstruct.CreateNewAttributeStream("Normals",Vec3<double>);
normalStream.push_back(Vec3<double>(0.03,0.02,0.18));
AttribStream indexStream = vstruct.CreateNewAttribStream("Indices",int);
indexStream.push_back(23);
std::cout << indexStream.size() << "," << normalStream.size() << posStream.size() << std::endl;
现在我可以做到的一种简单方法是使用预定义的数据类型创建一个枚举,就像 OpenGL 的做法一样。喜欢:
enum {
DOUBLE = 0,
FLOAT,
INT,
};
AttribStream posStream = vstruct.CreateNewAttributeStream("Position",DOUBLE,3);
posStream.push_back_vec3d(23.5,12.5,11.3);
但是,它非常冗长,我必须为每种可能的数据类型创建一个枚举,并为每种数据类型提供单独的函数来推回新元素。
另一种可能的方法是使用抽象类。但即使这样也不能保证类型安全(除非使用 RTTI)并且涉及强制转换并且也很难抽象它。另外,没有办法创建通用的“push_back”,所以我需要为每种类型创建专门的函数。
class PX_STREAMBase
{
public:
template <typename T>
PX_STREAMBase( T val) : value_type(typeid(T)),
value_size(sizeof(val))
{};
virtual size_t bytes() const = 0;
virtual size_t size() const = 0;
virtual const void* data() const = 0;
const std::type_info& value_type;
const std::size_t value_size;
private:
};
template<typename T, template <typename, typename> class Container = std::vector> class PX_STREAM;
template<typename T, template <typename, typename> class Container>
class PX_STREAM : public PX_STREAMBase {
public:
PX_STREAM() :
PX_STREAMBase( T())
{}
size_t bytes() const {
return vec.size() * value_size;
}
size_t size() const {
return vec.size();
}
const void* data() const {
return vec.data();
}
private:
Container<T, std::allocator<T> > vec;
};
最后,使用 char 数组结构为 described in this question 那么,创建一个抽象向量并可以保存任何类型的属性流的结构的最佳方法是什么?
【问题讨论】:
-
你过火了:
VEC2_DOUBLE。首先,双精度顶点属性是 GL4 的特性;事实上,D3D11 甚至不支持它们。您应该做的是将基本组件类型和组件数量存储为两个单独的属性。例如,您在此类属性中有 2 个GLdouble组件。计数 = 2,组件 = GLdouble。双精度对于渲染并不是特别有用。 -
数据不应该与 OpenGL 兼容。我只是用它作为例子。但你是对的。
-
好吧,您在问题中提到了 “就像 OpenGL 是如何做到的一样”。这实际上并不是 GL 的做法。虽然 GL 确实有
DOUBLE_VEC2作为常量枚举,但它用于 describe the type of a GLSL variable。您永远不会使用该枚举告诉 GL 顶点属性,它总是通过告诉 GL 底层数据类型和组件数量来完成。如果你想像 GL 那样做,那么你会遵循那个模式。 -
明白了。但是,这仍然意味着 POD 结构必须分解为单独的属性。
标签: c++ opengl data-structures stl