纹理重复四边形OpenGL

时间:2014-04-10 17:34:51

标签: java opengl rendering lwjgl repeat

我正在写一个体素引擎 我正在研究Chunk-Rendering-System,但我遇到了问题。 看起来纹理在四边形上重复了。

http://i.stack.imgur.com/6iuuN.png

草块底部有绿线,我不知道为什么。

这是OpenGL-Render-Code:

Texture texture = TextureManager.getTexture(block.getTextureNameForSide(Direction.UP));
texture.bind();
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0, 0); GL11.glVertex3f(0, 1, 0);
GL11.glTexCoord2d(1, 0); GL11.glVertex3f(0, 1, 1);
GL11.glTexCoord2d(1, 1); GL11.glVertex3f(1, 1, 1);
GL11.glTexCoord2d(0, 1); GL11.glVertex3f(1, 1, 0);
GL11.glEnd();

这是OpenGL-Setup:

GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glClearColor(0.1F, 0.4F, 0.6F, 0F);
GL11.glClearDepth(1F);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
GL11.glCullFace(GL11.GL_BACK);
GL11.glEnable(GL11.GL_CULL_FACE);

2 个答案:

答案 0 :(得分:4)

确保GL_TEXTURE_WRAP_SGL_TEXTURE_WRAP_T设置为GL_CLAMP_TO_EDGE

答案 1 :(得分:3)

genpfault的答案应该适合你,我只是想让你深入了解为什么你需要这个特定的包裹状态。

要清楚,屏幕截图中的绿线对应于您的某个体素的边缘?

看起来您正在使用GL_LINEAR过滤(默认)以及不适当的纹理包装状态(例如GL_REPEATGL_CLAMP)。我将在稍后解释为什么GL_CLAMP是一个坏主意。


你可能认为纹理坐标 0.0 1.0 完全在标准化的纹理坐标范围内,因此不会被包裹,但你会错的。

这种特殊的状态组合将在[0,1]纹理坐标范围的任一极端处从纹理的另一侧拾取纹素。纹理坐标 1.0 实际上是超出纹理中最后一个纹素的 中心 ,因此当GL提取时用于线性过滤的4 最接近的 纹素,它至少包含2个纹理的另一边。

GL_CLAMP_TO_EDGE修改了这种行为,它将纹理坐标限制在一个实际上比[0,1]更具限制性的范围内,这样任何坐标都不会超出任何边缘纹素的 center 在你的纹理。线性过滤不会使用此集从纹理的另一侧拾取纹素。您也可以(大部分)使用GL_NEAREST过滤来解决此问题,但这会导致大量纹理别名。


您也可能正在使用GL_CLAMP,顺便说一下,它已在OpenGL 3.1中删除。在GL的旧版本中,它被设计为将坐标钳位到范围[0,1]中,然后如果线性过滤试图获取超出边缘的纹理元素,则它将使用一组特殊的边框纹理而不是环绕。不再支持边框纹理,因此包装模式消失了。

底线是不使用GL_CLAMP,它没有做大多数人的想法。当您想到夹紧纹理时,GL_CLAMP_TO_EDGE几乎总是真正想要的。


编辑:

genpfault提出了一个好点;用图表来理解这一点会容易得多......

下图说明了1维问题:

http://i.msdn.microsoft.com/dynimg/IC83860.gif

我在写给similar issue的答案中对这个图表有了更全面的解释。