在我的2D游戏中,我需要可以任意大的纹理,可以是NPOT和非方形。 它们只被映射到一种基元:通过GL_QUADS的矩形(四个QUAD角被映射到四个纹理角)。有时纹理矩阵在绘制之前已经缩放。
我希望我的游戏能够在任何地方工作,即使是只允许小型和/或POT纹理的旧/便宜的视频卡。 我应该使用什么解决方案?它应该......
目前我知道以下选项:
使用像GL_TEXTURE_RECTANGLE_{EXT,NV,ARB}
这样的extension,因此NPOT适用于不支持OGL2.0本机NPOT纹理的卡片。
将BigTextures实现为一堆小的POT纹理切片,它们是在几个相邻的QUAD上精心绘制的。这两者都提供了“大纹理”和NPOT,但它有点困难和限制。
有问题的显卡的一个例子是移动式英特尔®945GM高速芯片组,它似乎不支持原生NPOT。
更新:我最终使用了第三个选项。很酷的是,我能够使用glTexSubImage2D,而不是手动填充纹理。这很疯狂。是的,它不提供“大纹理”支持,但我意识到我的目标GPU支持高达2048x2048,这对我来说已经足够了。哦,移动式英特尔®945GM高速芯片组甚至不支持GL_TEXTURE_RECTANGLE_EXT。
答案 0 :(得分:2)
如果所有的UV坐标都在[0,1]范围内,您可以将NPOT纹理打包成texture atlas。
由于纹理可以任意大,我可能会建议将NPOT纹理(和相应的四边形)分割成不大于硬件可以处理的POT块。如果您选择此解决方案,请记住将包装模式设置为GL_CLAMP_TO_EDGE以最小化边缘处的渲染工件(如果您需要缩小,您仍然可以获得一些)。
如果卡不支持OpenGL 2.0 NPOT纹理,则它们不太可能支持GL_TEXTURE_RECTANGLE_{EXT,NV,ARB}
。
答案 1 :(得分:0)
你最好每个级别使用后备。
如果您的卡支持大纹理但只支持POT,那么您只需分配下一个2的幂的纹理。即对于1024x768纹理,分配1024x1024并将其拉伸到完整纹理大小。这样可以很好地平铺,你不应该注意到拉伸操作的失真。
如果您的卡无法做大纹理,则表示您遇到问题。唯一真正的解决方案是细分三角形并使用大量较小的纹理。正如你所说,这不是最好的解决方案,因为这样做非常密集。事实上,在无法支持此类纹理的硬件上,您可能会发现额外的顶点负载也会削弱性能。在这种情况下,您可能只需将纹理缩放回较低的细节版本。它不是一个很好的解决方案,但它可能是您唯一的选择。你唯一的另一个选择是不支持这样的卡......
答案 2 :(得分:0)
根据经验,我会坚持制作所有纹理POT。它更快,您不必担心兼容性。请记住,您的纹理大小不必与其显示的大小具有1对1的相关性 - 您可以在图像编辑器中将NPOT纹理拉伸到POT大小,并以正确的大小显示它。纹理地图集也是一件好事;它们减少了你做的纹理切换量,这可能会很慢。
对于大型纹理,您只能选择将它们拆分为较小的纹理。这是一个严格的硬件限制,因此你需要做一些工作来分割你的纹理(动态或预先)。
答案 3 :(得分:0)
关于那些NPOT扩展,从内存中它们都非常相似,只是表明不强制对两个纹理的幂的正常限制。您可以在OpenGL Extension Registry
中查找它们从内存来看,这三个扩展实际上是SAME扩展,它被NVidia引入为GL_ NV_ texture_non_power_ of_2,然后被架构审查委员会(即GL_ ARB_ texture_ non_ power_ of_ two)接受。一旦被OpenGL 2.0接受,它将成为GL_ EXT_ texture_ non_ power_ of_2。我可能在其中一些细节上错了,但是你有一个新的OpenGL扩展的生命周期。
您当然可以自由检查是否存在这些扩展,并在存在时利用它们。可能有一些支持它的预OpenGL2.0卡,但并不多,所以你需要一个额外的备份策略。
有两种选择。