为啥 glm::vec 将 vec 值表示为联合?
Posted
技术标签:
【中文标题】为啥 glm::vec 将 vec 值表示为联合?【英文标题】: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
【参考方案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++ 类。以上是关于为啥 glm::vec 将 vec 值表示为联合?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 glm::vec4<float> 转换为 GLfloat*?