从Atlas获取正确的纹理

我正在编写一个OpenGL ES(2.0)应用程序,并有一个自定义Quad类,为我的精灵绘制一个纹理的四边形。

目前,我把相同尺寸的精灵的纹理放在一个文件或图集中,然后在绘图的时候,我可以简单地指定我想要的框架。 它将基于图集中的纹理数量以及总帧数等来呈现正确的帧。例如:

mySprite.x = 0; mySprite.y = 0; mySprite frame = 1; drawSprite(mySprite); 

纹理图集看起来是这样的:(为了这个问题的简化,在真实的项目中,有200多个纹理排列整齐的行/列,但重要的是有秩序,每个纹理是相同的大小因为这是计算所必需的)。

在这里输入图像说明

所以,在上面的例子中,我可以说,有2列,1行和2个纹理。

所以,如果我指定1作为我的纹理(第二纹理),我的精灵类可以解决(使用列,行,总纹理等..)我想要的纹理以及如何得到它。 正如我所说这是简化,计算是有点多,但有更多的时候有多行。 但是它使animation变得更加简单,因为我可以简单地递增或递减当前帧。

但是,我一直看到精灵表没有秩序。 有不同大小的纹理似乎扔进地图集像这样:

在这里输入图像说明

我真的想走这条路,因为这意味着我不需要按照对象大小分开我的精灵表,因此,大大减less了我必须使用的单独表的数量。

然而,我不能通过指定要渲染的纹理编号来计算如何获得正确的纹理。

那么这是如何工作的? 我是否需要手动计算每个对象(实际上是帧)的texel坐标,手动(也许将这个值存储在一个数组中,并将其与一个帧号相关联)?还是我在这里错过了一个技巧?

你的直觉是正确的。

除非应用程序需要的所有信息都可以从硬编码的知识和规则中获得,否则必须将图像的外部信息映射区域映射为精灵。 即使在你常规的基于网格的例子中,你也缺less关于一般情况的一些信息。

精灵表单的公共元数据是:

  • 起源 ,精灵内的一个位置,表示它的逻辑中心;
  • 碰撞范围 ,精灵的碰撞点通常比视觉要小,以平衡游戏玩法的公平性和精灵在视觉上可以穿透其他东西而不碰撞的程度;
  • 标识符/名称 ,对于用于不同对象的视觉效果的精灵表格,通常通过名称/ ID查找完成表格中哪个精灵的查找,元数据将包含这些映射。

使用单一的vec4制服,你可以使用任意大小的精灵:

 uniform vec4 spriteLoc;//x and y is the relative offset and z and w is the scaling factor varrying vec2 texCoord;//0-1 as you would without the atlas main(){ gl_fragColor = sampler2D(atlas, texCoord.xy*spriteLoc.zw + spriteLoc.xy); }