为啥 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 的源代码实现,我想知道为什么它们用联合表示向量值,而不是像floatint 这样的原始数据类型?

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

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

如果我们只写T xT yT zT w,有什么区别?

【问题讨论】:

请注意:这使得v.x == v.r == v.s 【参考方案1】:

因为vec4 通常用于:

空间坐标x, y, z, w 颜色组件rgba 纹理坐标stpq(虽然这些不太标准化,我也​​看到ru在不同的上下文中使用)

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

【讨论】:

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

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

【讨论】:

加一个用于突出与 GLSL 的兼容性,我没有考虑过。 这才是真正的原因。 GLM 的行为不像原生设计的 C++ 类。

以上是关于为啥 glm::vec 将 vec 值表示为联合?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 glm::vec4<float> 转换为 GLfloat*?

为啥灯光出现在对面?

glm::vec3 精度 C++

GLM:获取平面线交点的位置

opengl - 黑色纹理,如何在缓冲区上使用 glm::vec*?

glm - 将 mat4 分解为平移和旋转?