From ef5715c9011dcd1cc8288cad38ec03ddb387e2a7 Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 24 Oct 2025 18:17:13 +0200 Subject: [PATCH] Update project overview and version in Copilot instructions; enhance clarity and detail --- .github/copilot-instructions.md | 342 +++++++++----------------------- src/app.py | 8 +- 2 files changed, 97 insertions(+), 253 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2acb688..b2d5262 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -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 - ``` - -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. \ No newline at end of file diff --git a/src/app.py b/src/app.py index 1c83898..3ce1191 100644 --- a/src/app.py +++ b/src/app.py @@ -55,7 +55,7 @@ class IsometricTerrainApp: glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - # Setup lighting (sunset lighting) + # Setup lighting glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_COLOR_MATERIAL) @@ -64,12 +64,6 @@ class IsometricTerrainApp: glLightfv(GL_LIGHT0, GL_POSITION, self.config.RENDERING['light_position']) glLightfv(GL_LIGHT0, GL_AMBIENT, self.config.RENDERING['light_ambient']) glLightfv(GL_LIGHT0, GL_DIFFUSE, self.config.RENDERING['light_diffuse']) - - # Add specular component for sunset highlights - if 'light_specular' in self.config.RENDERING: - glLightfv(GL_LIGHT0, GL_SPECULAR, self.config.RENDERING['light_specular']) - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [0.3, 0.3, 0.3, 1.0]) - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10.0) def handle_events(self): """Handle pygame events"""