如何经常实施闪烁的插入符号?

时间:2017-04-22 15:26:35

标签: user-interface opengl cross-platform caret

我正在尝试实现一个跨平台的UI库,它尽可能少地占用系统资源。我正在考虑使用我自己的软件渲染器或opengl。

对于静止控制,一切都很好,我只能在需要时重新粉刷。然而,当涉及到实现动画时,尤其是动画闪烁的插入符号,例如崇高文本中的“阶段”插入符号,我看不到平衡资源使用和性能的简单方法。

对于闪烁的插入符号,需要非常频繁地重绘插入符号(至少每秒15-20次,我猜)。一方面,软件渲染器支持部分重绘,但实际上太慢了(大的重绘区域为3-4 fps,比如1000x800,这使得无法实现动画)。另一方面,据我所知,opengl不支持部分重绘,这意味着整个屏幕需要不断以15-20 fps的速度渲染。

所以我的问题是:

  1. 如何在各种UI系统中实现插入符号?
  2. 有没有办法让opengl只渲染到屏幕的一部分?
    • 我知道glViewport可以渲染到屏幕的一部分,但是由于双缓冲或其他东西,屏幕的其余部分不能保持原样。这样我仍然需要再次渲染整个屏幕。

1 个答案:

答案 0 :(得分:1)

首先你需要问问自己。 我是否真的需要部分重绘屏幕?

OpenGL或更好的表示GPU可以轻松绘制数千个三角形。因此,在您开始摆弄部分重绘屏幕之前,您应该改为进行基准测试,看看它是否值得研究。

但这并不意味着你必须无休止地重绘屏幕。您仍然可以在发生更改时重绘它。

因此,如果光标每500毫秒闪烁一次,则每500毫秒重绘一次。如果您正在运行动画,则在播放该动画时不断重绘(或者每次动画执行需要重绘的更改时)。

这就是Chrome的功能。如果您打开开发人员工具( F12 )并转到时间轴选项卡,则可以看到此信息。

看一下下面的截图。时间轴的第一行显示了Chrome重绘窗口的频率。

  • 第一部分显示了很多不断重绘的内容。 这是因为我在页面上滚动。
  • 最后一节显示每隔500毫秒进行一次重绘。 光标在文本框中闪烁。

在新标签页中打开图片,以便更好地查看正在进行的操作。

请注意,它并不能说明Chrome是完全重绘窗口还是只重绘窗口的那些部分。它只是显示重绘的频率。

通过双缓冲和部分重绘来规避问题。然后你可以改为绘制一个帧缓冲对象。现在,您可以根据需要使用glScissor()。如果你有各种静态的东西,只有一些动态的东西。然后你可以拥有多个帧缓冲对象,只绘制一次静态内容并不断更新包含动态内容的帧缓冲区。

然而(并且我不能强调这一点)基准并检查是否需要这样做。拥有两个帧缓冲对象可能比仅重新绘制所有内容更昂贵。同样地说,为每个矩形设置一个缓冲区,而不是将所有矩形打包在一个缓冲区中。

最后举一个例子,让我们来NanoGUI (a minimalistic GUI library for OpenGL)。 NanoGUI不断重绘屏幕。 问题 只是不断重新绘制屏幕,​​现在您需要一个系统来发布重绘。现在在标签上调用setText()需要回调并告诉窗口重绘。现在,如果添加标签的父面板不可见,该怎么办?然后setText()刚刚发布了一个冗余的屏幕重绘。

我想说的是,如果你有一个系统来重新绘制屏幕。那么这可能更容易出错。因此,除非连续重绘是个问题,否则这绝对是一个更优的起点。