SDL2面向对象的包装器; 1000+虚拟函数调用一个帧;有没有办法优化这个?

时间:2015-11-09 17:14:11

标签: c++ function oop polymorphism sdl-2

我正在为SDL2编写面向对象的包装器。我决定创建两个类:Sprite类和Rectangle类。我使用了一些多态性,因此我不必为每个可绘制对象重载draw函数。我有一个基类Drawable,它具有纯粹的虚拟函数draw

现在SpriteRect继承Drawable并定义draw函数以适合类的样式。现在,当我必须在屏幕上绘制很多东西时,我会指向Drawable,然后调用draw方法。这种情况每秒发生1000次以上。

如果我查看我的CPU使用率,它大约是10%。我知道每秒60次抽取1000多个精灵会妨碍我的CPU使用率,但我认为不会那么多。

现在,我的问题:有没有办法优化这个?也许取出纯虚函数只是重载函数?

我的代码(我试图尽可能缩短它):

Sprite :: Draw声明

void Draw() override;

精灵::绘制功能

void Sprite::Draw() {

    // rect is SDL_Rect

    rect.x = rect.x - window->getCamera().getCoords().x;
    rect.y = rect.y - window->getCamera().getCoords().y;
    SDL_RenderCopyEx(window->renderer, texture, NULL, &rect, 0, NULL, flip);

}

调用Sprite :: Draw

的函数
void Window::Draw(Drawable *d) {

    d->Draw();

}

绘制循环

// 1024 grass Sprites

for (int i = 0; i < 1024; i++) {

            mainWindow.Draw(&grass[i]); // Calls Window::Draw

}

正如我之前所说,它占用了大约10%的CPU使用量。我有一台AMD 6300和一台NVIDIA GTX 750Ti。我正在使用Microsoft Visual Studio Express 2013。

可执行文件名是OBA.exe

OBA

2 个答案:

答案 0 :(得分:1)

这些草精灵的纹理是否可以压缩成1个纹理贴图,然后绘制一部分(第三个参数,srcrect - https://wiki.libsdl.org/SDL_RenderCopyEx)?

我猜你不会有1024个独特的草纹,而是一些重复的纹理。将它们全部合并为一个图像并将其加载为草纹理。 然后你的精灵类只需要为它绘制的纹理部分定义一个SDL_Rect

样本纹理:

<img>http://i.imgur.com/MY0BIh2.png</img>

假设您的精灵使用纹理0,它的srcrect将是0,0,32,32。绘制它只会在RenderCopy调用中添加一个参数。

SDL_RenderCopyEx(window->renderer, texture, &srcrect, &rect, 0, NULL, flip);

这可以提高绘制大量精灵的性能。此外,如果它们位于摄像机视图中,您只能绘制精灵。

答案 1 :(得分:0)

我修好了,我所做的只是绘制目前在相机视图中的精灵。 SDL_LogCritical被调用的原因是每次调用SDL_RenderCopyEx,调用SDL_LogCritical以及其他SDL函数。但通过绘制用户可以看到的内容,我将CPU使用率降低到约0.1%