你的问题很可能不是由于舍入误差,而是对OpenGL如何将纹素映射到像素的理解有误。如果你注意到偏差为1,那么很可能是因为你的UV坐标、顶点位置或投影矩阵/视口对齐不正确。
为了简化,我只讨论一维情况,并假设你使用一个投影和视口将X、Y坐标映射到相应的像素位置(即
glOrtho(0,width,0,height,zmin,zmax)
和
glViewport(0,width,0,height)
)。
假设你想在屏幕上从第20个像素开始显示64宽度纹理的5个纹素(为简单起见,从0开始)。
为了实现这个目标,需要绘制X坐标为20和30的三角形,以及U(UV对中的一个)为10/64和15/64。OpenGL的光栅化将生成10个像素进行着色,X坐标为20.5、21.5、... 29.5。
请注意,这些位置不是整数。OpenGL在像素的中心进行光栅化。
同样地,它将生成U坐标为10.25/64、10.75/64、11.25/64、11.75/64...14.25/64、14.75/64。再次
请注意,纹素坐标在纹理空间中的位置不是整数。OpenGL从纹素位置的中心进行采样,所以这是可以的。
采样器如何使用这些UV来生成纹素值取决于过滤模式,但无论是最近的还是线性的,像素应该仅包含在感兴趣的纹素内(大小为0.5的0.25应仅使用从0到0.5的颜色,这完全在第一个纹素内)。
一般来说,如果你遵循我提出的一般原则,就不应该看到伪影。
- 使用与帧缓冲区大小完全相同的正交和视口
- 使用X、X+width的位置
- 使用对应于你想要的纹素的确切UV(如果你想要从纹素0开始的10个纹素,使用U=0到U=10)。
如果你的计算中有-1,那么很可能是不正确的(对于位置或UV)。
回到你的例子,不清楚你是如何将计算出的UV与位置联系起来的(因为你没有显示位置计算)。也不清楚你是如何得到xpos_in_texture的(你应该解释一下如何计算精灵的四个角落)。我猜你计算错了。