Difference between revisions of "Data Type (GLSL)"
m (Adding missing tag.) 
(→Arrays) 

Line 83:  Line 83:  
Basic types can be grouped into sequences of those elements, called arrays. This generally works like in C/C++, but there are some limitations.  Basic types can be grouped into sequences of those elements, called arrays. This generally works like in C/C++, but there are some limitations.  
+  
+  Arrays usually must be declared with a size. Input arrays to geometry shaders do not need a size. Global variables can be declared without a size, but only if they are later redeclared with a size.  
+  
+  The array size must be a compiletime integral constant expression.  
+  
+  With a few exceptions, arrays can be used for all of the storage qualifiers: inputs, outputs, uniforms, constants, etc. Outputs from the fragment shader cannot be arrays.  
+  
+  The length of an array variable can be computed with the <code>.length()</code> function. For example:  
+  
+  <source lang="cpp">  
+  uniform float myValues[12];  
+  
+  ...  
+  
+  myValues.length(); //Returns 12.  
+  </source>  
+  
+  Arrays can be accessed with arbitrary numeric expressions. They do not have to be compiletime constants (though there are a few exceptions to this rule).  
=== Sampler arrays ===  === Sampler arrays ===  
−  Arrays of sampler types  +  Arrays of sampler types are special. Under GLSL version 3.30, sampler arrays can be declared, but they can only be accessed by compiletime integral constant expressions. So you cannot loop over an array of samplers. 
+  
+  Under GLSL 4.00 and above, sampler arrays can be accessed by noncompiletime constants, but there are still limitations. The value must be "dynamically uniform." This means that the value used to access sampler arrays must be the same, in the same execution order, regardless of any nonuniform parameter values. So the index must be either a compiletime constant, a uniform variable, or an expression composed of only compiletime constants and uniform variables.  
+  
+  For example, in 4.00, it is legal to loop over an array of samplers, so long as the loop index is based on constants and uniforms. So this is legal:  
+  
+  <source lang="cpp">  
+  uniform sampler images[10];  
+  uniform int imageCount;  
+  
+  void main()  
+  {  
+  vec4 accum = vec4(0.0);  
+  for(int i = 0; i < imageCount; i++)  
+  {  
+  accum += texture(images[i], ...);  
+  }  
+  }  
+  </source>  
+  
+  This would add up all of the values in the textures, up to ''imageCount'' in size. Note that this is not legal in GLSL 3.30.  
== Structs ==  == Structs == 
Revision as of 02:56, 25 March 2011
This article is missing information. Further details can be found on the talk page. 
The OpenGL Shading Language defines a number of types. It also defines the means by which users can define types.
Contents
Basic types
Scalars
The basic nonvector types are:
 bool: conditional type, values may be either
true
orfalse
 int: a signed integer
 uint: an unsigned integer
 float: a floating point number
 double: a doubleprecision floatingpoint number
Vectors
Each of the scalar types, including booleans, have 2, 3, and 4component vector equivalents. The n digit below can be 2, 3, or 4:
 bvecn: a vector of booleans
 ivecn: a vector of signed integers
 uvecn: a vector of unsigned integers
 vecn: a vector of singleprecision floatingpoint numbers
 dvecn: a vector of doubleprecision floatingpoint numbers
Vector values can have the same math operators applied to them that scalar values do. These all perform the componentwise operations on each component. However, in order for these operators to work on vectors, the two vectors must have the same number of components.
Swizzling
You can access the components of vectors using the following syntax:
vec4 someVec; someVec.x + someVec.y;
This is called swizzling. You can use x, y, z, or w, referring to the first, second, third, and fourth components, respectively.
The reason it has that name "swizzling" is because the following syntax is entirely valid:
vec2 someVec; vec4 otherVec = someVec.xyxx; vec3 thirdVec = otherVec.zyy;
You can use any combination of up to 4 of the letters to create a vector (of the same basic type) of that length. So otherVec.zyy
is a vec3, which is how we can initialize a vec3 value with it. Any combination of up to 4 letters is acceptable, so long as the source vector actually has those components. Attempting to access the 'w' component of a vec3 for example is a compiletime error.
Additionally, there are 3 sets of swizzle masks. You can use xyzw, rgba (for colors), or stpq (for texture coordinates). These three sets have no actual difference; they're just syntactic sugar.
Matrices
In addition to vectors, there are also matrix types. All matrix types are floatingpoint, either singleprecision or doubleprecision. Matrix types are as follows, where n and m can be the numbers 2, 3, or 4:

matnxm
: A matrix with n columns and m rows. OpenGL uses columnmajor matrices, which is standard for mathematics users. Example:mat3x4
. 
matn
: A symmetric matrix with n columns and rows. This type is equivalent tomatnxn
.
Doubleprecision matrices (GL 4.0 and above) can be declared with a dmat
instead of mat
Swizzling does not work with matrices. You can instead access a matrix's fields with array syntax:
mat3 theMatrix; theMatrix[1] = vec3(3.0, 3.0, 3.0); //Sets the second column to all 3.0s theMatrix[2][0] = 16.0; //Sets the first entry of the third column to 16.0.
Samplers
Texture access is not as simple as reading a value from a memory address. Filtering and other processes are applied to textures, and how texture coordinates are interpreted can be part of the texture access operation. For these reason, texture access is somewhat complicated.
It starts with samplers, a special type that GLSL defines. Each sampler variable represents a texture that is attached to the context. Samplers have a type that defines what kind of texture can be attached to them.
Sampler types cannot be initialized to a value. They cannot have any operations executed on them. They can only be passed as parameters to functions, and variables of sampler types can only be global uniforms (declared outside of interface blocks or as input parameters to functions.
Implicit conversion
Certain values can be implicitly converted to certain types. This means that an explicit construction operation is not necessary.
Signed integers can be implicitly converted to unsigned integers, but the reverse is not true. Either integer type can be converted into floats, and integers and floats can be converted into doubles.
Vector and matrix values are implicitly converted if the basic type they contain is implicitly convertible.
Arrays
Basic types can be grouped into sequences of those elements, called arrays. This generally works like in C/C++, but there are some limitations.
Arrays usually must be declared with a size. Input arrays to geometry shaders do not need a size. Global variables can be declared without a size, but only if they are later redeclared with a size.
The array size must be a compiletime integral constant expression.
With a few exceptions, arrays can be used for all of the storage qualifiers: inputs, outputs, uniforms, constants, etc. Outputs from the fragment shader cannot be arrays.
The length of an array variable can be computed with the .length()
function. For example:
uniform float myValues[12];
...
myValues.length(); //Returns 12.
Arrays can be accessed with arbitrary numeric expressions. They do not have to be compiletime constants (though there are a few exceptions to this rule).
Sampler arrays
Arrays of sampler types are special. Under GLSL version 3.30, sampler arrays can be declared, but they can only be accessed by compiletime integral constant expressions. So you cannot loop over an array of samplers.
Under GLSL 4.00 and above, sampler arrays can be accessed by noncompiletime constants, but there are still limitations. The value must be "dynamically uniform." This means that the value used to access sampler arrays must be the same, in the same execution order, regardless of any nonuniform parameter values. So the index must be either a compiletime constant, a uniform variable, or an expression composed of only compiletime constants and uniform variables.
For example, in 4.00, it is legal to loop over an array of samplers, so long as the loop index is based on constants and uniforms. So this is legal:
uniform sampler images[10];
uniform int imageCount;
void main()
{
vec4 accum = vec4(0.0);
for(int i = 0; i < imageCount; i++)
{
accum += texture(images[i], ...);
}
}
This would add up all of the values in the textures, up to imageCount in size. Note that this is not legal in GLSL 3.30.
Structs
Constructors and initializers
Literals
Values have particular types.
This article is a stub. You can help the OpenGL Wiki by expanding it. 