Help end child hunger

Data Types and Variables

 
Prev: Attribute Variables Next: Statements and Functions
 

The following simple data types are available in GLSL:

  • float
  • bool
  • int

Float and int behave just like in C, whereas the bool type can take on the values of true or false.

Vectors with 2,3 or 4 components are also available for each of the simple data types mentioned above. These are declared as:

  • vec{2,3,4} a vector of 2,3,or 4 floats
  • bvec{2,3,4} bool vector
  • ivec{2,3,4} vector of integers

Square matrices 2×2, 3×3 and 4×4 are provided since they are heavily used in graphics. The respective data types are:

  • mat2
  • mat3
  • mat4

A set of special types are available for texture access. These are called samplers and are required to access texture values, also known as texels.

The data types for texture sampling are:

  • sampler1D – for 1D textures
  • sampler2D – for 2D textures
  • sampler3D – for 3D textures
  • samplerCube – for cube map textures
  • sampler1DShadow – for shadow maps
  • sampler2DShadow – for shadow maps

In GLSL, arrays can be declared using the same syntax as in C. However arrays can’t be initialized when declared. Accessing array’s elements is done as in C.

Structures are also allowed in GLSL. The syntax is the same as C.

struct dirlight {

	vec3 direction;
	vec3 color;
};

Variables

Declaring a simple variable is pretty much the same as in C, you can even initialize a variable when declaring it.

float a,b;		// two vector (yes, the comments are like in C)
int c = 2;		// c is initialized with 2
bool d = true;	// d is true

Declaring the other types of variables follows the same pattern, but there are differences between GLSL and C regarding initialization. GLSL relies heavily on constructor for initialization and type casting.

float b = 2;		// incorrect, there is no automatic type casting
float e = (float)2;// incorrect, requires constructors for type casting

int a = 2;
float c = float(a); // correct. c is 2.0

vec3 f;		// declaring f as a vec3
vec3 g = vec3(1.0,2.0,3.0); // declaring and initializing g

GLSL is pretty flexible when initializing variables using other variables. All that it requires is that you provide the necessary number of components. Look at the following examples.

vec2 a = vec2(1.0,2.0);
vec2 b = vec2(3.0,4.0);

vec4 c = vec4(a,b) // c = vec4(1.0,2.0,3.0,4.0);

vec2 g = vec2(1.0,2.0);

float h = 3.0;

vec3 j = vec3(g,h);

Matrices also follow this pattern. You have a wide variety of constructors for matrices. For instance the following constructors for initializing a matrix are available:

mat4 m = mat4(1.0) // initializing the diagonal of the matrix with 1.0

vec2 a = vec2(1.0,2.0);
vec2 b = vec2(3.0,4.0);

mat2 n = mat2(a,b); // matrices are assigned in column major order

mat2 k = mat2(1.0,0.0,1.0,0.0); // all elements are specified

The declaration and initialization of structures is demonstrated below:

struct dirlight {		// type definition
	vec3 direction;
	vec3 color;
};

dirlight d1;

dirlight d2 = dirlight(vec3(1.0,1.0,0.0),vec3(0.8,0.8,0.4));

In GLSL a few extras are provided to simplify our lives, and make the code a little bit clearer. Accessing a vector can be done using letters as well as standard C selectors.

vec4 a = vec4(1.0,2.0,3.0,4.0);

float posX = a.x;
float posY = a[1];

vec2 posXY = a.xy;

float depth = a.w

As shown in the previous code snippet, it is possible to use the letters x,y,z,w to access vectors components. If you’re talking about colors then r,g,b,a can be used. For texture coordinates the available selectors are s,t,p,q. Notice that by convention, texture coordinates are often referred as s,t,r,q. However r is already being used as a selector for “red” in RGBA. Hence there was a need to find a different letter, and the lucky one was p.

Matrix selectors can take one or two arguments, for instance m[0], or m[2][3]. In the first case the first column is selected, whereas in the second a single element is selected.

As for structures the names of the elements of the structure can be used as in C, so assuming the structures described above the following line of code could be written:

d1.direction = vec3(1.0,1.0,1.0);

Variable Qualifiers

Qualifiers give a special meaning to the variable. The following qualifiers are available:

  • const – The declaration is of a compile time constant
  • attribute – Global variables that may change per vertex, that are passed from the OpenGL application to vertex shaders. This qualifier can only be used in vertex shaders. For the shader this is a read-only variable. See Attribute section
  • uniform – Global variables that may change per primitive (may not be set inside glBegin,/glEnd), that are passed from the OpenGL application to the shaders. This qualifier can be used in both vertex and fragment shaders. For the shaders this is a read-only variable. See Uniform section
  • varying – used for interpolated data between a vertex shader and a fragment shader. Available for writing in the vertex shader, and read-only in a fragment shader. See Varying section.

 

Prev: Attribute Variables Next: Statements and Functions
 

  2 Responses to “Data Types and Variables”

  1. It seems to me that all communication with shaders is going only in one direction – from our program to shaders. How can I read some data that was created by shaders? For example, If I need to know the value of gl_Position variable how can I retrieve it?

    Is there a way a shader could write data to a piece of memory that could be read from the “main” program?

    • Yes there is, but it is far different from reading back a variable. You can write values to textures, read back the frame buffer, use transform feedback to store values in buffers, among other possibilities

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: