2012-02-10 65 views
2

我现在的渲染方式并没有什么问题,但我觉得这不是处理渲染的好方法。我正在使用SDL。一个干净的方式来渲染东西

它归结到这一点,我有一些抽象类

class Renderable 

有两个功能。

virtual void update() = 0; 
virtual void doRender(SDL_Surface* surface) = 0; 

我有另一类

class RenderManager 

随着1 std::vector

std::vector<Renderable*> _world; 

和2 std::queue

std::queue<Renderable*> _addQueue; 
std::queue<Renderable*> _delQueue; 

这两个队列包含需要添加到下一个滴答的可渲染对象以及需要删除的可渲染对象。尽一切办法给了我一些问题,现在我想到了这一点,这是有道理的(至少我是这么做的)。

可执行文件可以静态添加和从RenderManager中删除自己。

这里或多或少的处理一切的函数。

void renderAll() { 
    std::vector<Renderable*>::iterator begin, end; 
    begin = _world.begin(); 
    end = _world.end(); 

    for (;begin != end; ++begin) { 
     (*begin)->update(); 
     (*begin)->doRender(_mainWindow); // _mainWindow is the screen of course 
    } 

    begin = world.begin(); 

    if (_delQueue.size() > 0) { 
     for (unsigned int i = 0; i < _delQueue.size(); i++) { 
      std::vector<Renderable*>::iterator del; 
      del = std::find(begin, end, _delQueue.front()); 

      if (del != end) { 
       delete *del; 
       _world.erase(del); 
      } 
      _delQueue.pop(); 
     } 
    } 

    if (_addQueue.size() > 0) { 
     for (unsigned int i = 0; i < _addQueue.size(); i++) { 
      Renderable* front = _addQueue.front(); 

      // _placement is a property of Renderable calculated by RenderManager 
      // where they can choose the level they want to be rendered on. 
      _world.insert(begin + front->_placement, front); 
      _addQueue.pop(); 
     } 
    } 
} 

我对C++很陌生,但我想我至少在平均规模上知道我的方式。我甚至更新SDL,但它看起来非常简单易学。我很担心,因为我有3个大环一起。我尝试了一次,但我在循环过程中遇到了问题,导致了大量的破坏。但我并不是说我做对了! :)

我在想也许是涉及到线程的东西?

编辑:

啊,对不起,含糊不清。 “更清洁”我的意思是更有效。我的方法也没有“问题”,我只是觉得有一个更有效的方法。

+0

我不明白你的做法。性能? – rasmus 2012-02-10 00:42:59

+1

这是一个很难回答的问题,主要是因为“渲染”是一个非常普遍的术语,处理它的最佳方式将在很大程度上取决于特定的渲染类型。另外,“最好”是主观的:你说的是性能最高的?最简单的代码? – 2012-02-10 00:44:07

+1

您可以使用[std :: remove](http://www.cplusplus.com/reference/algorithm/remove/)来代替手动循环_delQueue。 – 2012-02-17 12:34:31

回答

0

首先,我会说不要修理没有损坏的东西。您是否遇到性能问题?除非你在每一帧中大量添加和删除“可呈现的东西”,否则我看不到你有什么大问题。当然,就整体应用而言,它可能是一个笨拙的设计,但是你没有说明这是一种什么样的应用,所以很难判断,如果不是不可能的话。

但是,我可以猜测并说,因为您使用的是SDL,所以您有机会开发游戏。就我个人而言,我总是通过为每个活动对象提供渲染方法来渲染游戏对象,并使用对象管理器为每个对象循环指向每个对象的指针并调用此渲染方法。因为不断移除矢量中间的某个项目可能会导致内存复制(向量保证连续内存)导致速度变慢,所以您可以在每个要删除的对象中设置一个标志,并定期将对象管理器执行“垃圾收集”,同时删除所有设置了该标志的对象,因此减少了需要完成的复制量。在垃圾收集发生之前,管理者只是忽略标记的对象,不会每次打勾都调用它的渲染方法 - 就好像它已经消失了一样。实际上,这与您在队列系统中所拥有的不同,事实上,如果游戏对象是从您的“可渲染”类派生的,则它可能被视为相同。

顺便问一下,有什么理由在访问它们的元素之前查询队列大小?如果size()是0,则for循环将无法操作。

相关问题