我现在渲染的方式并没有任何问题,但我觉得这不是处理渲染的好方法。我正在使用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;
这两个队列包含需要在下一个tick中添加的可渲染项和需要删除的渲染项。一次性完成所有事情给了我一些问题,现在我想到了它,它是有道理的(至少我做的方式)。
Renderables可以静态地从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 :(得分:0)
首先,我要说的是不要修复一些没有破坏的东西。您是否遇到性能问题?除非你每帧都大量添加和删除'renderables',否则我看不到你所拥有的大问题。当然,就整体应用而言,它可能是一种笨拙的设计,但你没有说明这是什么类型的应用,所以判断很难,甚至不可能。
然而,我可以猜测并说因为你正在使用SDL,你可能正在开发一款游戏。我个人总是通过为每个活动对象提供一个render方法来渲染游戏对象,并使用一个对象管理器在每个tick中循环遍历每个对象的指针并调用这个render方法。因为从向量中间不断删除项目会导致内存复制导致速度变慢(向量保证连续内存),所以在每个要删除的对象中都可以有一个标记,并定期对象manager执行'垃圾收集',删除同时设置此标志的所有对象,从而减少需要完成的复制量。在垃圾收集发生之前的平均时间内,管理器只是忽略标记的对象,而不是每次调用它的渲染方法 - 就像它已经消失一样。它实际上与您在队列系统中所拥有的内容并没有太大不同,事实上如果游戏对象来自您的“可渲染”类,则可以认为它是相同的。
顺便提一下,在访问元素之前是否有任何理由要查询队列大小?如果size()为0,for循环将无法运行。