windows - OpenGL 中的 GL_CLAMP 与 GL_CLAMP_TO_EDGE 有何不同?
问题描述
根据您参考的文档glTexParameteri()
,对纹理的钳制有两种不同的解释。
在Microsoft 的文档中,您会找到GL_CLAMP,而在Khronos 的文档中,您会找到GL_CLAMP_TO_EDGE。
我认为它们在功能上是同义词,但似乎并非如此。
在我的 Ubuntu 18.04.2 上,我有以下内容。
/usr/include/GL/gl.h
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_CLAMP 0x2900
#define GL_CLAMP_TO_BORDER 0x812D
而在我的 Windows 10 16299 Enterprise 版本中,我有以下内容。
C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\gl\GL.h
#define GL_CLAMP 0x2900
它们被映射到不同的值,因此人们也会期望不同的行为。
我试图摆脱使用 GL_REPEAT 获得的伪像。请参见下图中的绿色圆圈(图片来源 - freepik.com)。
GL_CLAMP
确实摆脱了伪影,但是我无法找到有关各种钳位模式如何不同的足够详细信息,以及何时更喜欢一种。
我在我的 Windows 机器上编码,以后可能会将相同的应用程序移植到 GNU/Linux。
更新 1:GL_CLAMP
消除了大多数伪像,但不是全部,最后我为我的所有纹理添加了一个 10px 透明边框。然而,问题仍然存在。
更新 2:问题不在于 GL_CLAMP 在实现之间有何不同,而是GL_CLAMP 与 GL_CLAMP_TO_EDGE 有何不同?
解决方案
如果您深入研究 Khronos Registry的不同 GL 规范,您会发现一些解释。
在第一个规范(1.0 1994)中CLAMP
,REPEAT
是参数的唯一选项TEXTURE_WRAP_x
。
规范 1.2 1998 添加CLAMP_TO_EDGE
。它提供了您需要的线索:
GL 通常会进行钳制,以使纹理坐标精确地限制在 [0;1] 范围内。当使用此算法钳制纹理坐标时,纹理采样过滤器跨越纹理图像的边缘,从纹理图像中获取一半样本值,另一半从纹理边界获取样本值。有时需要在不需要边框且不使用恒定边框颜色的情况下钳制纹理。
一种新的纹理钳制算法 CLAMP_TO_EDGE 在所有 mipmap 级别上钳制纹理坐标,这样纹理过滤器就不会对边界纹素进行采样。夹紧时返回的颜色仅来自纹理图像边缘的纹素。
该CLAMP
选项在规范 3.0 2008 中已弃用,并在规范 3.2 Core 2009 中删除。当(且仅当)您未设置核心配置文件上下文时,您仍然可以使用它。
Microsoft doc 采用 old 的原因CLAMP
是 MS 提供了 OpenGL 1.1,而不需要检索指向 GL 命令的函数指针。更高的版本需要特殊的头文件(除了 gl.h)和其他特殊的东西。
推荐阅读
- c++ - c++ std::async 比顺序 for 循环慢
- continuous-integration - 单元测试或集成测试位桶 repo 中的特定文件夹
- javascript - 如何根据属性名称破坏对象数组需要映射值
- c# - VB.NET 中 C# BeginInvoke((Action)) 的等价物
- java - 使用 Guava Cache 在多个服务实例上进行分布式缓存同步
- matlab - 如何根据第四个变量的数据为 scatter3 中的点着色?
- scala - Scala RDD 有条件地调用过滤函数
- javascript - 嵌套的while循环怎么可能是O(n)?
- r - 使用 data.table::fread 读取特定的非连续行(相当于“Select”参数,但用于行)?
- swift - 使用 UIGraphicsImageRenderer 创建圆形图像