以编程方式定义混合(如在GLSL中)

时间:2016-07-21 19:18:45

标签: swizzling

如何在编程语言中将swizzling作为定义的行为? (像GLSL中的矩阵和向量一样的混合成员)因此,如果我想制作一种允许定义某些成员调配的编程语言,那么这样做的好方法是什么?例如,我可以这样做:

struct
{
    swizzable
    {
        float x, float y, float z, float w
    }
}

但这种情况很少见。例如,当我调换更多或更少的元素或分配给子集或仅向后分配元素时,它没有定义它返回的内容。就像在GLSL中一样,我可以使用v.xyz从一个名为v的Vec4创建一个Vec3。或者我可以分配一个成员子集:v.zyx = ...以任何顺序。

所以这个可调节的子结构不是解决方案(或者至少太有限)。另一种方法是返回一个混合成员数组,隐式强制转换(使用构造函数)将生成所需元素:

struct Vec2
{
    swizzable { float x, float y }
    Vec2(float[2] elements)
    { x = elements[0]; y = elements[1]; }
}

struct Vec3
{
    swizzable { float x, float y, float z }
}

所以如果我通过swizzling访问Vec3的x和y,我会得到一个float [2],因为我有一个Vec2的构造函数,我可以将这个数组赋给它(并隐式实例化一个vec2)。

这看起来是一个更好的解决方案,但仍然是:如何做得更好?

编辑:对不起,我没有指定问题:我想实现一种支持这种事情的编程语言。

1 个答案:

答案 0 :(得分:0)

我不确定如何给出一个好的,详细的答案,所以这只是一个想法。

如果我理解正确,调酒主要是语法上的便利。页面https://www.opengl.org/wiki/GLSL_Optimizations提供了以下关于调配的示例:

gl_FragColor = mycolor.xyzw * constantList.xxxy + constantList.yyyx;

这可能仅仅是语法简写:

gl_FragColor = Vector(mycolor.x, mycolor.y, mycolor.z, mycolor.w)
    * Vector(constantList.x, constantList.x, constantList.x, constantList.y)
    + Vector(constantList.y, constantList.y, constantList.y, constantList.x);

因此,一步可能是弄清楚如何解析较短的语法并将其解释为类似于较长语法的含义。

我不明白为什么有必要将结构声明为比struct myStruct { float x, float y, float z, float w }更复杂的结构。语言本身应该能够处理如何实现这种混合的所有细节。