Add procedural pixelated textures for tiles
- Implement 16x16 procedural textures using Perlin noise (RCT-style) - Each tile has unique texture based on grid position and biome - GL_NEAREST filtering for retro pixelated look - Random seeds for both heightmap and textures on regeneration (R key) - Disable lighting on top faces to show pure texture colors - Uniform brown color for side faces with shading - Update documentation (README, docs/) with texture features - Update copilot instructions with communication rules
This commit is contained in:
+23
-15
@@ -11,8 +11,9 @@ Quando avvii il programma, vedrai:
|
||||
1. **Una griglia di terreno 3D** composta da 20×20 tessere (chiamate "tile")
|
||||
2. **Variazioni di altezza** che creano colline, valli e montagne
|
||||
3. **Diversi colori** che rappresentano biomi (acqua, sabbia, erba, roccia, neve)
|
||||
4. **Linee nere** che delimitano ogni tessera, creando un effetto griglia
|
||||
5. **Una vista dall'alto** con un angolo di 45 gradi (vista isometrica)
|
||||
4. **Texture procedurali pixelate** - Ogni tile ha decorazioni uniche in stile retro
|
||||
5. **Linee nere** che delimitano ogni tessera, creando un effetto griglia
|
||||
6. **Una vista dall'alto** con un angolo di 45 gradi (vista isometrica)
|
||||
|
||||
### Interattività
|
||||
|
||||
@@ -74,23 +75,24 @@ Altezza 70+ → Bianco (Neve) 🏔️
|
||||
|
||||
### 3. Rendering 3D
|
||||
|
||||
Il computer disegna ogni tessera come un quadrato in 3D:
|
||||
Il computer disegna ogni tessera come un quadrato in 3D con texture procedurale:
|
||||
|
||||
```
|
||||
Vista dall'alto: Vista isometrica:
|
||||
Vista dall'alto: Vista isometrica con texture:
|
||||
|
||||
┌──┬──┐ ◇──◇
|
||||
│ │ │ ╱│ ╱│
|
||||
├──┼──┤ → ◇──◇ │
|
||||
│ │ │ │ ╱│ ╱
|
||||
┌──┬──┐ ◇──◇ (con pattern 16×16 pixel)
|
||||
│ │ │ ╱│ ╱│ (macchie scure, variazioni)
|
||||
├──┼──┤ → ◇──◇ │ (ogni tile unica)
|
||||
│ │ │ │ ╱│ ╱ (stile retro pixelato)
|
||||
└──┴──┘ ◇──◇
|
||||
```
|
||||
|
||||
Ogni quadrato (quad) è disegnato con:
|
||||
- Una **faccia superiore** (quella che vediamo)
|
||||
- **Facce laterali** (per mostrare l'altezza)
|
||||
- **Colore** basato sull'altezza
|
||||
- **Ombreggiatura** per dare profondità
|
||||
- Una **faccia superiore** con texture procedurale 16×16 pixel
|
||||
- **Facce laterali** uniformi marroni per l'altezza
|
||||
- **Colore base** determinato dal bioma
|
||||
- **Pattern unici** generati con Perlin noise per ogni tile
|
||||
- **Ombreggiatura** sulle facce laterali per profondità
|
||||
|
||||
## Risultati Visivi
|
||||
|
||||
@@ -161,7 +163,14 @@ shader/
|
||||
## Caratteristiche Principali
|
||||
|
||||
### ✅ Generazione Procedurale
|
||||
Il terreno è generato automaticamente usando algoritmi matematici. Ogni volta che premi R, ottieni un paesaggio completamente diverso!
|
||||
Il terreno è generato automaticamente usando algoritmi matematici. Ogni volta che premi R, ottieni un paesaggio completamente diverso con texture uniche!
|
||||
|
||||
### ✅ Texture Procedurali Pixelate
|
||||
Ogni tile ha una texture 16×16 pixel generata proceduralmente con:
|
||||
- Pattern casuali unici per ogni tile
|
||||
- Macchie scure e variazioni di colore
|
||||
- Stile retro pixelato (GL_NEAREST filtering)
|
||||
- Contestuali al bioma (erba, sabbia, roccia, ecc.)
|
||||
|
||||
### ✅ Configurabilità
|
||||
Tutto è personalizzabile tramite il file `config/settings.py`:
|
||||
@@ -211,10 +220,9 @@ Il progetto base ha alcune limitazioni:
|
||||
- ❌ Non c'è salvataggio/caricamento delle mappe
|
||||
- ❌ Non puoi modificare il terreno interattivamente
|
||||
- ❌ La griglia è fissa a 20×20 (modificabile nel config)
|
||||
- ❌ Non ci sono texture, solo colori solidi
|
||||
- ❌ Nessun sistema di gameplay
|
||||
|
||||
Queste sono tutte cose che puoi aggiungere estendendo il progetto!
|
||||
Le texture procedurali sono completamente implementate! ✅
|
||||
|
||||
## Prossimi Passi
|
||||
|
||||
|
||||
+88
-14
@@ -38,9 +38,10 @@ heightmap[i+1][j+1] = 13
|
||||
### 1. Calcolo Vertici
|
||||
|
||||
```python
|
||||
def draw_tile(self, x, z, h1, h2, h3, h4):
|
||||
def draw_tile(self, x, z, h1, h2, h3, h4, grid_i, grid_j):
|
||||
# x, z: posizione in griglia
|
||||
# h1, h2, h3, h4: altezze dei 4 angoli
|
||||
# grid_i, grid_j: indici griglia per texture unica
|
||||
|
||||
corners = [
|
||||
(x, h1, z), # Angolo 1
|
||||
@@ -50,24 +51,97 @@ def draw_tile(self, x, z, h1, h2, h3, h4):
|
||||
]
|
||||
```
|
||||
|
||||
### 2. Faccia Superiore
|
||||
### 2. Generazione Texture Procedurale
|
||||
|
||||
Prima di disegnare, ogni tile genera una texture OpenGL unica:
|
||||
|
||||
```python
|
||||
# Calcola colore medio
|
||||
avg_height = (h1 + h2 + h3 + h4) / 4.0
|
||||
color = self.get_color_for_height(avg_height)
|
||||
|
||||
# Disegna quad
|
||||
glBegin(GL_QUADS)
|
||||
glColor3f(*color) # Applica colore
|
||||
for corner in corners:
|
||||
glVertex3f(*corner) # Definisci vertice
|
||||
glEnd()
|
||||
def generate_procedural_texture(self, base_color, grid_i, grid_j, texture_size=16):
|
||||
# Crea array 16×16 pixel
|
||||
texture_data = np.zeros((16, 16, 3), dtype=np.uint8)
|
||||
|
||||
# Offset unico per questo tile
|
||||
tile_offset_x = grid_i * 1000.0
|
||||
tile_offset_y = grid_j * 1000.0
|
||||
|
||||
for i in range(16):
|
||||
for j in range(16):
|
||||
# Coordinate noise con offset tile
|
||||
i_coord = float(i) / 16 * scale + tile_offset_x
|
||||
j_coord = float(j) / 16 * scale + tile_offset_y
|
||||
|
||||
# 3 layer di Perlin noise
|
||||
detail = noise.pnoise2(i_coord, j_coord, octaves=3)
|
||||
pattern = noise.pnoise2(i_coord * 0.5, j_coord * 0.5, octaves=2)
|
||||
spots = noise.pnoise2(i_coord * 1.5, j_coord * 1.5, octaves=1)
|
||||
|
||||
# Combina e applica al colore base
|
||||
variation = (detail * 0.4 + pattern * 0.6) * 0.25
|
||||
spot_factor = 0.75 if spots > 0.6 else 1.0
|
||||
|
||||
final_color = (base_color + variation) * spot_factor
|
||||
texture_data[i, j] = final_color * 255
|
||||
|
||||
# Crea texture OpenGL
|
||||
texture_id = glGenTextures(1)
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # Pixelato!
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)
|
||||
|
||||
return texture_id
|
||||
```
|
||||
|
||||
**Risultato**: Faccia superiore della tile colorata.
|
||||
**Caratteristiche**:
|
||||
- 16×16 pixel per effetto retro
|
||||
- GL_NEAREST = nessuna interpolazione → pixel netti
|
||||
- 3 layer Perlin noise per variazioni naturali
|
||||
- Offset unico (grid_i, grid_j) = ogni tile diversa
|
||||
- Macchie scure dove `spots > 0.6`
|
||||
|
||||
### 3. Facce Laterali
|
||||
### 3. Faccia Superiore con Texture
|
||||
|
||||
```python
|
||||
# Ottieni texture unica per questo tile
|
||||
avg_height = (h1 + h2 + h3 + h4) / 4.0
|
||||
base_color = self.get_color_for_height(avg_height)
|
||||
texture_id = self.get_texture_for_tile(base_color, grid_i, grid_j)
|
||||
|
||||
# Abilita texturing
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id)
|
||||
glDisable(GL_LIGHTING) # Mostra colori puri texture
|
||||
glColor3f(1.0, 1.0, 1.0) # Bianco = non tinta la texture
|
||||
|
||||
# Disegna quad con coordinate texture
|
||||
glBegin(GL_QUADS)
|
||||
glTexCoord2f(0.0, 0.0) # Angolo texture
|
||||
glVertex3f(*corners[0])
|
||||
glTexCoord2f(1.0, 0.0)
|
||||
glVertex3f(*corners[1])
|
||||
glTexCoord2f(1.0, 1.0)
|
||||
glVertex3f(*corners[2])
|
||||
glTexCoord2f(0.0, 1.0)
|
||||
glVertex3f(*corners[3])
|
||||
glEnd()
|
||||
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
glEnable(GL_LIGHTING) # Riabilita per facce laterali
|
||||
```
|
||||
|
||||
**Coordinate Texture (UV)**:
|
||||
```
|
||||
(0,0)────(1,0)
|
||||
│ 16×16 │
|
||||
│ pixel │
|
||||
(0,1)────(1,1)
|
||||
```
|
||||
|
||||
Ogni angolo del quad mappa un angolo della texture 16×16.
|
||||
|
||||
**Risultato**: Faccia superiore con pattern procedurale pixelato unico.
|
||||
|
||||
### 4. Facce Laterali (Uniformi)
|
||||
|
||||
#### Faccia Destra (X+)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user