我试图通过将纹理组合到数组纹理中来优化我的代码(我意识到我不能使用纹理图集,因为大多数纹理都是重复的(在地面上等))。我在PyGame和PyOpenGL工作,我之前从未使用过着色器。是否可以使用glBindTexture(GL_TEXTURE_2D_ARRAY, texname)
绑定单个数组纹理并使用3d纹理坐标或其他东西来访问不同的图层?没有着色器甚至可能吗?
目前,我使用此函数调用每个纹理的glDrawArrays:
def DRAW(im, array):
glBindTexture(GL_TEXTURE_2D,im)
glTexCoordPointer(2, GL_FLOAT, 32, array)
glNormalPointer(GL_FLOAT, 32, array[2:])
glVertexPointer(3, GL_FLOAT, 32, array[5:])
glDrawArrays(GL_QUADS,0,len(array)/8)
答案 0 :(得分:4)
无需着色器即可使用纹理数组。他们从未成为固定功能管道的一部分。 GL 中没有GL_TEXTURE_2D_ARRAY
启用位。
固定功能片段处理在OpenGL 4.5 compatibility profile specification.的第16节中指定。第16.2节规定:
只有着色器支持数组和多重采样纹理,可能不支持 启用固定功能纹理。
在原始GL_EXT_texture_array扩展程序中,您会找到以下声明:
(2)固定功能片段是否应支持纹理数组 处理?
决议:否;它被认为不值得付出努力。 固定功能 允许应用程序可以轻松支持片段处理 启用或禁用
TEXTURE_1D_ARRAY_EXT
或TEXTURE_2D_ARRAY_EXT
。注意,对于固定功能片段处理,会有 问题 带有阴影的二维数组纹理的纹理查找 映射。鉴于所有纹理查找都是投影的,总共五个 将需要坐标分量(s,t,层,深度,q)。
(3)如果支持固定功能,应该是层数(T或 R)是 在投影纹理查找中除以Q?
已解决:此扩展程序中不需要解析它,但它 会是个问题。可能存在应用程序的情况 想要分裂(处理R或多或少像S / T);可能有 其他不需要划分的情况。许多开发者都不会 小心,甚至可能不知道Q坐标用于什么!该 默认值1.0允许不关心投影的应用程序 查找只是忽略了这一事实。
对于可编程片段着色,应用程序可以对其进行编码 无论哪种方式 并使用非投影查找。在某种程度上除以Q为 投射查找是免费的"或者"便宜"在OpenGL硬件上,编译器 能够识别计算中的投影模式 适当地协调和生成代码。
当数组纹理被提升为OpenGL核心功能时,这没有改变。
答案 1 :(得分:3)
正如@derhass在答案中的规范引用所示,如果没有着色器,则不支持数组纹理。
但是,你可以使用3D纹理做同样的事情。您将每个纹理存储在3D纹理的图层中。然后像往常一样使用前2个纹理坐标,以确定纹理图像中的位置。第三个纹理坐标用于选择3D纹理中的图层。
要将图像加载到3D纹理,请使用glTexSubImage3D()
。例如,假设您的纹理大小为512x512,并且您想要加载纹理索引20:
glTexSubImage3D(GL_TEXTURE_3D, 0,
0, 0, 20, 512, 512, 1,
GL_RGBA, GL_UNSIGNED_BYTE, data);
唯一稍微棘手的部分是正确计算第三个纹理坐标,因为纹理坐标是标准化的浮点数。特别是如果你使用线性采样,你必须准确地击中一个图层的中心,否则你会得到一个混合的图像。
如果3D纹理中有n
个图层,则图层k
的纹理坐标为:
(k + 0.5f) / n
例如,对于n = 4
,4层的结果纹理坐标为:
0.125f
0.375f
0.625f
0.875f
注意值如何间隔0.25f,如您所料,并且对称放置在区间[0.0f, 1.0f]
使用3D纹理的一个缺点是它们具有较小的尺寸限制。使用此方法,请确保不要超过MAX_3D_TEXTURE_SIZE
。
我鼓励您学习使用着色器。起初它可能看起来有些令人生畏,因为它对于非常简单的用例肯定更有用。但是你会发现,一旦掌握了它,它们实际上会使你的功能变得更加复杂。编写GLSL代码以完全按照您的意愿执行操作通常要简单得多,而不是试图弄清楚如何正确设置几十个状态值以获得所需的结果。当然,着色器允许您实现在固定管道中根本不可能实现的功能。