SDL2:如何在不清除屏幕的情况下进行渲染

Posted

技术标签:

【中文标题】SDL2:如何在不清除屏幕的情况下进行渲染【英文标题】:SDL2: How to render without clearing the screen 【发布时间】:2019-02-14 10:49:22 【问题描述】:

我正在尝试为图形库制作 SDL2 适配器。我相信这个库假设它在屏幕上绘制的所有东西都保留在屏幕上,只要它从不在屏幕上绘制任何东西。 (详情见问题末尾)

最好的方法是什么?

我遇到过多种解决方案,包括:

硬件渲染,无需调用SDL_RenderClear。这样做的问题是 SDL 使用双缓冲区,因此内容可能会出现在其中任何一个缓冲区中,而我最终一次只能看到渲染的一个子集。 软件渲染,如果我对 SDL 的理解正确,这意味着有一个我映射到纹理的表面,所以我可以渲染纹理,我将编辑 pixels 字段主存储器中的表面。这会很慢,而且由于库希望所有内容都立即渲染并且没有帧的概念,这意味着每次有更新(甚至是单个像素)时都将数据发送到 gpu。

我可能遗漏了一些关于 SDL2 的内容,当然还有关于库 (Adafruit-GFX-Library) 的内容。在这种情况下,transaction api 是什么意思?我找不到任何有关它的信息,我觉得它可能很重要。

【问题讨论】:

即使没有双缓冲,也可能被其他窗口遮蔽。您可以渲染到纹理,然后将该纹理复制到帧缓冲区。或者使用软件渲染,例如固定更新间隔(每 1/n 秒刷新到屏幕,例如监控 vsync 间隔)。虽然不清楚你的目标是什么。您是否出于某种原因在模拟 VGA? 是的,我的目标是模拟一个 tft arduino 屏幕,它由我链接的库控制。每隔一段时间刷新可能是个好主意,而且性能对于我的应用程序来说可能已经足够了。 @keltar 我很难找到有关遮蔽的信息。你介意再详细说明一下吗? 假设您已将窗口最小化,然后将其恢复。之后,前端缓冲区的内容可能会丢失。如果其他窗口遮盖了您的窗口(显示在其顶部,因此您看不到窗口的某些部分),或者窗口部分超出屏幕-我想是窗口系统/图形驱动程序将定义前缓冲区会发生什么在那种情况下。 【参考方案1】:

在我对 SDL2 和一般渲染应用程序编程的理解中,SDL2 被设计为每次绘制一个完整的帧,这意味着您可以通过 OpenGL API 调用清除“当前窗口”

glClearColor(0, 1.0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);

这会清除当前的 OpenGL 上下文,即帧缓冲区,您将拥有 2 个或使用我不熟悉的 SDL2 渲染器。 然后你会交换缓冲区,然后重复。 (与this architecture proposal I am relying on 完美契合)

因此,要么您必须以某种方式从库中重播第二帧的绘制命令,要么您也可以禁用双帧缓冲,至少对于 OpenGL 后端,通过

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);

(有关其他 OpenGL SDL2 设置代码,请参阅this GitHub repository with a general helper class of mine

【讨论】:

以上是关于SDL2:如何在不清除屏幕的情况下进行渲染的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用值的情况下清除 TextInput

如何在不应用盐堆栈的情况下渲染和转储文件 sls

安卓——SurfaceView。在不清除屏幕的情况下更新。 (注:我是菜鸟)

如何在不注销的情况下清除所有会话变量

如何在不清除 GoogleMap 的情况下更新多个位置

如何在不保留任何到期时间的情况下清除 javascript 中的 cookie [重复]