GLSL“in”结构

mpe*_*pen 4 opengl glsl

我不允许使用带有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也可以在这里工作,但zw“宽度”和“高度”的含义并不完全相同,这只是一个示例)

我想你只能用 为每个位置指定一个类型glVertexAttribPointer,所以我可以理解为什么不允许使用结构......我只是想办法在不影响性能的情况下保持我的代码干净整洁。

Nic*_*las 5

你不能有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是它的大小。而且它仍然只占据一个位置。

增强的布局功能使其适用于任何输入和输出,而不仅仅是顶点着色器。