Uniforms, Uniform Blocks & Host Communication

Unused uniforms are optimized away (location = -1) — not an error.

15.1 Plain uniforms

Unused uniforms are optimized away (location = -1) — not an error.

uniform float uTime;
uniform vec2 uResolution;
uniform vec3 uLightPos;
uniform mat4 uMVP;
uniform sampler2D uTexture;
uniform Light uLight;          // structs: set each member: "uLight.position"
uniform vec3 uColors[4];       // arrays: "uColors[0]" ...
glUseProgram(prog);
GLint loc = glGetUniformLocation(prog, "uTime");      // cache locations after linking
glUniform1f(loc, (float)glfwGetTime());
glUniform3f(glGetUniformLocation(prog, "uLightPos"), 1.0f, 4.0f, 2.0f);
glUniformMatrix4fv(glGetUniformLocation(prog, "uMVP"), 1, GL_FALSE, glm::value_ptr(mvp));
glUniform1i(glGetUniformLocation(prog, "uTexture"), 0);   // sampler → texture unit 0
glProgramUniform1f(prog, loc, t);                         // DSA: no glUseProgram needed (4.1+)

15.2 Uniform Buffer Objects (UBOs)

Share uniforms across programs and update them efficiently:

layout (std140, binding = 0) uniform CameraBlock {
    mat4 view;
    mat4 projection;
    vec4 cameraPos;        // use vec4 instead of vec3 to avoid padding surprises
    float time;
};
GLuint ubo; glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, sizeof(CameraData), nullptr, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);                   // binding point 0
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(CameraData), &camData);   // update per frame
// Pre-4.20: glUniformBlockBinding(prog, glGetUniformBlockIndex(prog, "CameraBlock"), 0);

15.3 std140 vs std430 layout rules

float, int, uint, bool vec3, vec4 16 (vec3 occupies 12, next scalar can pack after it) array element (scalar/vec2) 16 (rounded up to vec4) 4 × vec4 columns (16 each) rounded up to 16 largest member alignment

Rule of thumb: avoid vec3 in buffers (use vec4), avoid scalar arrays in std140 (pack into vec4 arrays), and mirror the layout with aligned C structs (alignas(16)). std430 (SSBOs, and UBOs with GL_EXT_scalar_block_layout in Vulkan) is tighter.

layout (std140) uniform Example {
    float a;        // offset 0
    vec3 b;         // offset 16 (aligned to 16)
    float c;        // offset 28 (fits after vec3's 12 bytes)
    float arr[3];   // offset 32, stride 16 each! → 48 bytes total
    mat4 m;         // offset 80
};

15.4 Other ways to feed data

Vertex attributes (per-vertex/per-instance data).

Textures / buffer textures (samplerBuffer) for large read-only arrays.

SSBOs (§27) for large read/write data.

Push constants (Vulkan, §32) for small, frequently changing data.

Specialization constants (Vulkan) / #define injection for compile-time options.