65.9K
CodeProject 正在变化。 阅读更多。
Home

OpenGL ES:Texture2D 和二次幂

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (1投票)

2009年7月19日

CPOL

2分钟阅读

viewsIcon

40972

downloadIcon

344

如何调整你的 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 类。完整的源代码,包括 Texture2DTextureManager 以及我的 C++ iPhone 引擎中使用的任何其他类,可以在 http://code.google.com/p/djinnengine 找到。

希望这篇内容对您有所帮助!如果任何人有任何有用的信息,请随时评论!

祝大家编码愉快!

历史

  • 2009 年 7 月 19 日:初始发布
© . All rights reserved.