纹理坐标

转自http://blog.163.com/mt_lty/blog/static/592999522010163435446/

纹理实际上是一个二维数组,它的元素是一些颜色值。单个的颜色值被称为纹理元素(texture elements)或纹理像素(texel)。每一个纹理像素在纹理中都有一个唯一的地址。这个地址可以被认为是一个列(column)和行(row)的值,它们分别由U和V来表示。

纹理坐标位于纹理空间中。也就是说,它们和纹理中的(0,0)位置相对应。当我们将一个纹理应用于一个图元时,它的纹理像素地址必须要映射到对象坐标系中。然后再被平移到屏幕坐标系或像素位置上。

Direct3D直接将纹理空间中的纹理像素1.2 纹理坐标 - 咬花专家 - 咬花专家

映射到屏幕空间中的像素,跳过了中间过程,从而提高了效率。这一映射过程实际上是一个相反的(inverse)映射。也就是说,对于屏幕空间中的每一个像素,我们来计算相应的纹理空间中的纹理像素位置。对那一点上的或那一点周围的纹理颜色进行采样(sample)。采样过程被称为纹理过滤(texture filtering)。

纹理中的每一个纹理像素可以通过它的坐标来声明。但是,为了将纹理像素映射到图元上,对于所有纹理上的所有纹理像素,Direct3D需要有一个统一的地址范围。因此,它使用了一个通用的地址方案,在这个方案中所有纹理像素地址的范围都在0.0到1.0之间,包括0.0和1.0。Direct3D程序用U、V的值来声明纹理坐标,它和用x、y坐标来声明二维迪卡尔坐标系一样。

在这种情况下,不同纹理中的同一纹理地址又可能被映射为不同的纹理像素坐标。如左面插图中的纹理地址(0.0,0.5)。由于纹理的大小有所不同,因此纹理地址将会映射为不同的纹理像素。左边的纹理1,大小为5x5,纹理地址(0.0,0.5)映射到纹理像素(0,2);右边的纹理2,大小为7x7,纹理地址(0.0,0.5)映射到纹理像素(0,3)。

左图展示了一个简单的纹理像素映射的过程:1.2 纹理坐标 - 咬花专家 - 咬花专家

我们要给图中左边的像素确定一定的颜色。像素四个角的地址被映射到对象空间中的图元上,这时,像素的形状会有一些变形,这是由图元的形状和观察的角度造成的。然后,与像素角相对应的图元表面上的几个角被映射到纹理空间中。这一映射过程再次使像素的形状产生变形。像素最终的颜色值就由该像素映射到的区域中的纹理像素计算而得。在设置纹理过滤方法时,要决定Direct3D使用什么方法来得到像素的颜色。

程序可以直接将纹理坐标分配给顶点。这一能力使我们能够控制将一个纹理的哪些部分映射到一个图元上。现在假定我们要创建一个矩形图元,它的大小恰好与下图中纹理的大小一样。我们要将整个纹理都映射到一整堵墙上,那么分配给图元顶点的纹理坐标就应该是(0.0,0.0)、(1.0,0.0)、(1.0,1.0)和(0.0,1.0)。

现在我们要将墙的高度缩小一半。我们可以将纹理变形以适应墙的变化,也可以在分配纹理坐标时只使用纹理的下面一半。

1.2 纹理坐标 - 咬花专家 - 咬花专家

如果使用纹理变形或缩放的方法,那么所使用的纹理过滤方法就会对图象的质量产生影响。详细内容见“纹理过滤”。

如果采用分配纹理坐标的方法,那么分配给图元顶点的纹理坐标就应该是(0.0,0.0)、(1.0,0.0)、(1.0,0.5)和(0.0,0.5)。Direct3D会将纹理的下面一半应用到墙上。

有时,一个顶点的纹理坐标可能比1.0大。当分配给顶点的纹理坐标不在0.0到1.0(包括它们)范围内时,就要设置纹理寻址模式了。

<think>好的,我现在需要回答用户关于OpenGL纹理坐标范围以及如何正确设置的问题。用户还提供了几个引用,我需要结合这些引用来组织答案。首先,我需要明确用户的问题:他们想了解纹理坐标的范围以及如何正确设置这些坐标。根据引用[2],纹理坐标通常范围是0到1,但超出这个范围时有不同的环绕方式。用户可能想知道如何设置坐标来适应不同的纹理映射需求,比如重复纹理或者拉伸边缘。接下来,我需要整理OpenGL中纹理坐标的基本概念。根据引用[1],纹理坐标是2D坐标,关联到顶点,用于将纹理映射到图形表面。每个顶点都需要指定纹理坐标,这样OpenGL在渲染时才能正确匹配纹理像素。因此,正确设置坐标对贴图效果至关重要。然后,关于纹理坐标的范围,引用[2]详细说明了默认范围是(0,0)到(1,1),超出范围时的四种环绕方式:重复、镜像重复、边缘拉伸和边框颜色。用户可能需要知道如何设置这些环绕方式,以及何时使用哪种方式。例如,在创建重复的地板纹理时,使用GL_REPEAT可以让纹理无缝衔接。关于如何设置纹理坐标,用户可能需要具体的代码示例。比如在定义顶点数据时,为每个顶点指定对应的纹理坐标。例如,一个矩形四个顶点的纹理坐标可能是(0,0)、(1,0)、(1,1)、(0,1),覆盖整个纹理。如果需要重复,可以设置坐标超过1,并配置环绕方式为GL_REPEAT。此外,用户提供的引用[3]和[4]提到不同框架(如Cocos2d-x)和平台(Android)中纹理坐标的差异,特别是坐标原点的位置。例如,Cocos2d-x可能需要将原点调整到左上角,而默认OpenGL的原点在左下角。这可能涉及到使用stbi_set_flip_vertically_on_load函数来翻转图像,确保纹理正确显示。这部分内容是否需要包含在回答中?用户的问题主要围绕OpenGL本身,但如果有跨平台或框架的考虑,可能也需要提及。 在注意事项部分,需要提到坐标原点的差异,以及如何通过API设置翻转,如引用[3]中的例子。同时,环绕方式的设置是通过glTexParameteri函数实现的,具体参数如GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T,引用[2]中的描述。 可能还需要解释顶点坐标纹理坐标的关系,如引用[4]中提到的不同坐标系,但用户的问题更关注纹理坐标的设置,所以这部分可能简要提及即可。 最后,生成相关问题需要考虑用户可能进一步想知道的内容,比如环绕方式的具体应用场景、不同平台的原点处理、如何与顶点坐标对应等。确保问题与当前主题相关,并引导用户深入理解。</think>### OpenGL 纹理坐标范围与设置详解 #### 1. 纹理坐标范围 OpenGL 纹理坐标的**标准范围**是 $(0.0, 0.0)$ 到 $(1.0, 1.0)$,对应纹理图像的左下角到右上角[^1]。超出此范围时,可以通过**纹理环绕方式**(Texture Wrapping)控制行为: - **默认行为**:`GL_REPEAT`(重复纹理) - **其他模式**: | 环绕模式 | 效果描述 | |-----------------------|--------------------------------------------------------------------------| | `GL_MIRRORED_REPEAT` | 镜像重复纹理 | | `GL_CLAMP_TO_EDGE` | 超出部分拉伸边缘像素 | | `GL_CLAMP_TO_BORDER` | 超出部分显示指定颜色(需用`glTexParameterfv`设置边框颜色) | #### 2. 如何设置纹理坐标 ##### 步骤 1:定义顶点纹理坐标 在顶点数据中为每个顶点指定纹理坐标,例如一个矩形顶点数据: ```c float vertices[] = { // 位置坐标 // 纹理坐标 -0.5f, -0.5f, 0.0f, 0.0f, // 左下角 0.5f, -0.5f, 1.0f, 0.0f, // 右下角 0.5f, 0.5f, 1.0f, 1.0f, // 右上角 -0.5f, 0.5f, 0.0f, 1.0f // 左上角 }; ``` 纹理坐标 $(0.0, 0.0)$ 对应纹理左下角像素,$(1.0, 1.0)$ 对应右上角像素[^1]。 ##### 步骤 2:设置纹理环绕方式 通过 `glTexParameteri` 配置超出范围的纹理行为: ```c glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // 水平方向 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // 垂直方向 ``` #### 3. 坐标系差异处理 - **原点问题**:OpenGL 纹理坐标原点在左下角,而图像数据通常原点在左上角(如PNG/JPG文件)。需在加载纹理前调用: ```c stbi_set_flip_vertically_on_load(1); // 垂直翻转图像数据[^3] ``` - **跨平台差异**:Android 等平台的屏幕坐标系原点可能在左上角,需注意与 OpenGL 坐标系转换[^4]。 #### 4. 数学表达 纹理坐标 $(s, t)$ 与纹理像素的映射关系为: $$ (s_{\text{tex}}, t_{\text{tex}}) = (s \cdot W, t \cdot H) $$ 其中 $W$ 和 $H$ 是纹理的宽度和高度。若使用 `GL_REPEAT`,实际计算时会取小数部分: $$ s_{\text{final}} = s - \lfloor s \rfloor,\quad t_{\text{final}} = t - \lfloor t \rfloor $$ #### 5. 注意事项 1. **顶点对齐**:纹理坐标必须与顶点一一对应,否则会导致贴图错乱 2. **Mipmap 影响**:使用 Mipmap 时,`GL_CLAMP_TO_EDGE` 在低分辨率层级可能产生边缘模糊 3. **性能优化**:频繁切换纹理环绕方式会增加 GPU 状态切换开销 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值