7.2. Creating Shader Objects
The design of the OpenGL Shading Language API mimics the process of developing a C or C++ application. The first step is to create the source code. The source code must then be compiled, the various compiled modules must be linked, and finally the resulting code can be executed by the target processor.
To support the concept of a high-level shading language within OpenGL, the design must provide storage for source code, compiled code, and executable code. The solution to this problem is to define two new OpenGL-managed data structures, or objects. These objects provide the necessary storage, and operations on these objects have been defined to provide functionality for specifying source code and then compiling, linking, and executing the resulting code. When one of these objects is created, OpenGL returns a unique identifier for it. This identifier can be used to manipulate the object and to set or query the parameters of the object.
The first step toward utilizing programmable graphics hardware is to create a shader object. This creates an OpenGL-managed data structure that can store the shader's source code. The command to create a shader is
GLuint glCreateShader(GLenum shaderType)
Creates an empty shader object and returns a non-zero value by which it can be referenced. A shader object maintains the source code strings that define a shader. shaderType specifies the type of shader to be created. Two types of shaders are supported. A shader of type GL_VERTEX_SHADER is a shader that runs on the programmable vertex processor; it replaces the fixed functionality vertex processing in OpenGL. A shader of type GL_FRAGMENT_SHADER is a shader that runs on the programmable fragment processor; it replaces the fixed functionality fragment processing in OpenGL.
When created, a shader object's GL_SHADER_TYPE parameter is set to either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER, depending on the value of shaderType.
After a shader object is created, strings that define the shader's source code must be provided. The source code for a shader is provided as an array of strings. The command for defining a shader's source code is
void glShaderSource(GLuint shader,
const GLchar **string,
const GLint *length)
Sets the source code in shader to the source code in the array of strings specified by string. Any source code previously stored in the shader object is completely replaced. The number of strings in the array is specified by count. If length is NULL, then each string is assumed to be null terminated. If length is a value other than NULL, it points to an array containing a string length for each of the corresponding elements of string. Each element in the length array can contain the length of the corresponding string (the null character is not counted as part of the string length) or a value less than 0 to indicate that the string is null terminated. The source code strings are not scanned or parsed at this time; they are simply copied into the specified shader object. An application can modify or free its copy of the source code strings immediately after the function returns.
The multiple strings interface provides a number of benefits, including
A way to organize common pieces of source code (for instance, the varying variable definitions that are shared between a vertex shader and a fragment shader)
A way to share prefix strings (analogous to header files) between shaders
A way to share #define values to control the compilation process
A way to include user-defined or third-party library functions