OpenGL ES 2.0 中具有不同纹理的许多对象
Posted
技术标签:
【中文标题】OpenGL ES 2.0 中具有不同纹理的许多对象【英文标题】:Many objects with different textures in OpenGL ES 2.0 【发布时间】:2011-11-22 16:18:28 【问题描述】:我是 OpenGL ES 2.0 的新手,它具有可编程管道,我正在移植应用程序,该应用程序可以渲染许多具有不同纹理的对象。 所以这将需要为每个对象调用 glDrawArrays 并在调用之间更改纹理?或者还有另一种方法可以通过单个 glDrawArrays 调用绘制具有不同纹理的多个对象?
我之所以这么问,是因为我注意到当尝试使用 glDrawArrays 而不是 glBegin/glEnd 与“桌面”OpenGL 一起使用时,对 glDrawArrays 的调用要慢得多。
我正在渲染地图图块,因此所有纹理都是不同的,它们是动态加载的(不能像加载一次一样花太多时间处理它们)而且非常大(高达 512x512)。
【问题讨论】:
【参考方案1】:不幸的是,没有一种简单的内置方法可以在单个批处理 glDrawArrays
调用中应用多个纹理。然而,有一些方法可以让它发挥作用。最常见的策略之一被称为纹理图集。基本上,这个想法是将许多图像组合成一个更大的纹理,每个子图像占据纹理的一个已知子矩形。当您将它们映射到您的图元上时,您需要提供与您要显示的图像相对应的子矩形的坐标。
纹理图集可以在很多情况下使用,但设置起来可能相对复杂。如果您不必为每个对象制作不同的纹理,首先要尝试的是简单地将尽可能多的使用相同纹理的图元批处理在一起。
如果你没有使用 OpenGL ES,你也可以考虑使用纹理数组,如果你的纹理都是相同的大小。
【讨论】:
谢谢。不幸的是,我认为我不能使用 atlas,因为我的纹理非常大(256x256 - 512x512),并且将 4 个纹理合二为一不会有太大区别(但需要一些时间来创建更大的纹理)。是否可以将不同的纹理绑定到与设备一样多的纹理单元,然后在着色器中根据顶点属性选择纹理单元? 是的,通过将一个纹理绑定到每个插槽然后为每个插槽提供纹理坐标并在着色器中混合它们,或者通过让纹理坐标遵循某种模式来实现这一点相当简单这使您可以将它们映射到特定的插槽(例如,如果纹理坐标在 0.0 和 1.0 之间,则适用于插槽 0 中的纹理,如果在 10.0 和 11.0 之间,则适用于插槽 1 中的纹理,依此类推) .我没有提到这一点,因为它将纹理的数量限制在一个相当小的数量。不过,就您而言,这可能是最好的选择。 谢谢!我只需要学习 GLSL .. 我是否理解正确,在 GLSL 中不能有“采样器数组”,并且每个纹理都将作为单独的统一出现,所以我需要一堆 IF 来选择合适的插槽而不仅仅是纹理[我]? 你是对的,很遗憾,glsl 不支持采样器数组,if
语句链可能是你能做的最好的。以上是关于OpenGL ES 2.0 中具有不同纹理的许多对象的主要内容,如果未能解决你的问题,请参考以下文章
OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)
ETC1 纹理压缩保证在 OpenGL ES 2.0 Android 设备上可用?
OPENGL ES 2.0 知识串讲 ——OPENGL ES 详解III(纹理)