【问题标题】:How to determine an OpenGL texture's size in texels?如何确定 OpenGL 纹理在纹素中的大小?
【发布时间】:2010-01-08 10:44:29
【问题描述】:

我知道这是一个微不足道的问题,但从glGet() 的文档开始,我还没有找到任何似乎有帮助的信息。我将我的纹理用作精灵,因此以纹素/像素为单位跟踪它们的大小至关重要。

当我使用glTexImage2D() 创建纹理时,我需要将像素数据数组的大小传递给它。但是 OpenGL 是否将它存储在任何地方,还是我必须在我的代码中跟踪它们? (这感觉很尴尬,因为客户端代码仍然可以使用 glTexImage2D() / glTexSubImage2D() / glCopyTexImage2D() 等调用覆盖纹理,而不会相应地更改大小,从而导致视觉失真。)

【问题讨论】:

    标签: opengl textures


    【解决方案1】:

    正如 Bahbar 所说,glGetTexLevelParameteri 可用于查询GL_TEXTURE_WIDTH。但是,我强烈建议不要将其用作一般方法。一方面,您可以使用 glGet* 调用来停止管道,因为驱动程序必须让 GPU 完成它正在做的事情,弄清楚您问了什么,然后返回答案。结果是巨大的性能损失。

    因此,您最好在自己的代码中管理这样的状态。大概你有一个带有纹理句柄的Sprite 类(或结构或等价物)。用更多的字节来跟踪宽度和高度并没有什么意义,它可以让您不必点击驱动程序或 GPU 来获取信息。

    至于glTeSubImage*,这是关于何时以及如何更新纹理的政策决定。

    【讨论】:

    • 虽然 Gets 理论上可以刷新管道,但我严重怀疑您是否会找到实际刷新的最新实现。如今,大多数驱动程序都存储了绝大多数状态客户端。
    • 我可以看到像纹理尺寸这样简单的东西可以在客户端缓存,但其他glGet* 查询可能取决于要渲染的东西来回答。并且可以说,将纹理元数据保留在对象中是更好的设计(并且直接访问数据成员比调用驱动程序更快)。无论如何,我读过的几乎所有谈论的书都会导致停滞不前。对于哪些驱动程序缓存哪些状态信息,您是否有任何参考?那会很方便。
    • 谢谢 - 这完全有道理。我的冲突就在这一点上,为我的框架编写功能意味着客户不会支持它。我猜到目前为止,这些细节都已记录在案,可以合理地预期,如果客户想要使用该框架并提供所需的功能,他们将不会((觉得他们)不得不)绕过它.
    • 是的,最好自己保留状态影子。但是,需要管道刷新的 Get 正是您自己无法跟踪的。这就是为什么他们需要冲洗。我没有公开的参考资料,但话又说回来,测试起来并不难。在管道里放一个很长的操作,调用一个Get,看看需要多长时间。
    • 我应该补充一点,倾向于巨大的状态(例如纹理数据)是一个例外。这些很少在客户端缓存。
    【解决方案2】:

    如果你真的想依赖GL,请使用

    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &param)
    

    也就是说,我不确定客户端代码在您的上下文中意味着什么,但是如果您希望编写允许您的客户直接操作您自己的状态的中间件,那么您就有麻烦了。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2011-04-20
    • 2023-04-08
    相关资源
    最近更新 更多