【问题标题】:Why does glm::vec represent vec values as unions?为什么 glm::vec 将 vec 值表示为联合?
【发布时间】:2017-02-24 15:44:57
【问题描述】:

我在查看vec4 glm 的源代码实现,我想知道为什么它们用联合表示向量值,而不是像float 或int 这样的原始数据类型?

这是我在vec4实现中找到的代码:

union { T x, r, s; };
union { T y, g, t; };
union { T z, b, p; };
union { T w, a, q; };

如果我们只写T x,T y,T z,T w,有什么区别?

【问题讨论】:

  • 请注意:这使得v.x == v.r == v.s

标签: c++ glm-math


【解决方案1】:

因为vec4 通常用于:

  • 空间坐标x, y, z, w
  • 颜色组件r、g、b、a
  • 纹理坐标s、t、p、q(虽然这些不太标准化,我也​​看到r和u在不同的上下文中使用)

使用联合允许使用访问例如第二个数据成员为 .y 或 .g,具体取决于您的偏好和语义。

【讨论】:

  • 这是使用定义的行为吗?我知道使用联合的类型双关语不是,但这并不是真正的类型双关语。
  • @chbaker0 如果您只为给定成员使用一个名称,那无疑是。如果您使用多个...我仍然这么认为。我更熟悉 C 语言,它有专门用于覆盖它的工会的语言。 C ++似乎没有,但我认为“对象生命周期”(N4140 3.8.7)下的某些内容具有使其合法的效果,因为不同的名称是具有相同类型和相同存储位置的不同“对象” ,并且在使用一个和另一个之间没有释放存储空间(从技术上讲,这会导致一个的生命周期结束而另一个的生命周期开始)。
  • @chbaker0:是的,这是定义明确的行为,因为所有类型都是相同的。是的,即使在 C++ 中也是如此。
  • @NicolBolas C++11标准中的语言是“在一个联合体中,在任何时候最多可以有一个非静态数据成员处于活动状态,即最多的值其中一个非静态数据成员可以随时存储在联合中,”因此从表面上看,答案似乎是否定的。这就是我问的原因。不过霍布斯的回答很有说服力。
  • @chbaker0 你引用的那段的其余部分解释了为什么你可以像他们那样使用联合。假设T 是标准布局类型(所有原语都是),那么您可以从它们的公共部分访问数据(因为它们都是相同的类型,所以是整个值)
【解决方案2】:

GLM 被设计成在 C++ 允许的范围内表现得像 GLSL。在 GLSL 中,向量的 swizzle 操作可以使用 xyzw、rgba 或 stpq,对应的元素名称引用向量的相同元素。因此,联合用于匹配这种行为。

【讨论】:

  • 加一个用于突出与 GLSL 的兼容性,我没有考虑过。
  • 这才是真正的原因。 GLM 的行为不像原生设计的 C++ 类。
猜你喜欢
  • 2020-09-25
  • 2019-04-06
  • 1970-01-01
  • 2020-10-28
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
相关资源
最近更新 更多