简体   繁体   English

OpenGL ES纹理略微偏离

[英]OpenGL ES Texture Coordinates Slightly Off

I'm trying to draw a subregion of a texture in OpenGL by specifying the coordinates I want. 我试图通过指定我想要的坐标在OpenGL中绘制一个纹理的子区域。 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. 偏移量似乎小于像素的大小,并且输出是相邻像素的模糊组合。

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. 在这种情况下,我想要选择6x5绿色/白色区域,但OpenGL渲染的内容包括顶部和左侧像素的浅粉色调。 偏移图

What the output would look like: 输出结果如下:

产生的输出纹理

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. 我可以通过在将它们传递给glTexCoordPointer之前向纹理坐标添加偏移来修复它,但问题是我无法计算偏移量是什么,并且对于不同的纹理看起来不同。

Pseudocode: 伪代码:

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);

Keep in mind, that OpenGL samples textures at the texel centers. 请记住,OpenGL会在纹素中心对纹理进行采样。 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. 因此,当使用线性过滤(如GL_LINEARGL_LINEAR_MIPMAP_LINEAR )时,只有在纹素中心采样时才会返回确切的纹理颜色。 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 ). 因此,当您只想使用纹理的子区域时,需要将纹理坐标缩进半个纹素(或0.5/width0.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. 如果你用完整个纹理,这个效果会被GL_CLAMP_TO_EDGE包装模式补偿,但是当使用一个子区域时,GL不知道它的边缘在哪里,并且过滤不应该越过它。

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] ). 因此,当您在[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] )。

Therefore try 所以试试吧

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;

Propably this has to do with the wrap around. 这可能与环绕有关。 Try this when you create the source image: 在创建源图像时尝试此操作:

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP )
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM