Shaders are written in the OpenGL Shading Language (GLSL). This section is about compiling, linking and using them. In OpenGL a shader is a vertex shader or fragment shader. Then they are combined into a program and it is the program that is used to render with.
When you create a shader select the type of shader. The most common ones are GL_VERTEX_SHADER and GL_FRAGMENT_SHADER. After a program is linked it is possible to delete the shader object. Like a c executable you do not need to keep the source when you have the exe to run.
Set source and compile
Provide the source to the shader with glShaderSource and it can be made up multiple sections. Then compile it with glCompileShader.
Check the result of compilation
To check if the compile worked use glGetShaderiv to check for the GL_COMPILE_STATUS to be true. If not use glGetShaderInfoLog to get the log with the errors. GL_INFO_LOG_LENGTH can be used on glGetShaderiv to get the size of the log.
Attatch the compiled shader objects to the program object and then link it.
Check the result of Link
To verify the link use glGetProgramriv to check that GL_LINK_STATUS is GL_TRUE. Get the program info log with glGetProgramInfoLog if it fails.
A program is used by calling glUseProgram. Calling it with zero unbinds the program.
Set Shader Uniforms
Each uniform has a location in a form of a integer. To get the location use glGetUniformLocation. With the location it is possible to set the value with glUniform*. It takes the value to set it to and the location of the uniform. For textures assign the texture to a texture unit. Then assign the id of the texture unit to the uniform variable.
Set Color numbers
The shader will output a number of color variables and glGetFragDataLocation is used to get the color number for a variable. That color number is then used in glDrawBuffers to select what color buffer the variable should write to.
Using a Interface Block in GLSL it is possible to fill in it with the content of a uniform buffer. In the program each Interface Block get's it's own block index. It is possible to query the program for it with glGetUniformBlockIndex or to set it with a layout in the shader. Then use the glUniformBlockBinding to Interface Block to use a binding index. The binding index is part of the OpenGL context and buffers are bound to the using glBindBufferBase with target GL_UNIFORM_BUFFER.
When storing the data in the uniform buffer the correct memory layout needs to be used. There are four to select from, packed, shared, std140 and std430. Shared is the default one. If using packed or shared the driver pack things as it please and query functions must be used to get the correct positions to put things in the buffer. With std140 and std430 there are some rules on need to follow.
Program pipeline object