【问题标题】:OpenGL + SDL_TTF: texture index recyclingOpenGL + SDL_TTF:纹理索引回收
【发布时间】:2016-07-10 17:35:19
【问题描述】:

我目前正在将一堆应用程序从 SDL2 渲染(内部使用 OpenGL)迁移到“纯”OpenGL 渲染。在这项工作中,我弄清楚了如何将纹理上传到 GPU,并了解到每个纹理都有一个索引。

为了渲染文本,我使用了 SDL_TTF 函数,基本上可以将纹理上传到 GPU,描绘一些文本。我正在迁移的大多数应用程序的文本并不繁重,但我注意到它们可能存在问题。

想象一个应用程序接受用户文本输入并显示在屏幕上:每次击键都会生成一个包含所有输入文本的新纹理(与相同功能相关的任何其他先前纹理都将被删除)。所以,要写“Hello”,我们会得到五个纹理:“H”、“He”、“Hel”、“Hell”,最后是“Hello”。如前所述,每个“以前的”纹理(在这种情况下从“H”到“Hell”)都将被删除,并且只保留“Hello”的内存。

不过,在文本繁重的应用程序中(例如,使用这种方法来放置游戏的分数,做得很糟糕以至于您为每一帧生成一个新纹理)会上传和删除大量纹理,并且纹理索引会继续增长。

我的主要问题是:OpenGL 会回收这些索引,还是会用完数字并崩溃?。

PS:我知道可以将所有 TTF 字符打包到图集中,然后得到我需要的字母。我现在不想研究这个,除非我目前的方法很危险(这个图集有点像旧的位图字体)。

PS2:我也知道不断更改纹理并不完全是高性能的(GPU 方面),但这些应用程序在图形上并不具有挑战性,并且在旧系统中具有良好的性能。

【问题讨论】:

  • 如果您担心,为什么不直接替换纹理数据而不重新创建纹理 ID/名称? IE。再次glTexImage,或者分配大纹理并稍后替换其部分数据。
  • 是的,是的,这正是我计划在未来做的事情:)。看,所有可能改变的文本(例如,前面提到的游戏中的分数标记或提示框)都封装在管理其资源删除的类中(这些通常有很长的生命周期,不会消耗很多索引)。我可以很好地扩展它们以“替换”当前纹理,但我不确定我周围的一些遗留代码。非常感谢。

标签: c++ opengl sdl-ttf


【解决方案1】:

OpenGL 对象由 OpenGL 规范所称的“名称”来引用(编程中其他常用的术语是“句柄”或“id”/“标识符”)。当第一次绑定新名称时(使用glBind…),会创建相应的 OpenGL 对象(纹理、缓冲区等);一些 OpenGL 函数创建对象并将名称返回给它 (glCreate…)。删除(有效)名称后(使用glDelete…),一旦释放了对它的最后一个内部引用,相应的 OpenGL 对象将被释放。删除名称后(由 OpenGL)可以有效地重用名称,然后引用 不同的 对象。


不要重新发明轮子。使用 OpenGL 进行文本渲染非常复杂,并且(还没有)存在一种完美的方法。然而,有几个库可以解决纹理生成和资源管理问题。帮自己一个忙并使用其中一个。在你的情况下 freetype-gl 将是最好的选择(恕我直言):https://github.com/rougier/freetype-gl


1:我目前正在开发一种新的基于着色器的字形光栅化器,它可以解决大多数已知问题,但还没有完成。

【讨论】:

  • Datenwolf,感谢您的帖子,但它并没有真正回答发布的有关索引回收的问题。现在我对使用新库并不感兴趣,因为我对它是如何工作的有点了解。不过,谢谢,当一切都向南时,我会记住 Rougier :)。
  • @TheMarlboroMan:如果您正确地glDeleteTextures 并取消绑定未使用的纹理名称(最终会发生),纹理名称将被回收。纹理名称不需要是增量的或没有间隙的。
  • 我正在纹理类本身的析构函数中执行 glDeleteTextures,以便该部分清晰。老实说,我什至不知道 OpenGL 中有一个“纹理名称”功能,所以我想我是安全的。您介意用回收信息更新您的答案,以便我解决这个问题吗?
  • 接受的答案。似乎“名称”就是我所说的“索引”,所以现在一切都在控制之中。一旦创建了纹理并获得了索引,那么 glBindTexture(GL_TEXTURE_2D, myindex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixel_data);代码块足以替换纹理?我假设它可以,但现在无法检查。
  • @TheMarlboroMan:是的,调用 glTexImage2D 将完全替换与名称关联的纹理。先前关联的纹理对象将在对其的所有 internal 引用被释放后立即被释放(对象可能仍与在管道中排队的操作相关联),但这发生在幕后。任何资源泄漏都是 OpenGL 实现中的错误。
猜你喜欢
  • 1970-01-01
  • 2013-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
相关资源
最近更新 更多