使用SDL2

时间:2017-09-20 00:10:55

标签: c++ graphics sdl-2

我正在使用SDL2在C ++中制作2D游戏,其中世界地图由120x67个拼贴组成。在任何给定的时间,地图上只会有大约20个左右的精灵(每个精确占据一个瓷砖),并且只有一小部分瓷砖(主要是水砖)将被动画化。因此,在绝大多数情况下,大多数瓷砖将保持静止。目前,我有一个简单的绘制循环,遍历所有切片并重绘它们:

/* Drawing loop, excluding frame rate limiting logic and updating gamestate */
while(true) {

    /* game state is updated (omitted) */

    /* clear the entire screen */
    SDL_RenderClear(renderer);

    /* loop through all the tiles and redraw them */
    for (int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++) {

            /* call the tile's draw method, which calls SDL_renderCopy()
             * to draw the tile background and sprite (if there is one) */
            tiles[i][j].drawTile(renderer);
        }
    }

    /* output everything to the screen */
    SDL_RenderPresent(renderer);
}

但是,由于大多数瓷砖在大多数时间都会保持静止,因此无需继续绘制它们。仅重绘正在改变的屏幕的小部分将更加有效。所以我的新想法是,在更新游戏状态时,将所有更新的图块添加到列表中,然后只需重新绘制每个帧上更新的图块,如下所示:

/* Drawing loop that only redraws updated tiles */
while(true) {

    /* game state is updated, updated tiles added to a list (omitted) */

    /* loop through only the updated tiles and redraw them */
    for (std::list<Tile>::iterator it=updatedTiles.begin(); it != updatedTiles.end(); ++it) {

        /* call the tile's draw method, which calls SDL_renderCopy()
         * to draw the tile background and sprite (if there is one) */
        it->drawTile(renderer);
    }

    /* output everything to the screen */
    SDL_RenderPresent(renderer);
}

由于我不想在每个帧之前清除屏幕,因此在第二种情况下会删除对SDL_RenderClear()的调用。但是,从SDL_RenderPresent找到here的SDL2文档中可以看出:

  

强烈建议您在开始每个新帧的绘图之前调用SDL_RenderClear()来初始化后备缓冲区。

有了这个,我的两个问题是:

  1. 如果我打算只更新修改过的图块,我是否真的需要在每个帧上调用SDL_RenderClear()
  2. 如果我必须坚持重绘每一帧上的每一块瓷砖,那么现代图形卡/ SDL库&#34;智能&#34;在调用SDL_RenderPresent()时,只需重新绘制已更改的屏幕部分,而不必执行此操作?

1 个答案:

答案 0 :(得分:0)

文档的相关部分紧接在您提到的文件之前(强调我的)

  

backbuffer 应该在每次出现后被视为无效;不要假设帧之间存在先前的内容。

这意味着,对SDL_RenderClear的调用必须超过建议的

你可以做的是绘制背景图片(无论它意味着什么,例如你不能拥有任何PC或NPC的图块集)在进入场景之前只进行一次纹理(有关详细信息,请参阅SDL_SetRenderTarget和其他函数)。然后,在循环中,您可以清除默认渲染器,立即将该图像复制为背景图像,最后只在其上绘制更新的图块,从而更新它们(让我说)默认或基本表示 事实上,如果您更新了N个图块,最终会在每次迭代时使用N + 1调用SDL_RenderCopy或其他任何内容来绘制所有内容。

老实说,只有当你观察到大量的帧时才会这样做,因为你在每次迭代时都画了太多。我的两分钱 无论如何,它是一个肮脏且有效的解决方案,至少可以满足您的需求。