可以为每个精灵调用 SDL_RenderCopy() 吗?

时间:2021-02-20 17:56:47

标签: c++ sdl-2

这是我的问题的后续:Is it okay to have a SDL_Surface and SDL_Texture for each sprite?

我创建了一个名为 entity 的类,每个类都有一个 SDL_Texture,它在构造函数中设置,然后为向量中的每个屏幕实体调用成员函数 render(),它使用 SDL_RenderCopy() 绘制到渲染器。< /p>

这个 render() 函数包括根据每个精灵的位置/相机数据为每个精灵生成矩形

这样好吗?有没有更快的方法?

我用 96 个精灵制作了一个测试关卡,每个精灵占据屏幕的 2%,大量透支,ft 为 15ms (~65fps),分辨率为 1600x900。对于某些精灵来说似乎有点慢,而且我的电脑在玩完整游戏(例如《洞穴探险》或《以撒》)时呼吸更重。

2 个答案:

答案 0 :(得分:2)

帧时间优于 FPS

您想根据帧时间而非 FPS 来衡量和判断您的表现。因为两者之间的关系不是线性的。从 20 FPS 到 30 FPS 需要大约 16.7 毫秒的优化时间。这与从 30 FPS 到 60 FPS 所需的优化性能增益相同。因此,如果您根据 FPS 判断性能,您会得出结论,将 FPS 从 30 增加到 60 的特定“优化”比使 20 FPS 场景运行 31 FPS 更好。而后者实际上是更好的优化。

批量抽奖

如果您将所有纹理打包成一个并存储每个单独图像的坐标,则可以使用相同的纹理来绘制多个对象。这受到纹理的大小和数量以及环境中支持的最大纹理大小的限制。根据我的经验,4096x4096 是安全的,但我更喜欢使用 2048x2048 的“纹理图集”。有许多实用程序可以制作此类纹理。您可以通过 Google 搜索轻松找到合适的。

在此设置中,除了 SDL 纹理之外,每个精灵还具有包含所需特定图像的“大”纹理中区域的 x、y、宽度和高度。您可以创建一个 TextureRegion 类。每个精灵都有一个TextureRegion。这整个过程通常称为批处理。查一下。整个想法是最小化状态变化。我不确定它是否适用于软件渲染或所有 SDL2 后端。

缓存您的转换

批处理您的精灵将提高 GPU 方面的性能。 CPU 绑定代码是另一个优化机会。不是在每一帧计算SDL_RenderCopy的参数,而是计算一次并缓存它们。然后当相机或物体的位置/旋转发生变化时,重新计算缓存。您可以在实体类的“访问器”(如 setPositionsetRotaion 等)中执行此操作。请注意,不是在位置或旋转改变后立即重新计算变换,而是希望将对象标记为“脏”并在渲染函数中检查脏标志。 if this->isDirty 然后重新计算并缓存转换。这可以防止您执行此操作时进行冗余计算:

//if dirty flag is not used each of the following function calls
//would have resulted in a recalculation of transforms. However by
//using the dirty flag they will be calculated only once before 
//the rendering of next frame in the render() function.
player->setPostion(start_x,start_y);
player->setRotation(0);
camera->reset();

答案 1 :(得分:0)

因此,我通过在“要求”级别全屏检查该程序的内存/cpu 使用情况进行了更多测试,并通过强制帧率上限使其与其他游戏类似

strong> 使用 SDL_Wait()

float g_max_framerate = 60;
float g_max_frametime = 1/g_max_framerate * 1000;
...
while (!quit) { 
        
        lastticks = ticks;
        ticks = SDL_GetTicks();
        elapsed = ticks - lastticks;
        
        ...
        
        SDL_RenderPresent(renderer);
        //lock framerate
        if(elapsed < g_max_frametime) {
            SDL_Delay(g_max_frametime - elapsed);
        }
}

由于这个限制,它是适当的低规格。