A shader is a program written in a specialized language (e.g., GLSL - OpenGL Shading Language) that runs on the GPU (Graphics Processing Unit) and is used to control the rendering pipeline in computer graphics applications.
In OpenGL, the shader needs to be compiled at runtime.
GLuint createShader(int shaderType, const char *text) {
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &text, nullptr);
glCompileShader(shader);
return shader;
}
// ShaderType can be GL_FRAGMENT_SHADER, GL_VERTEX_SHADER...
A uniform is a global Shader variable declared with the "uniform" storage qualifier. These act as parameters that the user of a shader program can pass to that program. Their values are stored in a program object.
Uniforms are so named because they do not change from one shader invocation to the next within a particular rendering call thus their value is uniform among all invocations. This makes them unlike shader stage inputs and outputs, which are often different for each invocation of a shader stage.
uniform float example; // Example of declaration
<aside> 🚨 Do not declare a uniform if you don’t use it since OpenGL would remove any non used uniform and it could lead to errors.
</aside>
In order to define a Uniform on the CPU side, we need to first access the reference and then update the value.
<aside> ⚠️ Make sure to have the targeted program activated (using glUseProgram) before doing that.
</aside>
GLuint uniID = glGetUniformLocation(shaderProgram, "example");
glUniform1f(uniID, 0.5f);
//1f to define a float. the end of the function name depends on the type defined
<aside> 🖌️ If you want to access a Texture as a uniform, define the type as sampler2d in the GLSL code and the texture unit id as an integer using glUniform1i.
</aside>