OpenGL ES纹理坐标略微关闭 [英] OpenGL ES Texture Coordinates Slightly Off

查看:106
本文介绍了OpenGL ES纹理坐标略微关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过指定所需的坐标在OpenGL中绘制纹理的子区域.不过,发生的是,根据图像的大小,似乎在选择纹理坐标的原点存在一些偏移.偏移量似乎小于像素的大小&像素.输出是相邻像素的模糊组合.

I'm trying to draw a subregion of a texture in OpenGL by specifying the coordinates I want. What's happening though is that, depending on the size of the image, it seems there's a slight offset in the origin of where it selects the texture coordinates. The offset amount seems to be less than the size of a pixel & the output is is blurred combination of neighboring pixels.

这是我所描述的想法.在这种情况下,我想选择6x5的绿色/白色区域,但是OpenGL呈现的是在顶部和顶部带有一点粉红色的色调.左像素.

Here's an idea of what I'm describing. In this case I'd want to select the 6x5 green/white region but what OpenGL is rendering includes a slight pink tint to the top & left pixels.

输出结果如下:

我可以通过在将纹理坐标传递给glTexCoordPointer之前在纹理坐标上添加偏移量来解决该问题,但是问题是我无法计算该偏移量,并且对于不同的纹理似乎有所不同.

I can fix it by adding an offset to the texture coordinates before passing them to glTexCoordPointer but the problem is that I have no way to calculate what the offset is and it seems different for different textures.

伪代码:

float uFactor = regionWidth / textureWidth;   // For the example: 0.6f
float vFactor = regionHeight / textureHeight; // For the example: 0.5f

data[0].t[0] = 0.0f * uFactor;
data[0].t[1] = 0.0f * vFactor;
data[1].t[0] = 1.0f * uFactor;
data[1].t[1] = 0.0f * vFactor;
data[2].t[0] = 0.0f * uFactor;
data[2].t[1] = 1.0f * vFactor;
data[3].t[0] = 1.0f * uFactor;
data[3].t[1] = 1.0f * vFactor;

glPushMatrix();

// translate/scale/bind operations

glTexCoordPointer(2, GL_FLOAT, 0, data[0].t);

推荐答案

请记住,OpenGL在纹理像素中心采样纹理.因此,当使用线性滤波(例如GL_LINEARGL_LINEAR_MIPMAP_LINEAR)时,仅在纹理像素中心进行采样时,才返回确切的纹理像素颜色.因此,当您只想使用纹理的子区域时,需要将纹理坐标缩进半个纹理像素(或0.5/width0.5/height).否则,过滤会将纹理的边界与目标区域之外的近邻纹理像素混合.这会导致您的边框略带粉红色.如果用尽了整个纹理,则可以通过GL_CLAMP_TO_EDGE环绕模式来补偿这种效果,但是使用子区域时,GL不知道其边缘在哪里,并且滤镜不应越过它.

Keep in mind, that OpenGL samples textures at the texel centers. So when using linear filtering (like GL_LINEAR or GL_LINEAR_MIPMAP_LINEAR) the exact texel color is only returned if sampled at the texel center. Thus, when you only want to use a sub-region of a texture, you need to indent your texture coordinates by half a texel (or 0.5/width and 0.5/height). Otherwise the filtering will blend the border of the texture with neigbouting texels outside of your intended region. This causes your slightly pinkish border. If you use up the whole texture this effect is compensated by the GL_CLAMP_TO_EDGE wrapping mode, but when using a subregion, GL does not know where it's edge is and that filtering should not cross it.

因此,当您获得纹理的子区域在[s1,s2]x[t1,t2](0 <= s,t <= 1)范围内时,实际有效的texCoord间隔应为[s1+x,s2-x]x[t1+y,t2-y],其中x0.5/widthy being 0.5/height(整个纹理的宽度和高度,对应于[0,1]x[0,1]).

So when you got a subregion of the texture in the range [s1,s2]x[t1,t2] (0 <= s,t <= 1), the real valid texCoord interval should be [s1+x,s2-x]x[t1+y,t2-y] with x being 0.5/width and y being 0.5/height (the width and height of the whole texture corresponding to [0,1]x[0,1]).

因此请尝试

data[0].t[0] = 0.0f * uFactor + 0.5/textureWidth;
data[0].t[1] = 0.0f * vFactor + 0.5/textureHeight;
data[1].t[0] = 1.0f * uFactor - 0.5/textureWidth;
data[1].t[1] = 0.0f * vFactor + 0.5/textureHeight;
data[2].t[0] = 0.0f * uFactor + 0.5/textureWidth;
data[2].t[1] = 1.0f * vFactor - 0.5/textureHeight;
data[3].t[0] = 1.0f * uFactor - 0.5/textureWidth;
data[3].t[1] = 1.0f * vFactor - 0.5/textureHeight;

这篇关于OpenGL ES纹理坐标略微关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆