OpenGL ES:Texture2D 和二次幂





3.00/5 (1投票)
如何调整你的 Texture2D 对象,以便在你的 OpenGL ES 项目中使用任意大小的纹理。
引言
正如大家可能已经发现的,OpenGL ES 不喜欢非 2 的幂次方的纹理,而且我真的不想在将纹理加载到游戏中之前,强制所有纹理都为 2 的幂次方。这给我带来了一个需要在代码中解决的问题。
为了真正理解 OpenGL 中的纹理映射,我不得不做了大量的研究。说实话,我仍然没有完全理解它,尽管有一些文章确实很好地解释了这些内容。其中一篇文章名为“从头开始的 OpenGL ES”,可以在 http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html 找到。请查阅第 6 章关于纹理映射的内容。
我面临的问题是,只有 2 的幂次方才能在 OpenGL ES 中使用,那么如果纹理加载进来是 40 x 40 纹理(例如),我们如何将其转换为 2 的幂次方呢?有很多方法可以做到这一点,但我选择了 Apple 为他们的 Texture 对象所使用的方法,并将其调整以适应我的代码。他们提出了以下方法来转换宽度和高度
//Adjust the width and height to be a power of two.
if(( _width != 1) && ( _width & (_width - 1) )
{
i = 1;
while( (sizeToFit ? 2 * i : i) < _width)
i *= 2;
_width = i;
}
if(( _height != 1) && ( _height & (_height - 1) )
{
i = 1;
while( (sizeToFit ? 2 * i : i) < _height)
i *= 2;
_height = i;
}
代码的第一部分将转换宽度为 2 的幂次方,然后转换高度。由于纹理将被拉伸,而不会缩小,Apple 必须找到一种方法来缩小纹理,如果它变得比由 kMaxTextureSize
= 1024 定义的最大纹理大小更长。以下代码将执行此操作
// scale down an image greater than the max texture size
while((_width > kMaxTextureSize) || (_height > kMaxTextureSize))
{
_width /= 2;
_height /= 2;
transform = CGAffineTransformScale(transform, 0.5, 0.5);
imageSize.x *= 0.5;
imageSize.y *= 0.5;
}
“transform
” 仅仅是一个 CGAffineTransform
(Core Graphics)。所以,现在你已经浏览了代码,还记得文章中 Jeff 谈论 S 和 T 坐标吗?我们将这样处理它们
_maxS = imageSize.x / (float)_width;
_maxT = imageSize.y / (float)_height;
这将给我们一个介于 0 和 1 之间的数字,可以用于我们的 textureCoordinates[]
进行绘制。这应该只渲染纹理中包含我们希望显示到屏幕上的数据的部分,而不是我们为了确保它是 2 的幂次方而添加的填充。
虽然我仍在学习 OpenGL,但我认为很多人会对以下解决方案感兴趣……特别是如果你像我一样,在开发 iPhone OpenGL 应用程序时,放弃了 Apple 的 Texture2D
类。完整的源代码,包括 Texture2D
、TextureManager
以及我的 C++ iPhone 引擎中使用的任何其他类,可以在 http://code.google.com/p/djinnengine 找到。
希望这篇内容对您有所帮助!如果任何人有任何有用的信息,请随时评论!
祝大家编码愉快!
历史
- 2009 年 7 月 19 日:初始发布