GLSL Object

From OpenGL.org
Jump to: navigation, search

A GLSL Object is an object in the OpenGL API that encapsulates the compiled or linked Shaders that execute portions of the OpenGL Pipeline. These objects represent code written in the OpenGL Shading Language (GLSL). Though they are called "objects", most of them do not fit within the OpenGL Object paradigm.

Program objects

A Program Object represents fully processed executable code, in the OpenGL Shading Language, for one or more Shader stages. A program object is an object in OpenGL, but it does not use the standard OpenGL Object model.

Creation

Empty program objects are created with this function:

GLuint glCreateProgram()

This will return an empty program object. Programs are deleted with glDeleteProgram.

Empty program objects must then be filled in with executable code. This is done by compiling linking shaders into the program, or by uploading binary, pre-compiled data from a previously-created program object.

Pre-link setup

Before performing the linking steps for a program, it is sometimes important to provide certain settings that affect the final linking step. These operations assign resource numbers to interface elements in a shader. More recent OpenGL features allow these resources to be assigned in the shader text itself.

Introspection

After a program has been successfully linked, information about the various interfaces can be queried. This allows the user to know how to set Uniform values, determine which Vertex Attributes the program takes (if any), and other similar resources.

State setting

Outside of the state used by the pre-link setup, program objects have the following mutable state:

Note that the last two pieces of state only need to be set if you did not set them directly in the shader.

Shader objects

Shader objects represent compiled GLSL code for a single shader stage. The code may not be the complete code for a shader stage; the complete code can be assembled from multiple shader objects that contain source code for the same stage. Shader objects are not OpenGL Objects, but they are objects.

Shader objects are created with this function:

GLuint glCreateShader(GLenum shaderType​);

The shaderType​ defines which shader stage the shader object holds code for. The enumerator is one of the standard shader stage enumerators.

Shader objects do not store very much state. They contain a set of strings, which represent the source code for that shader stage (retrieved with glGetShaderSource). They also store whether the most recent compilation to this shader object was successful (retrieved with glGetShader(GL_COMPILE_STATUS)), as well as error messages generated by that compilation if it failed (retrieved with glGetShaderInfoLog).

Conceptually, they lastly store the GLSL object code from the most recent compilation. This latter state cannot be queried, but it is accessed by the program object linking process when linking with one or more shader objects.

Shader objects are deleted with the glDeleteShader function. Though they are not OpenGL Objects, they can be orphaned, if they are attached to a program object before they are deleted.

Program pipeline objects

Successfully linked separable programs are intended to be used with program pipeline objects. A pipeline object is an OpenGL Object that contains separable program objects. When a pipeline is active, the Shader Stage code defined by the programs in the pipeline become the shader stages used in various operations.

Unlike program or shader objects, pipeline objects follow the standard OpenGL Object conventions. Therefore, there is a glGenProgramPipelines function to create new pipeline names, a glDeleteProgramPipelines to delete them, and a glBindProgramPipeline to bind it to the context. Program pipeline objects do not have targets, so the last function only takes the pipeline to be bound.

However, unlike most OpenGL objects, when a name is created for a pipeline, the object's data is also created. So you do not have to bind the pipeline before trying to use it. Similar to Sampler Objects, program pipeline objects should only be bound when you intend to render with them (or set uniforms through them, as described below).

The primary state in program pipeline objects are the list of programs that contain the code for the various shader stages. This state is set by this function:

void glUseProgramStages(GLuint pipeline​, GLbitfield stages​, GLuint program​);

The given pipeline​ will get the shader code for the shader stages defined by the bitfield stages​ from the given program​. The program​ parameter must either be 0 or a separable program that has been successfully linked as such.

The stages​ bitfield determines which Shader Stages from program​ will provide code for those shader stages in the pipeline. These bits can be a combination of:

  • GL_VERTEX_SHADER_BIT​
  • GL_TESS_CONTROL_SHADER_BIT​
  • GL_TESS_EVALUATION_SHADER_BIT​
  • GL_GEOMETRY_SHADER_BIT​
  • GL_FRAGMENT_SHADER_BIT​
  • GL_COMPUTE_SHADER_BIT​.

The bitfield can also be GL_ALL_SHADER_BITS​, which is equivalent to all of the above.

The stages of program​ attached to the pipeline​ are only those stages specified by the bitfield. If program​ is 0, then the specified stages are cleared from the pipeline.

Program pipeline objects are container objects. As such, they cannot be shared across multiple OpenGL contexts.

Uniforms and pipelines

Recommendation: The following explains a highly convoluted way to use glBindProgramPipeline to allow the user to set uniform state for one of the programs within a pipeline. You are strongly advised to ignore this section. Instead, when writing new code, use glProgramUniform to set uniforms directly into programs without having to bind or use the program. Only use this if you absolutely must remain backwards compatible with some functions that set uniforms on a program that is currently in use, and yet somehow can't temporarily use glUseProgram.

glUniform changes uniform state on the currently used program. However, with separate programs and program pipelines, the definition of "currently used program" is much more complicated. It works as follows.

If no program object is in use via glUseProgram, then the currently bound program pipeline is checked. If there is a bound program pipeline, then the program object which is considered "active" in that pipeline is used as the destination for glUniform calls.

The active program for a pipeline is set by this function:

void glActiveShaderProgram(GLuint pipeline​, GLuint program​);

program​ must be a valid, successfully linked program object. It may not be zero; you cannot unset an active program once you set it onto the pipeline.

Note: Silly though it may seem, program​ does not have to be attached to pipeline​ for this to work. A pipeline can have a completely unrelated program as its active program.

Program usage

In order to use the shader stages that a program encapsulates, you must first bind the program object to the OpenGL Context. Unlike standard OpenGL Objects, program objects are bound to the context with this function:

void glUseProgram(GLuint program​);

This will bind the program​ to the current context, unbinding the previously bound program object. If it is zero, then no program is bound to the context.

While a program object is bound to the context, all drawing commands (and compute dispatch operations with OpenGL 4.3 or ARB_compute_shader) will be rendered using the shaders linked into that program, as well as whatever state is set into that program.

If OpenGL 4.1 or ARB_separate_shader_objects is available and you wish to use the programs within a program pipeline, the first step is to unbind any programs with glUseProgram(0). If a program is bound with glUseProgram, then any bound program pipelines will be ignored.

Then, bind the program pipeline object with:

glBindProgramPipeline(GLuint pipeline​);

pipeline​ is the program pipeline object to bind. When this is done, the shader code and uniform state will come from the programs stored within the pipeline object.

Reference