我不允许使用带有in
关键字的结构,是吗?例如:
struct Rect {
float x,y,width,height;
};
layout(location = 7) in Rect TexSrc;
谷歌很难,但我在尝试使用GLSL着色器(INVALID_OPERATION
)时出错。不过,我似乎被允许使用float[4]
。
如果不允许我使用结构,你建议我怎么做?用float[4]
构造结构,或者吸收它,放弃漂亮的API,到处使用索引0-3?
(我知道vec4
在这里也可以,但z
和w
与"宽度"one_answers"高度"的含义并不完全相同,这只是一个例子)
我想你只能用glVertexAttribPointer
为每个位置指定一个类型,所以我可以理解为什么结构会被禁止。。。我只是想办法在不影响性能的情况下保持代码的整洁和易理解。
不能有struct
s的顶点着色器输入。
正确的方法是将它们粘在vec4
中。如果使用float[4]
,则需要四个属性,而不是一个。数组总是每个元素占用一个属性。因此,如果执行layout(location = 7) in float[4] TexSrc;
,这将占用属性索引7、8、9和10。这是对属性的严重浪费,而且可能会降低性能。
只需像其他人一样使用vec4
即可。人们总是用vec4
来封装输入;他们用注释来解释任何语义上的奇怪之处。
顺便说一句,如果你得到了一个无效的操作,这可能意味着你实际上没有检查你的着色器是否正确编译和链接。你应该一直这样做。
新事物
OpenGL 4.4或ARB_enhanced_layouts扩展,允许您执行类似的操作。
如前所述,layout(location = 7) in float[4] TexSrc;
的主要问题是它占用了4个输入位置。因此,如果你有4个浮动不是真正的4D矢量,你仍然需要将它们打包到vec4
中,以便运送到着色器中:
layout(location = 7) in vec4 rect;
这使得很难知道rect.z
在着色器中的含义,因为它没有任何明确的含义。
4.4/enhanced_layouts允许您将多个变量打包在一个位置,只要它们的组件不重叠。因此,如果每个位置在概念上都是一个vec4
,我们可以将其划分为2个vec2
s:
layout(location = 7, component = 0) in vec2 rectPos;
layout(location = 7, component = 2) in vec2 rectSize;
现在我们得到一些语义信息。rectPos
是矩形的位置,而rectSize
是矩形的大小。它仍然只占据一个位置。
增强的布局功能可用于任何输入和输出,而不仅仅是顶点着色器。