GLSL arrays
category: code [glöplog]
Is there any way to declare a variable size array on a GLSL shader, or do I have do declare an int n and a vec3 xxx[BIG_NUMBER]?
you can't have variable size arrays in GLSL. From http://www.opengl.org/registry/doc/GLSLangSpec.1.50.09.pdf:
4.1.9 Arrays
Variables of the same type can be aggregated into arrays by declaring a name followed by brackets ( [ ] ) enclosing an optional size. When an array size is specified in a declaration, it must be an integral constant expression (see Section 4.3.3 “Constant Expressions” ) greater than zero. If an array is indexed with an expression that is not an integral constant expression, or if an array is passed as an argument to a function, then its size must be declared before any such use. It is legal to declare an array without a size and then later re-declare the same name as an array of the same type and specify a size. It is illegal to declare an array with a size, and then later (in the same shader) index the same array with an integral constant expression greater than or equal to the declared size. It is also illegal to index an array with a negative
constant expression. Arrays declared as formal parameters in a function declaration must specify a size.
Undefined behavior results from indexing an array with a non-constant expression that’s greater than or equal to the array’s size or less than 0. Only one-dimensional arrays may be declared. All basic types and structures can be formed into arrays. Some examples are:
float frequencies[3];
uniform vec4 lightPosition[4];
light lights[];
const int numLights = 2;
light lights[numLights];
An array type can be formed by specifying a type followed by square brackets ([ ]) and including a size:
float[5]
This type can be used anywhere any other type can be used, including as the return value from a function
float[5] foo() { }
as a constructor of an array
float[5](3.4, 4.2, 5.0, 5.2, 1.1)
as an unnamed parameter
void foo(float[5])
and as an alternate way of declaring a variable or function parameter.
float[5] a;
It is an error to declare arrays of arrays:
float a[5][3]; // illegal
float[5] a[3]; // illegal
Arrays can have initializers formed from array constructors:
float a[5] = float[5](3.4, 4.2, 5.0, 5.2, 1.1);
float a[5] = float[](3.4, 4.2, 5.0, 5.2, 1.1); // same thing
Unsized arrays can be explicitly sized by an initializer at declaration time:
float a[5];
...
float b[] = a; // b is explicitly size 5
float b[5] = a; // means the same thing
However, implicitly sized arrays cannot be assigned to. Note, this is a rare case that initializers and assignments appear to have different semantics.
Arrays know the number of elements they contain. This can be obtained by using the length method:
a.length(); // returns 5 for the above declarations
The length method cannot be called on an array that has not been explicitly sized.
4.1.9 Arrays
Variables of the same type can be aggregated into arrays by declaring a name followed by brackets ( [ ] ) enclosing an optional size. When an array size is specified in a declaration, it must be an integral constant expression (see Section 4.3.3 “Constant Expressions” ) greater than zero. If an array is indexed with an expression that is not an integral constant expression, or if an array is passed as an argument to a function, then its size must be declared before any such use. It is legal to declare an array without a size and then later re-declare the same name as an array of the same type and specify a size. It is illegal to declare an array with a size, and then later (in the same shader) index the same array with an integral constant expression greater than or equal to the declared size. It is also illegal to index an array with a negative
constant expression. Arrays declared as formal parameters in a function declaration must specify a size.
Undefined behavior results from indexing an array with a non-constant expression that’s greater than or equal to the array’s size or less than 0. Only one-dimensional arrays may be declared. All basic types and structures can be formed into arrays. Some examples are:
float frequencies[3];
uniform vec4 lightPosition[4];
light lights[];
const int numLights = 2;
light lights[numLights];
An array type can be formed by specifying a type followed by square brackets ([ ]) and including a size:
float[5]
This type can be used anywhere any other type can be used, including as the return value from a function
float[5] foo() { }
as a constructor of an array
float[5](3.4, 4.2, 5.0, 5.2, 1.1)
as an unnamed parameter
void foo(float[5])
and as an alternate way of declaring a variable or function parameter.
float[5] a;
It is an error to declare arrays of arrays:
float a[5][3]; // illegal
float[5] a[3]; // illegal
Arrays can have initializers formed from array constructors:
float a[5] = float[5](3.4, 4.2, 5.0, 5.2, 1.1);
float a[5] = float[](3.4, 4.2, 5.0, 5.2, 1.1); // same thing
Unsized arrays can be explicitly sized by an initializer at declaration time:
float a[5];
...
float b[] = a; // b is explicitly size 5
float b[5] = a; // means the same thing
However, implicitly sized arrays cannot be assigned to. Note, this is a rare case that initializers and assignments appear to have different semantics.
Arrays know the number of elements they contain. This can be obtained by using the length method:
a.length(); // returns 5 for the above declarations
The length method cannot be called on an array that has not been explicitly sized.
I'm doing this
So, defining a variable amount of apples is still impossible?
Quote:
uniform float apples[32];
uniform int banana;
(...)
for(int carrot=0; carrot<banana; ++carrot)
Eat(apples[carrot]);
So, defining a variable amount of apples is still impossible?
just use a texture for bob's sake. this whole high level shader language thing is so sickening.
xernobyl: that will work, yes... just be careful not to mess around with your carrot too much. IIRC, in shader model 3 and lower, arrays are unrolled into that many variables, so there's no real "indexing" being done.
... an for model 2 If I'm correct, your banana value must be static. Anduse a texture as a table for bob's sake :+1.
well, what xernobyl said, and also you could have a look at these, i'm guessing they're pretty useful in this situation (iq only focuses on the GLSL side which is a mistake obviously here, and well, people also know reading the GLSL language reference manual).
EXT_bindable_uniform
EXT_texture_buffer_object
EXT_bindable_uniform
EXT_texture_buffer_object
the interrest of texture buffer objects is that
Quote:
While buffer textures can be substantially larger than equivalent
one-dimensional textures; the maximum texture size supported for buffer
textures in the initial implementation of this extension is 2^27 texels,
versus 2^13 (8192) texels for otherwise equivalent one-dimensional
textures.
Well, i just bump this thread to mention this article, uniform buffers vs texture buffers.
and to quote the most important results, (also in case their site doesn't work),
and to quote the most important results, (also in case their site doesn't work),
Quote:
Uniform Buffers
Maximum size: 64KByte (or more)
Memory access pattern: coherent access
Memory storage: usually local memory
Quote:
Texture Buffers
Maximum size: 128MByte (or more)
Memory access pattern: random access
Memory storage: global texture memory
Quote:
Uniform Buffers - Maximum size: 64KByte (or more)
i don't think my uberpowerful GMA950 can do that...
Well, indeed, and it's sad.
But according to the december 2009 steam hardware survey, intel graphic chips amount for 3,6% of steam users (which are quite representative of gamers machines nowadays).. so you can honestly just ignore intel GMA users. The other interesting fact is that 70% of people have a shader model 4 compatible graphics card (but only 45% of these have vista or win7 which enables the developers to use the full feature set only in that case under d3d 10 - i don't mean that geometry shaders are useful no, but texture arrays and rendering to 3d textures is quite interesting for nowadays 3d engines, and afaik it's only possible under d3d10 (can't wait for the D3D fanboys to scream for the scandal if i mistake here lol)). You can get however the whole feature set in opengl and target 70% of users with just one graphics codepath, in your 3d renderer though..
Steam Hardware Survey: December 2009
But according to the december 2009 steam hardware survey, intel graphic chips amount for 3,6% of steam users (which are quite representative of gamers machines nowadays).. so you can honestly just ignore intel GMA users. The other interesting fact is that 70% of people have a shader model 4 compatible graphics card (but only 45% of these have vista or win7 which enables the developers to use the full feature set only in that case under d3d 10 - i don't mean that geometry shaders are useful no, but texture arrays and rendering to 3d textures is quite interesting for nowadays 3d engines, and afaik it's only possible under d3d10 (can't wait for the D3D fanboys to scream for the scandal if i mistake here lol)). You can get however the whole feature set in opengl and target 70% of users with just one graphics codepath, in your 3d renderer though..
Steam Hardware Survey: December 2009
Quote:
so you can honestly just ignore intel GMA users
except that i'm myself a GMA user, and i can hardly ignore *that*...
blala: but you weren't the one asking the question.
that's true. But hijacking pouet threads is as close to the meaning of life as it gets!!
At the moment I the end user is me. If it works on my machine that's awesome.
Quote:
hijacking pouet threads
seriously... if you don't want to hear about me, then ban me. it will save my time. so it's good & ok to me.
but i find it "funny" really how people's point of view can change from one person to another who posts. If the nickname was "iq", with the same speech, everyone would applause and lick my penis.. it seems i'm the little nystep black sheep of pouet, i have no idea how it happened, but i don't care what people think about me here. :)
that's it!
bye :)
huh? i was talking about myself hijacking, not you :)
Dramaqueen.
( ..)
o_O
What I understood Xernobyl was asking is "Is there any way to declare a variable size array on a GLSL shader". It's long I don't write shaders, but iirc
can't be done. I think the question was very clearl that, at least xernobyl made it again: "So, defining a variable amount of apples is still impossible?". The answer seems to be "yes" to me, that's why the solution himself proposes seems ok to me: "do I have do declare an int n and a vec3 xxx[BIG_NUMBER]".
Now, of course, use your favourite tech to provide a xxx[BIG_NUMBER], be it the old uniform arryas, regular textures, uniform buffers or texture buffer. Given that we are speaking of 32 apples here, not 2^27, imho focusing on just-listing-the-last-extensions-cause-I-know-them is a mistake obviously here, the proper answer (that nobody clearly gave) would have been: "yes, use your proposed method with the regular uniform arrays just are you are doing"
Bad morning!
Code:
uniforrm int numApples;
uniform float apples[numApples];
uniform int banana; // banana<=numApples
(...)
for(int carrot=0; carrot<banana; ++carrot)
Eat(apples[carrot]);
can't be done. I think the question was very clearl that, at least xernobyl made it again: "So, defining a variable amount of apples is still impossible?". The answer seems to be "yes" to me, that's why the solution himself proposes seems ok to me: "do I have do declare an int n and a vec3 xxx[BIG_NUMBER]".
Now, of course, use your favourite tech to provide a xxx[BIG_NUMBER], be it the old uniform arryas, regular textures, uniform buffers or texture buffer. Given that we are speaking of 32 apples here, not 2^27, imho focusing on just-listing-the-last-extensions-cause-I-know-them is a mistake obviously here, the proper answer (that nobody clearly gave) would have been: "yes, use your proposed method with the regular uniform arrays just are you are doing"
Bad morning!
(I have a bad morning, I mean!)
Good morning to you too! And thanks.
Hi, guys! I'm trying to emulate stack operations (for the Forth translator). Please, check the line of GLSL code. Stack is "a" array and "pop" is a shift/roll function.
It was a bad idea, right? Looks like all that "a[n]=a[m]" runs in parallel (i.e. in random order).
Is there any solution?
Code:
void pop(out float a[8], out int k) { a[0]=a[1]; a[1]=a[2]; a[2]=a[3]; a[3]=a[4]; a[4]=a[5]; a[5]=a[6]; a[6]=a[7]; a[7]=0.0; k--; }
It was a bad idea, right? Looks like all that "a[n]=a[m]" runs in parallel (i.e. in random order).
Is there any solution?
Update: Ized/Quite suggested to use "inout" instead of "out". It suddenly helps.