OpenGL Cheatsheet
The Rendering Pipeline
Use this OpenGL reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Pipeline Overview
Data flows from CPU → GPU through a fixed sequence of stages. Programmable stages are written in GLSL; fixed-function stages are configured with GL state calls.
CPU (vertex data, uniforms) │ ▼ [Vertex Shader] ← programmable │ ▼ [Tessellation Control] ← programmable (optional, GL 4.0+) │ ▼ [Tessellation Evaluation]← programmable (optional, GL 4.0+) │ ▼ [Geometry Shader] ← programmable (optional) │ ▼ [Primitive Assembly + Clipping] ← fixed │ ▼ [Rasterization] ← fixed │ ▼ [Fragment Shader] ← programmable │ ▼ [Per-Fragment Tests] ← fixed (scissor, stencil, depth) │ ▼ [Blending / Framebuffer Write] ← semi-programmable (blend eq)
Vertex Shader
Runs once per vertex. Must write gl_Position.
#version 460 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec2 aUV; uniform mat4 uMVP; out vec2 vUV; void main() { vUV = aUV; gl_Position = uMVP * vec4(aPos, 1.0); }
Vertex shader built-ins
| Built-in | Type | R/W | Description |
|---|---|---|---|
gl_Position | vec4 | W | Clip-space position (required) |
gl_PointSize | float | W | Point sprite size (px); needs GL_PROGRAM_POINT_SIZE |
gl_VertexID | int | R | Index of the current vertex |
gl_InstanceID | int | R | Instance index (instanced rendering) |
gl_BaseVertex | int | R | basevertex from glDrawElementsBaseVertex |
gl_BaseInstance | int | R | baseinstance from glDrawArraysInstancedBaseInstance |
Tessellation Shaders (GL 4.0+)
Two-stage: control decides the tessellation level; evaluation computes final position.
// Tessellation Control Shader #version 460 core layout(vertices = 3) out; // output patch size (3 = triangle) void main() { gl_TessLevelOuter[0] = 4.0; gl_TessLevelOuter[1] = 4.0; gl_TessLevelOuter[2] = 4.0; gl_TessLevelInner[0] = 4.0; gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; }
// Tessellation Evaluation Shader #version 460 core layout(triangles, equal_spacing, ccw) in; void main() { vec3 p = gl_TessCoord.x * gl_in[0].gl_Position.xyz + gl_TessCoord.y * gl_in[1].gl_Position.xyz + gl_TessCoord.z * gl_in[2].gl_Position.xyz; gl_Position = vec4(p, 1.0); }
TES layout qualifiers
| Qualifier | Options |
|---|---|
| Primitive | triangles, quads, isolines |
| Spacing | equal_spacing, fractional_even_spacing, fractional_odd_spacing |
| Winding | cw, ccw |
| Point mode | point_mode (emit a point per tessellated vertex) |
Geometry Shader
Runs per-primitive. Can emit different primitive types or amplify geometry.
#version 460 core layout(triangles) in; // input primitive layout(triangle_strip, max_vertices = 3) out; // output in vec2 vUV[]; // arrays — one element per input vertex out vec2 gUV; void main() { for (int i = 0; i < 3; i++) { gUV = vUV[i]; gl_Position = gl_in[i].gl_Position; EmitVertex(); } EndPrimitive(); }
Geometry shader input/output layout tokens
| Stage | Input tokens | Output tokens |
|---|---|---|
| Input | points, lines, lines_adjacency, triangles, triangles_adjacency | — |
| Output | — | points, line_strip, triangle_strip |
Fragment Shader
Runs once per rasterized fragment (candidate pixel). Writes to output variables.
#version 460 core in vec2 vUV; uniform sampler2D uTex; out vec4 FragColor; // location 0 by default void main() { FragColor = texture(uTex, vUV); }
Fragment shader built-ins
| Built-in | Type | Description |
|---|---|---|
gl_FragCoord | vec4 | Window-space coords (x, y, z=depth, w=1/clip-w) |
gl_FrontFacing | bool | True if front face |
gl_FragDepth | float | Override depth write (disables early-Z) |
gl_SampleID | int | Sample index (requires multisampled FBO) |
gl_SamplePosition | vec2 | Sub-pixel sample location |
gl_ClipDistance[i] | float[] | User clip planes (set in vertex stage) |
Compute Shader (GL 4.3+)
Not part of the graphics pipeline — dispatched separately.
#version 460 core layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; layout(rgba32f, binding = 0) uniform image2D uOutput; void main() { ivec2 coord = ivec2(gl_GlobalInvocationID.xy); imageStore(uOutput, coord, vec4(1.0)); }
glUseProgram(computeProgram); glDispatchCompute(width / 16, height / 16, 1); // groups, not invocations glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // before reading output
Compute built-ins
| Built-in | Type | Description |
|---|---|---|
gl_NumWorkGroups | uvec3 | Total groups dispatched |
gl_WorkGroupID | uvec3 | This group's index |
gl_LocalInvocationID | uvec3 | Thread index within group |
gl_GlobalInvocationID | uvec3 | WorkGroupID * WorkGroupSize + LocalInvocationID |
gl_LocalInvocationIndex | uint | Flattened local index |
gl_WorkGroupSize | uvec3 | From layout qualifier |
Fixed-Function: Primitive Assembly
// Specify how vertices are wound for face culling glFrontFace(GL_CCW); // GL_CCW (default) or GL_CW // Cull faces glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // GL_BACK (default), GL_FRONT, GL_FRONT_AND_BACK
Fixed-Function: Rasterization
glLineWidth(2.0f); // line width in pixels (≥1.0) glPointSize(5.0f); // when GL_PROGRAM_POINT_SIZE is disabled glEnable(GL_PROGRAM_POINT_SIZE); // let vertex shader set gl_PointSize // Polygon offset (for shadow maps / decals) glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(factor, units); // depth bias = factor * maxSlope + units * r // Wireframe / point mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // default glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // vertices only
Pipeline Object (Separate Shader Stages, GL 4.1+)
Allows mixing shader stages from different programs.
// Create separable program GLuint prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertSrc); // Build pipeline GLuint pipeline; glGenProgramPipelines(1, &pipeline); glBindProgramPipeline(pipeline); glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vertProg); glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, fragProg);
Stage bit flags
| Flag | Stage |
|---|---|
GL_VERTEX_SHADER_BIT | Vertex |
GL_TESS_CONTROL_SHADER_BIT | Tessellation control |
GL_TESS_EVALUATION_SHADER_BIT | Tessellation evaluation |
GL_GEOMETRY_SHADER_BIT | Geometry |
GL_FRAGMENT_SHADER_BIT | Fragment |
GL_COMPUTE_SHADER_BIT | Compute |
GL_ALL_SHADER_BITS | All stages |
Gotcha:
glUseProgram(0)is needed to reactivate a pipeline object after callingglUseProgramwith a monolithic program. The two APIs compete.