我正在写一个体素引擎 我正在研究Chunk-Rendering-System,但我遇到了问题。 看起来纹理在四边形上重复了。
草块底部有绿线,我不知道为什么。
这是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);
答案 0 :(得分:4)
确保GL_TEXTURE_WRAP_S
和GL_TEXTURE_WRAP_T
设置为GL_CLAMP_TO_EDGE
。
答案 1 :(得分:3)
genpfault的答案应该适合你,我只是想让你深入了解为什么你需要这个特定的包裹状态。
要清楚,屏幕截图中的绿线对应于您的某个体素的边缘?
看起来您正在使用GL_LINEAR
过滤(默认)以及不适当的纹理包装状态(例如GL_REPEAT
或GL_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提出了一个好点;用图表来理解这一点会容易得多......
http://i.msdn.microsoft.com/dynimg/IC83860.gif
我在写给similar issue的答案中对这个图表有了更全面的解释。