Architecture
The rendering system is organized around these core components:- World (
src/world.h/cpp) - Owns shaders, texture manager, and manages the rendering pipeline - Chunk/Subchunk - Builds optimized meshes with packed vertex data
- Shader System - Minimal GL shader wrapper for program management
- Texture Manager - Handles texture array atlas for all block textures
- Shadow System - Cascaded shadow mapping (CSM) for directional shadows
Render Loop
The main render loop insrc/main.cpp follows this order:
Chunk Meshing
Chunks (16×128×16) are subdivided into subchunks (16×16×16) for efficient updates:- Face culling: Only visible block faces are meshed
- Greedy meshing: Not implemented, uses per-face quads
- Separate buffers: Opaque and translucent geometry use different VBOs
- Packed vertices: All data (position, UV, lighting) packed into 3×
uint32_tper vertex
Vertex Data Format
Each vertex is packed into three 32-bit integers:Lighting Model
MC-CPP uses a colored lighting system with two light sources:Block Light (Artificial)
- Orange/warm tint:
vec3(1.10, 0.85, 0.65) - Emitted by torches, lava, glowstone, etc.
- 16 light levels, propagated using flood-fill queues
Sky Light (Natural)
- Day tint:
vec3(0.85, 0.95, 1.05)(cool blue-white) - Night tint:
vec3(0.25, 0.35, 0.55)(deep blue) - Blended based on day/night cycle
- Propagates downward with no decay, horizontally with decay
colored_lighting/vert.glsl:56):
Smooth Lighting
WhenOptions::SMOOTH_LIGHTING is enabled:
- Per-vertex lighting interpolates light from neighboring blocks
- Ambient occlusion computed from 8 neighboring voxels per face
- Results in softer shadows at block edges
src/chunk/subchunk.cpp:75-150 for AO and smooth lighting implementation.
Rendering Passes
1. Shadow Pass
Renders depth-only to shadow map array (one layer per cascade):- Uses
shadow_shaderwith simplified vertex transformation - Alpha-tested for foliage/transparent blocks
- Outputs to
GL_TEXTURE_2D_ARRAYwithGL_DEPTH_COMPONENT24
2. Opaque Pass
Renders solid blocks front-to-back (chunks sorted by distance):- Samples block texture array on
GL_TEXTURE0 - Samples shadow map array on
GL_TEXTURE1 - Applies colored lighting and shadow factor
3. Translucent Pass
Renders transparent blocks (water, glass, leaves) back-to-front:- Same shader as opaque pass
glDepthMask(GL_FALSE)for correct blending- Alpha blending enabled
Performance Considerations
- Chunk updates: Limited to
Options::CHUNK_UPDATESper frame (default: 4) - Light propagation: Limited to
Options::LIGHT_STEPS_PER_TICKsteps (default: 2048) - Distance sorting: Visible chunks sorted by squared distance for minimal overhead
- Index buffer sharing: Single IBO shared by all chunks
- Texture atlas: Single texture array eliminates texture binding overhead
GL State Management
Critical invariants to maintain:- Texture unit 0 must always hold the block texture array during main rendering
- Texture unit 1 holds the shadow map (when shadows enabled)
- Shadow pass must restore
glDrawBuffer,glReadBuffer, and viewport - Main world shader must be bound before
player.update_matrices()
src/world.cpp:573-673 for the complete render implementation.
Related Pages
- Shader System - Shader loading and uniform management
- Texture Management - Texture atlas and loading
- Lighting System - Colored lighting details
- Shadow Mapping - CSM implementation