关于OpenGL纹理坐标

70

我知道在每次调用glVertex之前都必须调用以下其中一个:

glTexCoord(0,0); 
glTexCoord(0,1); 
glTexCoord(1,1); 
glTexCoord(1,0); 

但我不知道它们是什么意思。 但我知道,如果我将右侧(或全部)乘以2(还是除以2?),我的纹理会扩展,如果我做相反的操作,则我的纹理会重复两次。 我已经成功地编写了应用操作的纹理集代码,直到它起作用。 但我对发生的事情没有正确的想法。为什么除法这些坐标会影响图像,为什么颠倒它们会镜像呢?纹理坐标是如何工作的?

4个回答

162

纹理坐标指定了对于你所指定的顶点,纹理图像上对应的点。可以把它想象成一张印有纹理图像的矩形橡胶板,每条边的长度都规范化到范围0-1之间。现在假设你想要使用该纹理绘制一个三角形。你需要将3个大头针分别固定在橡胶板上,位置与你所需的纹理坐标点相同(例如[0, 0]、[1, 0]和[1, 1]),然后移动这些大头针(不取出)到你需要的顶点坐标上(例如[0, 0]、[0.5, 0]和[1, 1]),使橡胶板被拉伸,并且图像被扭曲。这就是纹理坐标的基本工作原理。

如果你使用的纹理坐标大于1,并且你的纹理设置为平铺,则好像橡胶板大小无限,纹理在其上被平铺。因此,如果你的两个顶点的纹理坐标分别为0、0和4、0,则在这些顶点之间的图像将被重复4次。

enter image description here @b1nary.atr0phy 图像,供所有视觉思维者参考!


5
引用的“ pins”比喻很棒。我想要拉伸和移动纹理到四边形上,而不是四边形使用纹理坐标从纹理中“取样”。谢谢。 - mk.
4
我可能错了,但是对于WebGL,纹理的原点在左上角,而不是左下角。我认为所有的GL都是相同的。这张图片引起了一些混淆。 - 0xcaff
我知道这是一个旧帖子,但纹理尺寸不再需要是二的倍数。 - SwiftsNamesake
2
@SwiftsNamesake,当我写下那个答案的时候,这可能已经是真的了...我会去把它删掉。 - geofftnz
@geofftnz 是和不是,它们可能不是,但是它们被内部重新采样为这样。 - Swift - Friday Pie

9

OpenGL使用反向纹理。它将世界空间(X、Y、Z)的坐标转换为纹理空间(X、Y),然后再转换为离散空间(U、V),其中离散空间在[0,1]域内。

想象一个多边形就像一张纸。通过这个过程:

glTexCoord(0,0); 
glTexCoord(0,1); 
glTexCoord(1,1); 
glTexCoord(1,0); 

你需要告诉OpenGL在整张纸上绘制。当你应用修改时,你的纹理空间会相应地根据给定的坐标进行修改。例如,当你将它们分成两半时,你会得到相同的纹理两次,这是因为你告诉OpenGL映射了你纸张的一半,而不是整张纸。

6

红皮书的第9章详细解释了这个问题,并可在网上免费获取。

http://www.glprogramming.com/red/chapter09.html

纹理坐标将x、y映射到宽度和高度纹理空间中的0-1区间。然后像橡皮筋一样拉伸到三角形上。最好用图片来解释,红皮书也有相关内容。


5
对于2D图像纹理,纹理坐标中的0,0对应于图像的左下角,而纹理坐标中的1,1对应于图像的右上角。请注意,“图像的左下角”不在左下角像素的中心,而在像素的边缘。
此外,在上传图像时也很有趣:
8.5.3 纹理图像结构
纹理图像本身(由数据引用)是一系列值组的序列。第一组是纹理图像的左下后角。随后的组从左到右填充宽度为width的行;高度行从底部向上堆叠形成单个二维图像切片; 深度切片从后向前堆叠。
请注意,大多数图像格式的数据从顶部开始而不是从底部行开始。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接