假设我们有一个纹理(在本例中为 8x8 像素),我们想将其用作精灵表。其中一个子图像(精灵)是纹理内部 4x3 的子区域,如下图所示:
(显示了四个角的归一化纹理坐标)
现在,基本上有两种方法可以将纹理坐标分配给 4px x 3px 大小的四边形,以便它有效地成为我们正在寻找的精灵;第一个也是最直接的方法是在子区域的角落对纹理进行采样:
// Texture coordinates
GLfloat sMin = (xIndex0 ) / imageWidth;
GLfloat sMax = (xIndex0 + subregionWidth ) / imageWidth;
GLfloat tMin = (yIndex0 ) / imageHeight;
GLfloat tMax = (yIndex0 + subregionHeight) / imageHeight;
虽然当第一次实现这个方法时,ca。2010 年,我意识到精灵看起来有点“扭曲”。经过一番搜索,我在 cocos2d 论坛上看到了一篇文章,解释了在渲染精灵时采样纹理的“正确方法”是这样的:
// Texture coordinates
GLfloat sMin = (xIndex0 + 0.5) / imageWidth;
GLfloat sMax = (xIndex0 + subregionWidth - 0.5) / imageWidth;
GLfloat tMin = (yIndex0 + 0.5) / imageHeight;
GLfloat tMax = (yIndex0 + subregionHeight - 0.5) / imageHeight;
...在修复了我的代码之后,我高兴了一阵子。但在此过程中的某个地方,我相信是在 iOS 5 推出前后,我开始觉得我的精灵看起来不太好。经过一些测试,我切换回“蓝色”方法(第二张图片),现在它们看起来不错,但并非总是如此。
我是疯了,还是与 GL ES 纹理映射相关的 iOS 5 发生了一些变化?也许我做错了什么?(例如,顶点位置坐标略微偏离?错误的纹理设置参数?)但是我的代码库没有改变,所以也许我从一开始就做错了什么......?
我的意思是,至少在我的代码中,感觉好像“红色”方法过去是正确的,但现在“蓝色”方法给出了更好的结果。
现在,我的游戏看起来不错,但我觉得我迟早必须修复一些错误的东西......
有什么想法/经验/意见吗?
附录
为了渲染上面的精灵,我会在正交投影中绘制一个 4x3 的四边形,每个顶点都分配了前面提到的代码中隐含的纹理坐标,如下所示:
// Top-Left Vertex
{ sMin, tMin };
// Bottom-Left Vertex
{ sMin, tMax };
// Top-Right Vertex
{ sMax, tMin };
// Bottom-right Vertex
{ sMax, tMax };
原始四边形是从 (-0.5, -0.5) 到 (+0.5, +0.5) 创建的;即它是屏幕中心的一个单位正方形,然后缩放到子区域的大小(在本例中为 4x3),其中心位于整数 (x,y) 坐标处。我闻到这也有关系,尤其是当宽度、高度或两者都不均匀时?
附录 2
我也找到了这篇文章,但我仍在尝试将它放在一起(这里是凌晨 4:00) http://www.mindcontrol.org/~hplus/graphics/opengl-pixel-perfect.html