Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 呈现事物的干净方式_C++_Algorithm_Rendering_Sdl - Fatal编程技术网

C++ 呈现事物的干净方式

C++ 呈现事物的干净方式,c++,algorithm,rendering,sdl,C++,Algorithm,Rendering,Sdl,我现在渲染的方式没有任何问题,但我觉得这不是一种很好的处理渲染的方式。我用的是SDL 归结起来,我有一些抽象类 class Renderable 有两个功能 virtual void update() = 0; virtual void doRender(SDL_Surface* surface) = 0; 我还有一节课 class RenderManager 使用1std::vector std::vector<Renderable*> _world; 这两个队列包含需要

我现在渲染的方式没有任何问题,但我觉得这不是一种很好的处理渲染的方式。我用的是SDL

归结起来,我有一些抽象类

class Renderable
有两个功能

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

我还有一节课

class RenderManager
使用1
std::vector

std::vector<Renderable*> _world;
这两个队列包含需要在下一个标记中添加的可渲染文件和需要删除的可渲染文件。一次完成每件事都会给我带来麻烦,现在我想起来,这是有道理的(至少我是这样做的)

可渲染文件可以静态地在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();
        }
    }
}
void renderAll(){
std::vector::迭代器开始、结束;
begin=_world.begin();
end=_world.end();
for(;begin!=end;++begin){
(*开始)->更新();
(*begin)->doRender(_mainWindow);//_mainWindow当然是屏幕
}
begin=world.begin();
如果(_delQueue.size()>0){
for(无符号整数i=0;i<_delQueue.size();i++){
std::vector::迭代器del;
del=std::find(begin,end,_delQueue.front());
如果(del!=结束){
删除*del;
_删除(del);
}
_delQueue.pop();
}
}
如果(_addQueue.size()>0){
for(unsigned int i=0;i<_addQueue.size();i++){
Renderable*front=_addQueue.front();
//_placement是RenderManager计算的Renderable属性
//他们可以在其中选择要渲染的级别。
_插入(开始+前面->前面的位置);
_addQueue.pop();
}
}
}
我对C++有点陌生,但我想至少我知道我的方法是平均规模。我甚至比SDL还新,但它似乎非常简单易学。我很担心,因为我有三个大环在一起。我试过一次拍摄,但在拍摄过程中,我遇到了调整世界大小的问题,造成了巨大的破坏。但我并不是说我做得对!:)

我在想可能是关于线程的事情

编辑:


啊,很抱歉这么含糊不清。我所说的“更清洁”是指更高效。此外,我的方法也没有“问题”,我只是觉得有一种更有效的方法。

首先,我要说的是,不要修复未损坏的东西。您是否遇到性能问题?除非你在每一帧中添加和删除大量的“可渲染”,否则我看不出你有什么大问题。当然,就整体应用程序而言,它可能是一个笨拙的设计,但您还没有说明这是用于什么类型的应用程序,因此很难判断(如果不是不可能的话)

然而,我可以猜测并说,因为您正在使用SDL,所以有可能您正在开发一个游戏。就我个人而言,我总是通过为每个活动对象提供一个渲染方法来渲染游戏对象,并使用对象管理器在指向每个对象的指针之间循环,并调用此渲染方法。由于不断地从向量中间删除一个项可能会由于内存的内部复制(向量保证连续内存)而导致速度减慢,因此可以在每个对象中设置一个标志,该标志在要删除时设置,并且对象管理器会定期执行“垃圾收集”,同时删除设置了此标志的所有对象,从而减少需要执行的复制量。同时,在垃圾回收发生之前,管理器只是忽略标记的对象,而不是在每次勾选时调用它的render方法,就好像它已经消失了一样。事实上,它与队列系统没有太大的不同,事实上,如果游戏对象是从“renderable”类派生的,那么它可以被认为是相同的


顺便问一下,在访问队列元素之前查询队列大小有什么原因吗?如果size()为0,for循环无论如何都不会运行。

首先,我要说的是不要修复未损坏的东西。您是否遇到性能问题?除非你在每一帧中添加和删除大量的“可渲染”,否则我看不出你有什么大问题。当然,就整体应用程序而言,它可能是一个笨拙的设计,但您还没有说明这是用于什么类型的应用程序,因此很难判断(如果不是不可能的话)

然而,我可以猜测并说,因为您正在使用SDL,所以有可能您正在开发一个游戏。就我个人而言,我总是通过为每个活动对象提供一个渲染方法来渲染游戏对象,并使用对象管理器在指向每个对象的指针之间循环,并调用此渲染方法。由于不断地从向量中间删除一个项可能会由于内存的内部复制(向量保证连续内存)而导致速度减慢,因此可以在每个对象中设置一个标志,该标志在要删除时设置,并且对象管理器会定期执行“垃圾收集”,同时删除设置了此标志的所有对象,从而减少需要执行的复制量。同时,在垃圾回收发生之前,管理器只是忽略标记的对象,而不是在每次勾选时调用它的render方法,就好像它已经消失了一样。事实上,它与队列系统没有太大的不同,事实上,如果游戏对象是从“renderable”类派生的,那么它可以被认为是相同的


顺便问一下,在访问队列元素之前查询队列大小有什么原因吗?如果size()为0,for循环无论如何都不会运行。

我不认为您的方法有问题。性能?这是一个很难回答的问题,主要是因为“渲染”是一个非常通用的术语,处理它的最佳方式在很大程度上取决于特定的渲染类型。此外,“最佳”也是主观的:你说的是最优秀的吗?最简单的代码?你可以
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();
        }
    }
}