2009-12-03 79 views
1

在我的2D游戏中,我需要可能是任意大的纹理,可以是NPOT和非正方形。通过GL_QUADS矩形(四个QUAD角映射到四个纹理角落): 他们永远只能映射到一个一种原始的。有时纹理矩阵在绘制之前已经缩放。模拟旧的GPU的大NPOT纹理

我希望我的游戏能够在任何地方工作,即使是只允许小型和/或POT纹理的旧/便宜的视频卡。 我应该使用什么解决方案?应该...

  • 很容易实现
  • 有非常不错的表现。

目前我知道的下列选项:

  • 使用一个extensionGL_TEXTURE_RECTANGLE_{EXT,NV,ARB}所以NPOT工作在不支持原生OGL2.0纹理NPOT卡。

    • 这并没有解决“大质地”的问题。
    • 它在PC上的最大数量的工作吗?那么支持原生OGL2.0 NPOT的视频卡也支持这些扩展?
    • 要使用的三种版本EXT/NV/ARB的?
  • 将BigTextures作为一束小小的POT纹理切片实现,这些切片仔细地绘制在几个相邻的QUAD上。这既提供了“大纹理”和NPOT,但它有点困难和限制。

  • 实现我的NPOT纹理作为POT纹理填充透明的右侧和底部。会浪费记忆并使纹理平铺更难一点,并且不能解决“质地粗糙”问题。
  • 使用一些预制的解决方案。

有问题的显卡的一个例子是移动式英特尔945GM Express芯片组这似乎不支持本地NPOT。

更新:我结束了使用第三个选项。很酷的是,我能够使用glTexSubImage2D,而不是手动填充纹理。这太疯狂了。是的,它不提供“大质感”支持,但是我意识到我的目标GPU支持高达2048x2048,这对我来说已经足够好了。哦,GL_TEXTURE_RECTANGLE_EXT甚至不支持在移动式英特尔945GM Express芯片组

回答

2

如果你所有的UV坐标都在[0,1]范围内,你可以将你的NPOT纹理打包成texture atlas

由于你的纹理可以是任意大的,我可能会去建议将NPOT纹理(和相应的四边形)分割成不大于硬件可以处理的POT块。如果您选择此解决方案,请记住将自动换行模式设置为GL_CLAMP_TO_EDGE,以最大限度地减少边缘处的渲染假象(如果需要缩小,您仍然可以获得一些)。

如果卡不支持OpenGL 2。0 NPOT纹理,它们不太可能支持GL_TEXTURE_RECTANGLE_{EXT,NV,ARB}

0

那么你最好使用每个级别的回退。

如果你的卡支持大纹理但只有POT,那么你可以分配一个2的下一个幂的纹理。即为一个1024x768纹理分配一个1024x1024并将其拉伸到完整的纹理大小。这将很好地平铺,你不应该注意到拉伸操作失真严重。

如果你的卡片不能做大纹理,你有问题。唯一真正的解决方案是细分三角形并使用大量较小的纹理。正如你所说,这不是最好的解决方案,因为这样做非常密集。实际上,在不支持这种纹理的硬件上,您可能会发现额外的顶点负载也会削弱性能。在这种情况下,您可能只需将纹理缩放到较低的细节版本即可。它不是一个很好的解决方案,但它可能是您唯一的选择。你唯一的选择是不支持这种卡...

0

作为一个经验法则,我会坚持使所有的纹理POT。速度更快,您不必担心兼容性问题。请记住,您的纹理尺寸不必与其显示的尺寸具有1对1的相关性 - 您可以在图像编辑器中将NPOT纹理拉伸到POT尺寸,并以正确的尺寸显示它。纹理地图集也是一件好事,他们减少了你做的纹理切换的数量,可能会很慢。

对于大型纹理,您只能选择将其分割为较小的纹理。这是一个严格的硬件限制,因此您需要将一些工作分解为您的纹理(即时或预先)。

0

对于那些NPOT扩展,从内存来看,它们都非常相似,并且简单地表明对两个纹理的功率的正常限制没有被强制执行。你可以看看他们在OpenGL Extension Registry

记忆中的三个分机实际上是相同的延伸,它是由NVIDIA推出的GL_ NV_ texture_ non_ power_ of_二,之前被接受为架构评审委员会(这是GL_ ARB_ texture_ non_ power_ of_ two)。一旦它被接受到OpenGL 2.0中,它就会变成GL_EXT_ texture_non_power_of_ two。我在某些细节上可能会出错,但是您有一个新的OpenGL扩展的生命周期。

您当然可以自由地检查这些扩展的存在并利用它们在现有位置。可能有一些支持OpenGL2.0的前期卡,但不是很多,所以你需要一个额外的备份策略。

想到两个选项。

  • 对于不重复的纹理,只需将剩余空间消除并确保设置纹理坐标,以免它们显示出来。
  • 拉伸纹理,使其两个幂。