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