2012-02-18 48 views
0

我正在用C++和DirectX 9编写图形引擎,我打算在后期阶段在游戏中使用它。前一段时间,我写了一个功能齐全的2D引擎和OpenGL中一个基本的3D引擎,但现在我决定在DirectX 9,开始一个新项目DirectX 9中面向对象渲染框架的一般方法?

在我以前的引擎,我做了Entitystd::vector可能包含Tank,Weapon,Particle等子类型。然后,我会通过多态性做类似'for each Entity in std::vector do Entity->Draw()'的操作。绘图功能将做glVertex3f(...)

现在我的问题是:如何在DirectX 9中实现类似的面向对象的框架?我正在考虑为每个类型(Tank,Weapon)保留一个顶点阵列,该顶点从文件加载,将所有对象的所有顶点复制到相同的顶点缓冲区,然后为每个顶点子集调用DrawPrimitive。这是做这个/一般方式的正确方法吗?还是应该为场景中的不同对象创建不同的顶点缓冲区?一些伪代码会很好地说明正确的实现。

回答

0

这取决于你的目标是什么,如果你想要效率,你可以用一个关联句柄在std::unordered_map中加载你的网格物体,纹理相同,那么这将允许你实例化相同对象类型的向量。

如果你想保持它更简单,你可以创建一个容器来存储所有的实体和所需的渲染信息(类似于你的'旧'引擎),尽管可能会希望使用一个剔除数据结构作为以及(像Octree):

class RenderInfo 
{ 
    IDirect3DVertexBuffer9* pVertex; 
    IDirect3DIndexBuffer9* pIndex; 
    //... 
}; 

class EntityController 
{ 
    std::vector<std::pair<Entity,std::shared_ptr<RenderInfo>>> Entities; 
    void Draw() 
    { 
     foreach e in Entities 
      e.first.Draw(e.second); 
    } 
} 

这里std::shared_ptr<RenderInfo>将是唯一的一个VB/IB对,以避免不必要的重复

+0

比方说,我会实现你的简单的方法解决问题(然后可能实例化的稍后阶段的相同对象)。你将在实体的Draw函数中做什么?将顶点复制到VB中,调用DrawPrimitives()并为实体向量中的每个实体清空VB? – red 2012-02-18 23:32:08

+0

您应该为每个不同的网格保留一个vb和一个ib。在渲染前简单地激活正确的。不要改变它们的内容。图形卡针对静态vb/ib进行了优化。通过更改vb/ib的内容,可以在GPU和CPU之间生成大量流量。 – rasmus 2012-02-19 01:16:09