Reputation: 7190
I wonder if I may have something like this:
layout (location = attr.POSITION) in vec3 position;
Where for example Attr
is a constant structure
const struct Attr
{
int POSITION;
} attr = Attr(0);
I already tried, but it complains
Shader status invalid: 0(34) : error C0000: syntax error, unexpected integer constant, expecting identifier or template identifier or type identifier at token ""
Or if there is no way with structs, may I use something else to declare a literal input qualifier such as attr.POSITION
?
Upvotes: 1
Views: 1300
Reputation: 473352
GLSL has no such thing as a const struct
declaration. It does however have compile time constant values:
const int position_loc = 0;
The rules for constant expressions say that a const-qualified variable which is initialized with a constant expression is itself a constant expression.
And there ain't no rule that says that the type of such a const-qualified variable must be a basic type:
struct Attr
{
int position;
};
const Attr attr = {1};
Since attr
is initialized with an initialization list containing constant expressions, attr
is itself a constant expression. Which means that attr.position
is an constant expression too, one of integral type.
And such a compile-time integral constant expression can be used in layout qualifiers, but only if you're using GLSL 4.40 or ARB_ehanced_layouts:
layout(location = attr.position) in vec3 position;
Before that version, you'd be required to use an actual literal. Which means the best you could do would be a #define
:
#define position_loc 1
layout(location = position_loc) in vec3 position;
Now personally, I would never rely on such integral-constant-expression-within-struct gymnastics. Few people rely on them, so driver code rarely gets tested in this fashion. So the likelihood of encountering a driver bug is fairly large. The #define
method is far more likely to work in practice.
Upvotes: 2