@ -18,9 +18,9 @@
## Project Overview
**GLTerrain** is an isometric terrain generator using OpenGL, Pygame, and Perlin noise. It creates procedurally generated 3D terrains with RollerCoaster Tycoon-style isometric view, biome-based coloring, and real-time camera controls.
**GLTerrain** is an isometric terrain generator using OpenGL, Pygame, and Perlin noise. It creates procedurally generated 3D terrains with RollerCoaster Tycoon-style isometric view, biome-based coloring, procedural pixelated textures, and real-time camera controls.
**Version**: 1.0 .0
**Version**: 1.1 .0
**Language**: Python 3.13+
**Graphics**: OpenGL with Pygame
@ -28,303 +28,153 @@
**IMPORTANT**: This project uses a Python virtual environment located at `./venv` .
### Before Running Any Python Script:
1. **Always activate the virtual environment** :
```bash
source venv/bin/activate & & python < script _name . py >
```
2. **For installing packages** :
```bash
source venv/bin/activate & & pip install -r requirements.txt
```
### Standard Command Pattern:
```bash
cd /home/enne2/Sviluppo/shader & & source venv/bin/activate & & python main.py
```
### DO NOT:
- Run Python scripts without activating the virtual environment
- Install packages globally
- Modify code without testing with activated venv
**DO NOT** run Python scripts without activating the virtual environment.
## Project Architecture
### Directory Structure:
```
shader/
├── main.py # Entry point (uses modular architecture)
├── isometric_terrain.py # Legacy monolithic version (preserved)
├── requirements.txt # Python dependencies
├── main.py # Entry point
├── isometric_terrain.py # Legacy version (preserved)
├── requirements.txt
├── config/
│ └── settings.py # All configuration (TERRAIN, CAMERA, RENDERING, BIOMES)
│ └── settings.py # All configuration
├── src/
│ ├── app.py # Main application coordinator
│ ├── camera/
│ │ └── camera.py # Camera positioning and controls
│ ├── terrain/
│ │ └── generator.py # Perlin noise terrain generation
│ └── rendering/
│ └── terrain_renderer.py # OpenGL mesh rendering
│ ├── app.py # Main application
│ ├── camera/camera.py # Camera controls
│ ├── terrain/generator.py # Perlin noise terrain
│ └── rendering/terrain_renderer.py # OpenGL + textures
└── docs/ # Italian documentation (8 chapters)
├── README.md # Index with navigation
├── 01-introduzione.md
├── 02-concetti-base.md
├── 03-opengl.md
├── 04-perlin-noise.md
├── 05-implementazione.md
├── 06-rendering.md
├── 07-camera.md
└── 08-personalizzazione.md
```
### Dependencies:
- **pygame** >= 2.5.0: Window management and event handling
- **PyOpenGL** >= 3.1.7: OpenGL bindings for 3D rendering
- **PyOpenGL-accelerate** >= 3.1.7: Performance optimization
- **numpy** >= 1.24.0: Array operations for heightmaps
- **noise** : Perlin noise generation (installed with pygame)
## Key Configuration Files
### config/settings.py
**CRITICAL**: All project parameters are centralized here. Never hardcode values in source files.
#### Main Sections:
1. **TERRAIN** - Grid and generation parameters:
```python
grid_size: 20 # 20×20 tiles
tile_width: 30 # 30px width
tile_height: 30 # 30px height
perlin_scale: 8.0 # Noise frequency (≈ grid_size / 2.5)
height_multiplier: 80.0 # Vertical scale
perlin_octaves: 4 # Detail levels
perlin_persistence: 0.6 # Detail influence
perlin_lacunarity: 2.5 # Detail density
```
2. **CAMERA** - View parameters:
```python
distance: 800 # Camera distance from center
height: 450 # Camera height (Y axis)
fov: 45 # Field of view (degrees)
zoom_speed: 10.0 # UP/DOWN key speed
height_speed: 10.0 # LEFT/RIGHT key speed
```
3. **RENDERING** - Visual settings:
```python
line_width: 5.0 # Tile border thickness
line_color: (0,0,0) # Border color (RGB)
light_position: (1,1,1,0) # Directional light
```
4. **BIOME_COLORS** - Biome RGB colors:
```python
water, sand, grass_low, grass_mid, grass_high, rock, snow
```
5. **BIOME_THRESHOLDS** - Height thresholds for biome assignment:
```python
water: -10, sand: 0, grass_low: 10, grass_mid: 25,
grass_high: 40, rock: 55, snow: 70
```
- pygame >= 2.5.0, PyOpenGL >= 3.1.7, numpy >= 1.24.0, noise
## Architecture Principles
## Key Configuration (config/settings.py)
### Separation of Concerns:
- **TerrainGenerator** : Only generates heightmaps (Perlin noise)
- **TerrainRenderer** : Only renders geometry (OpenGL calls)
- **Camera** : Only handles view transformations and input
- **IsometricTerrainApp** : Orchestrates all components
**CRITICAL**: All parameters centralized here. Never hardcode values.
### Data Flow:
```
User Input → Camera → App.update()
App → TerrainGenerator.generate() → heightmap array
App → TerrainRenderer.render(heightmap) → OpenGL drawing
```
**TERRAIN**: `grid_size: 20` , `tile_width: 30` , `perlin_scale: 8.0` , `height_multiplier: 80.0`
**CAMERA**: `distance: 800` , `height: 450` , `zoom_speed: 10.0`
**RENDERING**: `line_width: 5.0` , `side_face_color: (0.55, 0.45, 0.35)`
### Key Design Patterns :
1. **Configuration Object** : All settings in one module
2. **Single Responsibility** : Each class has one clear purpose
3. **Dependency Injection** : Pass dependencies via __init__
4. **Stateless Rendering** : Renderer doesn't store heightmap
**Texture settings (v1.1.0)**:
- `texture_enabled: True`
- `texture_detail_scale: 8.0` (noise sampling)
- `texture_variation: 0.25` (color variation 0-1)
- `texture_spots_threshold: 0.6` (dark spots)
## Important Implementation Details
### Perlin Noise Parameters
**Rule of Thumb**: `perlin_scale ≈ grid_size / 2.5`
**BIOME_COLORS**: water, sand, grass_low, grass_mid, grass_high, rock, snow
**BIOME_THRESHOLDS**: Heights for biome transitions
- Grid 10×10 → scale = 4.0
- Grid 20×20 → scale = 8.0 (current)
- Grid 30×30 → scale = 12.0
**Why?** Ensures terrain features span multiple tiles for natural appearance.
## Architecture Principles
### Isometric View Mathematics
### Separation of Concerns:
- **TerrainGenerator** : Heightmaps with random seeds
- **TerrainRenderer** : Geometry + procedural textures (OpenGL)
- **Camera** : View transformations and input
- **IsometricTerrainApp** : Orchestrates components
Camera positioned at **45° horizontal and vertical** :
```python
camera_position = (distance, height, distance) # X = Z for 45°
look_at = (0, 0, 0) # Center of terrain
up_vector = (0, 1, 0) # Y is up
### Texture System (v1.1.0):
```
Per-Tile Generation:
1. get_texture_for_tile(color, grid_i, grid_j)
2. generate_procedural_texture() → 16×16 pixels
3. 3-layer Perlin noise: detail + pattern + spots
4. glTexImage2D() → OpenGL texture
5. Cache with key: (grid_i, grid_j, color, seed)
6. UV mapping with glTexCoord2f()
```
### Tile Rendering
## Important Implementation Details
Each tile is a **quad** with 4 vertices:
```
Top face: 4 vertices at (x, height, z) corners
Side faces: Only drawn if neighbor is lower
```
### Perlin Noise Scale
**Rule**: `perlin_scale ≈ grid_size / 2.5`
Grid 20×20 → scale = 8.0 (current)
### Biome Assignment
### Tile Rendering (v1.1.0)
**Top face**:
- 16×16 texture per tile (GL_NEAREST = pixelated)
- GL_LIGHTING disabled (pure colors)
- Unique texture: (grid_i, grid_j, biome, seed)
```python
if height < threshold [ ' water ' ] :
color = BIOME_COLORS['water']
elif height < threshold [ ' sand ' ] :
color = BIOME_COLORS['sand']
# ... etc
```
**Side faces**:
- Uniform brown with shading (0.7 right, 0.8 back)
- GL_LIGHTING enabled
## Common Modification Patterns
### Random Seeds (v1.1.0)
**Heightmap**: `random_base = random.randint(0, 10000)` in `generate()`
**Textures**: New `texture_seed` in `set_heightmap()` + cache clear
**Result**: R key regenerates both completely
### Changing Grid Size:
1. Update `TERRAIN['grid_size']` in settings.py
2. Adjust `TERRAIN['perlin_scale']` (new_size / 2.5)
3. Consider adjusting `CAMERA['distance']` for larger grids
## Common Modifications
### Adding New Biome:
1. Add color to `BIOME_COLORS`
2. Add threshold to `BIOME_THRESHOLDS`
3. Update `get_color_for_height()` in terrain_renderer.py
4. Ensure thresholds are in ascending order
### Grid Size:
1. Update `TERRAIN['grid_size']`
2. Adjust `perlin_scale` (new_size / 2.5)
3. Adjust `CAMERA['distance']` if needed
### Modifying Camera Behavior:
1. Edit Camera class in `src/camera/camera.py`
2. All movement logic in `handle_input(keys)`
3. Projection setup in `setup_projection(aspect_ratio)`
4. View setup in `setup_modelview()`
### Textures:
- `texture_variation` : 0.0-1.0 (more/less change)
- `texture_detail_scale` : Lower = larger patterns
- `texture_spots_threshold` : Lower = more spots
- `texture_size=16` : Change in `generate_procedural_texture()`
- GL_LINEAR for smooth (non-pixelated)
### Performance Optimization :
- Reduce `grid_size` (20 → 15)
- Reduce `perlin_octaves` (4 → 3)
- Disable `enable_smoothing`
- Reduce `far_clip` (5000 → 3000)
### Performance:
- Reduce `grid_size` (20→15) = fewer textures
- Reduce `perlin_octaves` (4→3)
- Texture size (16×16 → 8×8)
- `texture_enabled: False` disables textures
## Testing Guidelines
## Testing
### Always Test After Changes:
```bash
source venv/bin/activate & & python main.py
```
### Test Controls:
- **UP/DOWN** : Zoom (should be smooth)
- **LEFT/RIGHT** : Height (should move camera up/down)
- **R** : Regenerate terrain (should create new random terrain)
- **ESC** : Exit
### Visual Validation:
- Check tile borders are visible (line_width > 3.0)
- Verify biome colors match settings
- Ensure no Z-fighting (flickering surfaces)
- Confirm terrain has variety (not flat)
**Controls**: UP/DOWN (zoom), LEFT/RIGHT (height), R (regenerate terrain+textures), ESC (exit)
## Documentation
**Visual checks**:
- Tile borders visible (line_width > 3.0)
- Textures pixelated and unique per tile
- Dark spots and color variations
- Side faces uniform brown with shading
### Italian Documentation (docs/):
Complete 8-chapter guide explaining:
1. Project overview and results
2. 3D graphics and isometric concepts
3. OpenGL technology
4. Perlin noise algorithm
5. Code architecture
6. Rendering system
7. Camera system
8. Customization guide
## Debugging
**Target Audience**: Non-technical users, no OpenGL knowledge assumed
**Update Rule**: When changing features, update relevant documentation chapter.
**Common Issues**:
1. Flat terrain: Increase `height_multiplier` or reduce `perlin_scale`
2. Invisible borders: Increase `line_width`
3. Textures not visible: Check `texture_enabled: True` + GL_LIGHTING disabled for tops
4. Textures not pixelated: Verify GL_NEAREST filtering
5. All tiles same: Check cache key includes `texture_seed`
## Git Workflow
### Repository:
- Remote: `ssh://git@git.enne2.net:222/enne2/GLTerrain.git`
- Branch: `master`
**Remote**: `ssh://git@git.enne2.net:222/enne2/GLTerrain.git`
**Branch**: `master`
### Version Tagging:
```bash
git tag -a v1.x.x -m "Description"
git push origin master --tags
```
### .gitignore Includes:
- venv/, __pycache__ /, *.pyc
- .vscode/, .idea/
- *.png, * .jpg (generated screenshots)
- *_backup_* .py
## Debugging Tips
### Common Issues:
1. **Flat Terrain** : Increase `height_multiplier` or reduce `perlin_scale`
2. **Too Chaotic** : Reduce `height_multiplier` or increase `perlin_scale`
3. **Invisible Borders** : Increase `line_width` (5.0 → 8.0)
4. **Camera Issues** : Check `distance` and `height` values match tile scale
5. **Performance** : Reduce `grid_size` or `perlin_octaves`
### OpenGL Debugging:
- Enable depth testing: `glEnable(GL_DEPTH_TEST)` (already enabled)
- Check matrix mode: `glMatrixMode(GL_MODELVIEW)` before drawing
- Verify vertex order: Counter-clockwise for front faces
## Future Enhancement Ideas
### Easy Additions:
- Export heightmap to PNG (PIL/Pillow)
- Save/load terrain seeds
- Multiple camera presets
- Minimap in corner
- FPS counter
### Medium Complexity:
- Smooth camera transitions (lerp)
- Camera rotation (Q/E keys)
- Day/night cycle (lighting animation)
- Biome gradients (blend colors)
- Water animation (vertex shader)
### Advanced Features:
- Texture mapping (replace flat colors)
- Normal mapping (surface detail)
- Shadow mapping
- LOD system (level of detail)
- Terrain editing tools
## Code Style Guidelines
- **Imports** : Standard library → Third party → Local modules
- **Naming** : snake_case for functions/variables, PascalCase for classes
- **Constants** : UPPER_CASE in settings.py
- **Docstrings** : Include for all public methods
- **Comments** : Explain "why", not "what"
- **Line Length** : Max 100 characters
- **Type Hints** : Use where it improves clarity
## Contact & Maintenance
**Author**: enne2
## Documentation
Italian docs in `docs/` (8 chapters). Update relevant chapter when changing features.
## Contact
**Author**: Matteo Benedetto
**Project**: GLTerrain (Isometric Terrain Generator)
**License**: (Add license info if applicable)
**Last Updated**: October 2025
#**Important**: These instructions must be under 200 lines to ensure clarity and conciseness.