Kevin Kostlan
Kevin Kostlan

Reputation: 3519

GLSL global variables

GLSL has many global variables that are predefined such as gl_LightSource. They are global because any shader can access them.

How do I define custom global variables in GLSL?

Upvotes: 6

Views: 19863

Answers (4)

Robert Rouhani
Robert Rouhani

Reputation: 14688

Global variables don't exist in GLSL. The gl_* variables are hardcoded variables (think of them as automatically added compile-time) to access non-programmable elements of the pipeline from a shader. In Core OpenGL 3.0 most of them were removed, including gl_LightSource. The user is now expected to handle his own matrices and lights and send them to the shaders as uniforms. For a complete list, see the Built-in Variable (GLSL) wiki.

What you want are uniforms. If you want to synchronize uniforms between shaders, store the location of the uniform and iterate through all your programs to upload the uniform to each shader.

Upvotes: 8

user2262111
user2262111

Reputation: 581

The usefulness of persistent variables is definitely something to aspire. OpenGL introduced instancing as part of the gl3, but was actually fully modeled in gl4. This answer's intent is to expand on the other answers as well as inform about instanced VBOs.

If you have access to gl4, you can keep an instanced VBO loaded with data that can change per draw (as opposed to per vertex) if its for something such as a tiled map. You can utilize the GLSL variable gl_InstanceID to detect which draw call you are on.

In the case of a tiled map, you use one model (probably 2 triangles aka 4 points, 4 texcoords, 6 indices to form a quad) to render a lot of tiles. You can update the values of said VBO easily cpu-side using normal gl buffer functions. The VBO can hold something like the tileid, which helps you calculate the texture coordinates indexing the tilesheet for the specified tile. The benefit is it updates per instance.

The typical use case of 'saving variables between draws' usually comes down to needing a counter, and gl_InstanceID definitely fits the bill. That is unless you need the GPU to do something that needs to be saved back.

If what you are after is calculating on the GPU, UBOs are a very nice way to get data to and from the GLSL shader. As @Arne suggested. However, there may be some way using other means to do what you are trying to do and they should be avoided in general use unless you actually use a lot of uniform variables.

If you are trying to define a constant variable, you can use the const keyword. However, this doesn't persist between shaders. Only the shader it is defined on.

const float example = 5.0;

Upvotes: 0

Arne
Arne

Reputation: 8509

You can use uniform buffers. Here is a tutorial: http://www.lighthouse3d.com/tutorials/glsl-tutorial/uniform-blocks/

Upvotes: 6

Cat Plus Plus
Cat Plus Plus

Reputation: 130004

Global shader variables in OpenGL are called "uniforms". They're read-only and can be bound with glUniformX calls. Roughly, it looks like this (this is more of a pseudocode):

// 1. activate the program
glUseProgram(program)

// 2. get uniform location
foo = glGetUniformLocation(program, "foo")

// 3. bind the value, e.g. a single float
glUniform1f(foo, 42.0)

Within the shaders, you need to qualify the variable with uniform storage qualifier, e.g.

uniform float foo;

Upvotes: 2

Related Questions