模板与交换机 我试图在C++领域找到我的方法,现在我越来越困惑。玩具应用程序是一个非常基本的OpenGL引擎。 所以这里有一个(我想很简单)问题: 我想处理不同顶点数据的网格,所以我有 struct Vertex { Vector3f position; } struct VertexN : public Vertex { Vector3f normal; }
现在我需要一个网格类,它保存数据并绘制数据。 我试过这样的方法:模板与交换机 我试图在C++领域找到我的方法,现在我越来越困惑。玩具应用程序是一个非常基本的OpenGL引擎。 所以这里有一个(我想很简单)问题: 我想处理不同顶点数据的网格,所以我有 struct Vertex { Vector3f position; } struct VertexN : public Vertex { Vector3f normal; },c++,C++,现在我需要一个网格类,它保存数据并绘制数据。 我试过这样的方法: template<class T> class Mesh { public: Mesh(); ~Mesh(); void load(const T * vertices, int num); void draw(); protected: T * vertices_; 模板 类网格 { 公众: 网格(); ~Mesh(
template<class T>
class Mesh
{
public:
Mesh();
~Mesh();
void load(const T * vertices, int num);
void draw();
protected:
T * vertices_;
模板
类网格
{
公众:
网格();
~Mesh();
无效荷载(常数T*顶点,整数);
无效抽取();
受保护的:
T*顶点;
})
不同的顶点必须以不同的方式加载和绘制,这可以通过模板专门化来完成
我的问题是,我希望有另一个类来保存网格对象的实例,但显然不允许使用模板化的类成员
我能想到的另一个解决方案是在网格中保留指向基本结构顶点的指针,传递所用顶点类型的标识符,然后在load()和draw()中使用switch语句以允许不同的实现
实现这一目标的最佳方式是什么
非常感谢您的帮助。您可以使用继承和虚拟函数。例如:
class MeshBase
{
public:
virtual ~MeshBase() { }
virtual void draw() = 0;
};
template <typename T>
class Mesh : public MeshBase
{
public:
virtual void draw() { }
// ...
};
classmeshbase
{
公众:
虚拟~MeshBase(){}
虚空绘制()=0;
};
模板
类Mesh:publicmeshbase
{
公众:
虚拟空绘制(){}
// ...
};
使用这种方法,可以将指向基类MeshBase
的指针存储在容器中
理想情况下,您可以使用指针容器为您管理指针,也可以使用智能指针容器(例如,如果您的实现包括shared_ptr
,则使用std::vector
;如果不包括,)
我还建议将顶点存储在
网格
类的容器中,而不是使用手动动态分配和内存管理。我建议您不要模板化网格类,而是使其能够处理不同类型的顶点数据。这是一个常见的图形问题,在DirectX中通过将不同的数据“流”绑定在一起以绘制几何图形来解决。换句话说,法线将是与位置数据不同的数据流。然后,网格对象成为多个数据流的容器,并且在编译时不会绑定到特定的顶点格式。我也不知道OpenGL,但我想也有类似的概念
请参阅:@bshiels有一点,您需要以最有效的方式表示顶点数据,在OpenGL中,这些数据是顶点缓冲区对象(VBO):
考虑到上面链接中公开的指导原则——这与@James McNellis关于不使用顶点类型继承的说法一致——以及加载和绘制都可能取决于顶点类型和输入(或输出)类型的事实,我建议您使用静态多态性应用策略模式,如对另一个问题的回答所述:考虑到顶点类的继承性,网格上的模板是否也可以删除?@drfrogsplat:仅当您希望存储指向各个顶点的指针时,这可能是出于性能原因而不需要的。我不会对顶点类使用继承:只需将每种类型的顶点实现为一个独立的类或使用一个模板(例如,OpenSceneGraph就是这样做的)。如果您有权访问boost(它是boost.PointerContainer的一部分),请尝试将
boost::ptr_vector
优先于std::vector
。在C++0x中,您可以使用std::vector
来避免boost依赖关系。@James:我知道解决方案必须很简单,谢谢!我还将删除顶点结构中的继承。关于在std::vector中存储顶点:那么仍然可以使用offsetof()宏访问顶点的不同成员吗?@matthieu:是的,学习boost是我的待办事项列表中的一部分,我会记住的谢谢。draw()已使用VBOs的包装器。我还应该正确地对齐数据。。。你链接的帖子很有趣,但现在对我来说似乎有些过分了。不管怎样,我还是把它放进书签了。