OpenGL + SDL_TTF:纹理索引回收
OpenGL + SDL_TTF: texture index recycling
我目前正在将大量应用程序从 SDL2 渲染(内部使用 OpenGL)迁移到 "pure" OpenGL 渲染。在这项工作中,我弄清楚了如何将纹理上传到 GPU,并了解到每个纹理都有一个索引。
为了渲染文本,我使用 SDL_TTF 函数,这些函数基本上允许您将纹理上传到 GPU 来描绘一些文本。我正在迁移的大多数应用程序都不是大量的文本,但我注意到它们可能存在问题。
想象一个接受用户文本输入并显示在屏幕上的应用程序:每次击键都会生成一个包含所有输入文本的新纹理(与相同功能相关的任何其他先前纹理都将被删除)。所以,要写 "Hello" 我们会得到五个纹理:"H"、"He"、"Hel"、"Hell" 最后是 "Hello"。如前所述,每个 "previous" 纹理(在本例中为 "H" 到 "Hell")都将被删除,只保留 "Hello" 的内存。
不过,在文本繁重的应用程序中(例如,使用这种方法来放置游戏的分数,做得很糟糕以至于你为每一帧生成一个新的纹理)大量的纹理会被上传和删除,并且纹理指数将继续增长。
我的主要问题是:OpenGL 会回收这些索引还是会 运行 超出数字并崩溃?
PS:我知道可以把所有的TTF字符打包成一个图集,只得到我需要的字母。我现在不想研究它,除非我目前的方法很危险(这个图集有点像旧的位图字体)。
PS2:我也知道不断改变纹理并不完全符合性能(GPU 方面),但这些应用程序在图形上没有挑战性并且在旧系统中具有良好的性能。
OpenGL 对象被 OpenGL 规范称为 "names"(其他编程中常用的术语是 "handle" 或 "id"/"identifier")。当一个新名称第一次被绑定时(使用 glBind…
),一个相应的 OpenGL 对象(纹理、缓冲区等)被创建;一些 OpenGL 函数创建对象和 return 名称 (glCreate…
)。在(有效的)名称被删除后(使用 glDelete…
),一旦对它的最后一个内部引用被释放,相应的 OpenGL 对象将被释放。名称在删除后可以(由 OpenGL)有效地重用,此后引用 不同的 对象。
不要重新发明轮子。使用 OpenGL 进行文本渲染非常复杂,并且(目前¹)还没有一种完美的方法。然而,有几个库可以解决纹理生成和资源管理问题。帮自己一个忙,使用其中一个。在您的情况下,freetype-gl 将是最佳选择(恕我直言):https://github.com/rougier/freetype-gl
1:我目前正在开发一种新的基于着色器的字形光栅器,它可以解决大多数已知问题,但尚未完成。
我目前正在将大量应用程序从 SDL2 渲染(内部使用 OpenGL)迁移到 "pure" OpenGL 渲染。在这项工作中,我弄清楚了如何将纹理上传到 GPU,并了解到每个纹理都有一个索引。
为了渲染文本,我使用 SDL_TTF 函数,这些函数基本上允许您将纹理上传到 GPU 来描绘一些文本。我正在迁移的大多数应用程序都不是大量的文本,但我注意到它们可能存在问题。
想象一个接受用户文本输入并显示在屏幕上的应用程序:每次击键都会生成一个包含所有输入文本的新纹理(与相同功能相关的任何其他先前纹理都将被删除)。所以,要写 "Hello" 我们会得到五个纹理:"H"、"He"、"Hel"、"Hell" 最后是 "Hello"。如前所述,每个 "previous" 纹理(在本例中为 "H" 到 "Hell")都将被删除,只保留 "Hello" 的内存。
不过,在文本繁重的应用程序中(例如,使用这种方法来放置游戏的分数,做得很糟糕以至于你为每一帧生成一个新的纹理)大量的纹理会被上传和删除,并且纹理指数将继续增长。
我的主要问题是:OpenGL 会回收这些索引还是会 运行 超出数字并崩溃?
PS:我知道可以把所有的TTF字符打包成一个图集,只得到我需要的字母。我现在不想研究它,除非我目前的方法很危险(这个图集有点像旧的位图字体)。
PS2:我也知道不断改变纹理并不完全符合性能(GPU 方面),但这些应用程序在图形上没有挑战性并且在旧系统中具有良好的性能。
OpenGL 对象被 OpenGL 规范称为 "names"(其他编程中常用的术语是 "handle" 或 "id"/"identifier")。当一个新名称第一次被绑定时(使用 glBind…
),一个相应的 OpenGL 对象(纹理、缓冲区等)被创建;一些 OpenGL 函数创建对象和 return 名称 (glCreate…
)。在(有效的)名称被删除后(使用 glDelete…
),一旦对它的最后一个内部引用被释放,相应的 OpenGL 对象将被释放。名称在删除后可以(由 OpenGL)有效地重用,此后引用 不同的 对象。
不要重新发明轮子。使用 OpenGL 进行文本渲染非常复杂,并且(目前¹)还没有一种完美的方法。然而,有几个库可以解决纹理生成和资源管理问题。帮自己一个忙,使用其中一个。在您的情况下,freetype-gl 将是最佳选择(恕我直言):https://github.com/rougier/freetype-gl
1:我目前正在开发一种新的基于着色器的字形光栅器,它可以解决大多数已知问题,但尚未完成。