【问题标题】:Is it possible to create a Texture2D_Array off several Texture2D objs in OpenGL?是否可以在 OpenGL 中创建多个 Texture2D obj 的 Texture2D 数组?
【发布时间】:2015-10-22 23:35:26
【问题描述】:

关于我的打算:

我有一个图像堆栈,出于多种原因,我需要它们都是单独的 2D 纹理。然后,对于一些组合显示器,我需要将其中的 5-10 个融合到一个显示器中(非常适合 Texture2d_Array)。我的想法是获取已经上传的 2D 纹理并将它们形成一个 Texture2d 数组。 OpenGL给我的功能可以实现吗?

备注:我想避免重新加载图像数据,出于效率原因,已经创建的 mip-maps 非常有用,应该保留。因此,诸如“从 Tex2d 获取数据并创建新的 Tex2Darray 层”之类的操作是愚蠢的。

如果失败,我的后备方案是在我的 Shader 中放置大约 10 个采样器,然后在显示之前将它们相加/平均。

【问题讨论】:

    标签: c# c++ opengl textures texture2d


    【解决方案1】:

    一切皆有可能!嗯,几乎任何东西......

    根据您可用的 OpenGL 版本,您可以考虑几个选项。这是如果您确实需要复制数据。当然,目前最好的选择是首先将纹理数据加载到数组纹理中,并避免额外的副本。

    glCopyImageSubData()

    glCopyImageSubData() 与您想要的功能非常直接匹配。唯一的缺点是它仅在 OpenGL 4.3 及更高版本中可用。

    glCopyTexImage2D()

    我只是为了完整起见而提到这一点,以防有人查看此答案以获得稍微不同的用例。 glCopyTexImage2D() 一般可以通过将源纹理设置为 FBO 附件来复制纹理数据。

    但事实证明它不支持GL_TEXTURE_2D_ARRAY,因此不能用于从常规纹理复制到数组纹理。另一个方向会起作用。

    glBlitFramebuffer()

    glBlitFramebuffer() 在 OpenGL 3.0 及更高版本中可用,可用于复制几乎任何类型的帧缓冲区/纹理数据。

    要从一个纹理复制到另一个纹理,您需要创建两个 FBO。您将其中一个绑定为GL_READ_FRAMEBUFFER,并将源纹理附加到它。您将第二个绑定为GL_DRAW_FRAMEBUFFER,并将目标纹理附加到它。然后你打电话给glBlitFramebuffer()

    【讨论】:

    • 感谢您的回答。不过,我不确定我能从中借到什么。也许我可以创建不完整的 Tedxture2D-Arrays,其中只有 50 层的第 0..4 层设置了有效数据。那可能吗?它会占用内存吗(它是关于 DICOM,所以图像有 2k² 甚至更大)?
    【解决方案2】:

    您可以通过结合使用以下两种技术来绕过您的限制,将每个纹理放在单独的 2D 纹理中:

    glTextureView()

    创建单个纹理数组,然后使用glTextureView()(OpenGL 4.3+ 中的核心)创建单独的 2D 纹理,其行为与您当前存在的纹理完全相同。与Reto Koradi 概述的函数相比,不同之处在于纹理视图不会在 GPU 上复制内存,这可能会更高效,具体取决于您的需要。

    但是,您不能使用此功能将多个现有 2D 纹理一起映射到您请求的新 2D 数组中。原因很简单,因为在 OpenGL 中对 GPU 内存映射没有足够的控制,尽管这在理论上至少在某些情况下是可能的(假设每个切片的大小可以除以 GPU 内存控制器的页面大小) )。

    纹理图集

    您不一定需要为每个特殊用例创建具有精确的 2D 纹理切片集的新纹理数组,而是将包含所有纹理的大型纹理数组绑定到单个(或多个)采样器( s) 并将其与切片索引数组(仅选择您需要的纹理)一起传递给您的着色器。 此选项显然只有在您愿意/能够更改着色器源代码时才可行。

    【讨论】:

    • 谢谢。所以我读到: nTex2D -> Tex2D-Array 是不可能的,但是 / Tex2D-Array -> nTex2D 是可能的。!?反过来会更好,因为我的瓶颈(我应该写过)是内存。我的纹理是 2k² 或其他 5k*4k 的 Dicom 图像,加载 50 个 2k² 图像肯定会爆卡。所以我试图找到可行的方法来在内存中加载尽可能少的纹理。
    • 如果所有纹理的总内存大小有问题,您可以检查GL_ARB_sparse_texture 在您的目标平台上是否可用。如果是这样,您可以选择从视频内存中删除任何纹理切片甚至 mipmap 级别,并在系统内存中保留备份。这样,您就可以完全控制纹理流式传输策略,以便在需要时提供数据。请注意,从纯内存大小的角度来看,纹理数组没有任何好处,因此同样适用于简单的 2D 纹理列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 2014-09-10
    • 2011-10-29
    • 1970-01-01
    • 2017-12-09
    相关资源
    最近更新 更多