有没有办法在GLSL中使用union?

有没有办法在GLSL中使用union?,glsl,shader,union,Glsl,Shader,Union,我想知道是否有办法在GLSL中使用union。我没有看到任何关于这个的文档。如果没有,是否有一个干净的解决方法来使用工会 我基本上想要一系列的东西。有些东西可能是两种东西中的任何一种,因此我想用一个并集来定义它 谢谢 另外,可能会有一些奇怪的铸造技巧,我不知道,请随意建议一个更好的方法 编辑: 代码示例(无法编译,因为union不可用): 另外,假设A和B是巨大的,你不会想复制它们 编辑2: 这里有更多信息,希望能有所帮助: 这些数据将来自“外部”,并且是特定于顶点的。根据类型(A或B),必须对

我想知道是否有办法在GLSL中使用union。我没有看到任何关于这个的文档。如果没有,是否有一个干净的解决方法来使用工会

我基本上想要一系列的东西。有些东西可能是两种东西中的任何一种,因此我想用一个并集来定义它

谢谢

另外,可能会有一些奇怪的铸造技巧,我不知道,请随意建议一个更好的方法

编辑:

代码示例(无法编译,因为union不可用):

另外,假设A和B是巨大的,你不会想复制它们

编辑2:

这里有更多信息,希望能有所帮助:

这些数据将来自“外部”,并且是特定于顶点的。根据类型(A或B),必须对其进行不同的处理。它们可能是从VBO访问的。

根据,关键字
union
保留供将来使用,并且确实会导致编译错误

GLSL支持的一种解决方法是使用带有标志的结构数组,因为它们鼓励您使用简单的数据结构(没有邪恶的指针分配或奇怪的强制转换技巧)

struct AandB {
   A a;
   B b;
   bool isA;
};
然后,您可以将其用于以下内容:

AandB foo;

if (a.isA) {
   /* a process */
}
else {
   /* b process */
}
但是,如果一个项可能不包含这两种类型,那么您应该注意标志最初为false并假定为类型B。在这种情况下,解决方法是使用两个标志并设置正确的标志

更新:

如果内存使用是一个问题,仍然有办法解决,但它需要一个更有趣的数据结构。想到的一种方法是使用一个包含索引和标志的项定义数组。让我们想象一下这种数据结构:

struct Item {
   bool isA;
   int index;
};

Item items[5];
A a[5];
B b[5];

Item firstAItem;
firstItem.isA = true;
firstItem.index = 0;
items[0] = firstAItem;

Item firstBItem;
firstBItem.isA = false;
firstBItem.index = 0;
items[1] = firstBItem;
迭代时,您可以检查标志并转到相关索引,如下所示,假设
N_items
是您拥有的项目数:

for (int i=0; i<N_items; i++) {
   Item currentItem = items[i];
   if (currentItem.isA) {
      A foo = a[currentItem.index];
      /* do some stuff with foo */
   } else {
      B bar = b[currentItem.index];
      /* do some stuff with bar */
   }
}

for(int i=0;i因为我们讨论的是顶点属性,所以可以执行以下操作:

layout(location = 0) vec4 floatVal;
layout(location = 0) ivec4 intVal;
OpenGL将此称为属性别名,并明确允许,但有以下警告。要么仅访问一个别名属性,要么通过着色器的每个代码路径仅访问其中一个属性。因此,如果使用布尔条件保护访问和值计算,则可以:

//Don't use either variable yet

if(isFloat)
{
  //Do something with `floatVal`
}
else
{
  //Do something with `intVal`
}

//Don't use either variable again.

好吧,理论上你会没事的。属性别名是一种非常奇怪的情况,任何使用OpenGL的主要程序实际上都不太可能做到这一点。这意味着实现支持可能会有缺陷(未使用的代码是未经测试的代码)。因此,如果你想确保你的代码能够跨平台运行,我建议你切换程序。

你能给出一个例子或一些你正在尝试的代码吗?是的,它不是有效的GLSL,但这是我想做的。这些信息到底从何而来?我制作了这个示例,union部分不会为sur编译e但我想做的事情就在这里。@user2888798:你还不太理解我的问题。数据从哪里来,这关系到你如何实际执行你所说的。数据是否在缓冲区对象中,通过UBO访问?数据是否在SSBO中?可能是纹理?顶点属性?每个都有自己的属性针对这些数据源的潜在解决方案。假设A和B很大,我希望它们共享相同的内存空间。是否有其他干净的方法可以做到这一点?请参阅我的更新答案。在不占用大量内存的情况下仍然可以做到这一点。不过,一切都是以复杂性为代价的。这是一个有趣的解决方案,您正在使用将第一个数组(项)作为指向第二个或第三个数组的“指针”。如果已知每种类型的元素数量,这可能会起作用。(即,我将有9个a元素和1个B元素,我可能仍然需要声明
a[10]
B[10]
,以防万一)。这将占用双倍的内存。我可能可以做到这一点,但我真的在寻找一种方法来共享相同的内存空间,如果可能的话……您仍然可以保留每种类型插入的项目数。共享相同的内存空间会更简单,但我认为如果没有
union
或pointe,这是不可能的不受支持的rs。谢谢,如果没有人有更好的解决方案,我会将你的答案标记为最佳答案。天哪,这是一个黑客程序,但它是我想要的黄金。非常感谢,如果我的问题不清楚,很抱歉。
//Don't use either variable yet

if(isFloat)
{
  //Do something with `floatVal`
}
else
{
  //Do something with `intVal`
}

//Don't use either variable again.