简体   繁体   English

纹理重复四边形OpenGL

[英]Texture repeating on quads OpenGL

I am writing a voxel engine and at the moment I am working on the Chunk-Rendering-System but I have a problem. 我正在写一个体素引擎,目前我正在研究Chunk-Rendering-System,但我有一个问题。 It seems that the textures were repeated on the quads. 似乎在四边形上重复了纹理。

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

There is this green line at the bottom of the grass blocks and I don't know why. 草块底部有绿线,我不知道为什么。

This is the OpenGL-Render-Code: 这是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();

And here is the OpenGL-Setup: 这是OpenGL设置:

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

确保GL_TEXTURE_WRAP_SGL_TEXTURE_WRAP_T设置为GL_CLAMP_TO_EDGE

genpfault's answer should do the trick for you, I just wanted to give you some insight into why you need this particular wrap state. genpfault的答案应该为你做的伎俩,我只是想让你深入了解为什么你需要这个特定的包裹状态。

To be clear, the green line in your screenshot corresponds to the edges of one of your voxels? 要清楚,屏幕截图中的绿线对应于您的一个体素的边缘?

It looks like you are using GL_LINEAR filtering (default) together with an inappropriate texture wrap state (eg GL_REPEAT or GL_CLAMP ). 看起来您正在使用GL_LINEAR过滤(默认)以及不适当的纹理包装状态(例如GL_REPEATGL_CLAMP )。 I will explain why GL_CLAMP is a bad idea later. 我将在后面解释为什么GL_CLAMP是一个坏主意。


You may think that the texture coordinate 0.0 and 1.0 are perfectly within the normalized texture coordinate range and therefore not subject to wrapping, but you would be wrong. 你可能认为纹理坐标0.01.0完全在标准化的纹理坐标范围内,因此不会被包裹,但你会错的。

This particular combination of states will pickup texels from the other side of your texture at either extreme of the [0,1] texture coordinate range. 这种特殊的状态组合将在[0,1]纹理坐标范围的任一极端处从纹理的另一侧拾取纹素。 The texture coordinate 1.0 is actually slightly beyond the center of the last texel in your texture, so when GL fetches the 4 nearest texels for linear filtering, it wraps around to the other side of the texture for at least 2 of them. 纹理坐标1.0实际上稍微超出了纹理中最后一个纹素的中心 ,因此当GL获取4个最接近的纹素以进行线性过滤时,它会围绕纹理的另一侧包裹至少2个纹素。

GL_CLAMP_TO_EDGE modifies this behavior, it clamps the texture coordinates to a range that is actually more restrictive than [0,1] so that no coordinate goes beyond the center of any edge texels in your texture. GL_CLAMP_TO_EDGE修改了这种行为,它将纹理坐标限制在实际上比[0,1]更具限制性的范围内,这样任何坐标都不会超出纹理中任何边纹理像素的中心 Linear filtering will not pickup texels from the other side of your texture with this set. 线性过滤不会使用此集从纹理的另一侧拾取纹素。 You could also (mostly) fix this by using GL_NEAREST filtering, but that will result in a lot of texture aliasing. 你也可以(大部分)通过使用GL_NEAREST过滤来解决这个问题,但这会导致很多纹理混叠。


It is also possible that you are using GL_CLAMP , which, by the way was removed in OpenGL 3.1. 您也可以使用GL_CLAMP ,顺便说一下,在OpenGL 3.1中删除了GL_CLAMP In older versions of GL it was designed to clamp the coordinates into the range [0,1] and then if linear filtering tried to fetch a texel beyond the edge it would use a special set of border texels rather than wrapping around. 在GL的旧版本中,它被设计为将坐标钳位到范围[0,1]中,然后如果线性过滤试图获取超出边缘的纹理元素,则它将使用一组特殊的边框纹理而不是环绕。 Border texels are no longer supported, and thus that wrap mode is gone. 不再支持边框纹理,因此包装模式消失了。

The bottom line is do not use GL_CLAMP , it does not do what most people think. 底线是不使用GL_CLAMP ,它没有做大多数人的想法。 GL_CLAMP_TO_EDGE is almost always what you really want when you think of clamping textures. 当你想到夹紧纹理时, GL_CLAMP_TO_EDGE几乎总是你真正想要的。


EDIT: 编辑:

genpfault brings up a good point; genpfault提出了一个好点; this would be a lot easier to understand with a diagram... 通过图表可以更容易理解...

The following diagram illustrates the problem in 1 dimension: 下图说明了1维问题:

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

I have a more thorough explanation of this diagram in an answer I wrote to a similar issue . 在我写给类似问题的答案中,我对这个图有了更全面的解释。

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

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