用SDL2在每个帧上渲染屏幕的部分
Rendering parts of the screen on each frame with SDL2
我使用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
的SDL2文档中说:
强烈建议您在启动每个新帧的绘图之前调用SDL_RenderClear()初始化backbuffer。
这样,我的两个问题是:
- 如果我只需更新修改的瓷砖,我真的需要在每个帧上调用
SDL_RenderClear()
? - 如果我必须坚持在每个框架上重新绘制每个瓷砖,则是现代图形卡/SDL库"智能",以至于在呼叫
SDL_RenderPresent()
时,只能重新绘制更改的屏幕部分,而没有我实施此操作?
文档的相关部分是在您提到的(强调我的)
之前backbuffer 应在每次存在后视为无效;不要假设以前的内容将存在于框架之间。
这意味着对SDL_RenderClear
的调用是强制性的,而不是建议的。
您可以做的是绘制背景图像(无论是什么意思,作为一个示例,在没有PC或NPC周围没有PC或NPC的一个示例)上仅在目标纹理上一次进入场景之前(有关更多详细信息,请参见SDL_SetRenderTarget
和其他功能)。然后,在循环中,您可以清除默认渲染器,立即将该图像复制为a background Image ,最后仅绘制更新的图块,从而更新其(让我说)默认或基本表示。
实际上,如果您已更新了n个瓷砖,则最终会用n 1个调用SDL_RenderCopy
或每次迭代中的任何内容绘制所有内容。
说实话,我只有在您观察大量帧的情况下,我才这样做,因为您在每次迭代中都绘制了太多。我的两分钱。
无论如何,这是一个肮脏且工作的解决方案,至少可以执行您想要的。
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 使用 SFML 和 C++ 将 Pixel 打印到屏幕上
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- 如何创建事件驱动的 SDL2 应用程序
- 使用 SDL2 和SDL_image C++加载图像
- Winapi:屏幕截图未显示在窗口中
- 如何在快板的屏幕中显示子位图的绘制?
- 将 SDL2 与 CMake 链接起来
- SDL2:如何在不清除屏幕的情况下渲染
- 如何使用 SDL2 在C++中将框渲染到屏幕上
- 如何使用 SDL2 移动屏幕,C++
- SDL2-从Surface(屏幕快照)创建纹理的问题
- 在锁定屏幕上恢复Android SDL2
- 用SDL2在每个帧上渲染屏幕的部分
- SDL1 -> 使用自定义屏幕模式类构建 SDL2 分辨率列表
- SDL2图像到屏幕问题
- SDL2加载屏幕/线程
- 如何使用SDL2获得屏幕分辨率
- SDL2,创建比屏幕大的窗口