The Xna-Way: Terrain Editor - Update 1

Aggiornamento sul terrain editor.

Dopo diversi giorni di lavoro, che sono stati più di quanto avessi preventivato all'inizio (non tanto per la complessità del problema, ma il fatto è che sono stato rallentato da problemi personali) direi che sono quasi alla fine della base di questo progetto.
Cosa è stato fatto in questo periodo?

Il codice è stato organizzato in modo che il controllo/editor del livello contenga due oggetti separati definiti come TerrainEditor e ModelLevelEditor. Tali oggetti vanno a riferire lo stesso oggetto Level, solo che il promo va a modificare il terreno e le texture del terreno, mentre il secondo da la possibilità di modificare in modo agevole i modelli presenti nel livello.

Questi oggetti come si è capito danno specifiche funzioni che agiscono su una parte del modello dell'applicazione.

Tra le caratteristiche comuni ad entrambi c'è la coda delle operazioni svolte: posso cioè tornare indietro con le operazioni svolte e ripristinare lo stato precedente alla modifica fatta, questo per ogni operazione possibile (editing del terreno, editind delle texture del terreno, editing delle trasformazioni spaziali del modello). Ancora è da rifinire e perfezionare, ma per ora funziona.

Ho aggiunto la possibilità di importare oggetti 3D a runtime, cioè non compilati a posteriori da XNA tramite il Visual C# o VS. Questa parte devo dire mi ha impegnato un po', ma solo per il fatto che non capivo come re-indirizzare il compilatore alla giusta versione delle dll da usare.
Ora, tramite un sistema di Builder e ContentManager, "compila" a tempo di esecuzione i file che deve importare nella scena. Il tutto rallenta un po' (dato che la compilazione/importazione dei modelli nel formato compatibile con XNA impiega un po' ti tempo; forse potrei ottimizzare aggiungendo in futuro la compilazione in un thread separato, in questo modo, almeno al caricamento di un livello precente otterrei un tempo minore), ma funziona.
Unica "pecca": dato che non riesco ancora a trovare il riferimento a tutti i file necessari per la compilazione di un modello (texture e simili) sarà compito di usa il modello copiare poi nella cartella/directory che più preferisce i file necessari al corretto funzionamento del modello nel livello.

A cosa serve poter importare oggetti nel livello se poi non si possono usare? Ho aggiunto quindi la possibilità di inserire/eliminare modelli dal livello tramite il mouse. Lo stesso dicasi per quanto riguarda la traslazione/rotazione/scaltura degli stessi.
Per le trasformazioni spaziali degli oggetti ho creato ed aggiunto degli assi cartesiani, per ora molto semplici, che permettono di postare l'oggetto.

Dato che le modifiche possibili sono diventate varie, ho deciso di rendere modulare il modo di agire sui dati.
L'applicazione permetterà di modificare la parte del modello che vogliamo modificare: tramite dei radio button (o con un short-cut) si può passare dalla modalità di editig del terreno, alla modalità di editing delle texture ed infina a quella dei modelli.
Forse è un po' scomodo all'inizio, ma se si pensa che in altri programmi professionali fanno cose simili (ok forse è esagerato comparare questo sgorbio che sto facendo con programmi professionali, ma a qualcuno/qualcosa ci si deve pur ispirare no?).

Aggiunta la possibilità di caricare nuove immagini da usare nei brush per la modifica del terreno, e queste immagini poi saranno copiate nella directory dei terrain brush e ricaricate al riavvio successivo.
Credo che andrò a fare una cose del genere anche per le texture usate per il terreno, in modo che quando si vorrà poi riusare il livello creato in un gioco (ma chi mai andrà a farlo mi domando io XD) almeno avrà parte dei dati raggruppati e più facilmente utilizzabili.

Per ora non credo di avere altro da aggiungere.
Se ho dimenticato qualcosa aggiungerò in seguito.

Vi lascio con uno screen del programma:


Per le percentuali di lavorazione:
Terrain Editor Journal

Alla prossima ^^

PS: non credo che molti avranno qualcosa da dire, ma in caso contrario che dite tutto quello che vi passa per la testa! Curiosità, possibili correzioni, cosa da fare/aggiungere.
E se avete qualche curiosità sul codice ditelo, e vedrò di pubblicarlo! (almeno in parte ^^)
Continua a leggere!

The Xna-Way: Terrain Editor Journal

Questo post sarà il giornale di sviluppo che dedicherò al terrain editor.
Aggiornerò di volta in volta con le modifiche che farò, con le possibili modifiche/update da fare al programma, gli errori (e quando riesco a risolverli anche come ho fatto XD).
Se poi ci saranno articoli relativi a pezzi di codice del Terrain Editor saranno linkati anche qui.

Quello che mi sono prefisso di fare inizialmente era di creare un Terrain Editor, in modo da poterlo poi utilizzare per creare i livelli di gioco per i miei futuri progetti (sempre pensare in grande perchè poi a forza di tagliare resta sempre poco XD).
Ho quindi poi deciso di ampliare il progetto permettendo di aggiungere oggetti alla scena.
Quindi da "semplice" terrain editor sono passato a voler fare un "semplice" Level Editor (con un formato mio personale).

I fondamenti sono i seguenti:
- Uso di un'immagine come Height Map (HM) per la creazione del terreno di base.
Un'immagine ha 4 canali per il colore (RGBA), ed ho deciso di utilizzare solo le informazioni presenti nel canale R per la creazione del modello del terreno. In questo modo gli altri canali potranno essere utilizzati per memorizzare altre informazioni (per esempio le zone in cui è possibile "camminare", posizione di alcuni oggetti di scena, etc)
Usando il valore di un singolo colore per l'altezza del vertice, il valore dell'altezza può variare tra 0-255 (estremi compresi).
Per ampliare il range di valori posso utilizzare un fattore di scala (positivo) per il quale moltiplicare il valore dell'altezza del vertice.
Avrò un fattore di scala anche per la dimensione del del modello lungo gli assi X-Z (in questo modo il fattore di scala per la larghezza sarà diverso e distinto da quello per l'altezza).

- Possibilità di editare il terreno, modificando l'altezza dei vertici che compongono il modello.
Cioè saranno dati dei brush con i quali sarà possibile modificare la mesh del terreno. Ad ogni brush (a seconda della funzionalità che deve espletare) può avere associata un'immagine, la quale verrà utilizzata per modificare la posizione dei vertici. L'immagine associata potrà essere cambiata a seconda del tipo di modifica che si vuole fare, e sarà in BN (o in caso non sia in BN verrà usato solo il valore del canale R, come per la HM usata per costruire il terreno).

- Possibilità di salvare il terreno prodotto come immagine.
Per quando ci saranno dei possibili modelli sul terreno dovranno essere salvati anche le informazioni sui modelli (forse serializzando con XML), come anche le informazioni sulle luci della scena, etc.

- Possibilità di utilizzare 4 texture per la colorazione del terreno. Per ora il numero è limitato a 4 per una maggiore semplicità di programmazione (e per la struttura dei vertici usati): difatto utilizzare più di 4 texture è "la stessa cosa" che usarne 4, solo che i casi da discriminare sono di più. Sarà possibile utilizzare le varie texture in base all'altezza dei vertici, o texturizzare a mano il terreno.

A presto per degli aggiornamenti

Stato attuale:
  • Caricamento HM e creazione terreno partendo dall'immagine: 100%
  • Caricamento altre informazioni dall'immagine: 100%
  • Salvataggio terreno editato: 100%
  • Uso di un file XML per la memorizzazione di altre informazioni sul livello: 100%
  • Definizione di Brush personalizzati atti alla modellazione del terreno: 100%
  • Salvataggio/caricamento brush ed immagini dei brush: 100%
  • Possibilità di texturizzare il modello in base all'altezza dei vertici o a mano: 100%
  • Possibilità di creare ed aggiungere nuovi brush: 0%
  • Possibilità di modificare le texture usate dal modello: 100%
  • Possibilità di aggiungere/gestire modelli al livello: 100%
  • Possibilità di aggiungere/gestire luci nel livello: 0%
  • Possibilità di fare degli screenshot/render del terreno: 0%
  • Algoritmo di intersezione mouse-VS-poligoni: 100% (Implementato algoritmo ricorsivo a partizione dello spazio per la l'indificazione del vertice più vicino al puntatore)
  • Algoritmo di editig dei vertici del modello: 100%
  • Algoritmo di texturing: 100%
End
Continua a leggere!

The Xna-Way: Terrain Editor

Come avevo detto tempo fa, non ho molto tempo per scrivere qualcosa su XNA da postare qua, ma non per questo vuol dire che non stia andando avanti in qualche modo.

Ho recentemente iniziato un progetto per l'università (o almeno spero che possa usarlo per un esame universitario), che per ora ha il nome di Terrain Editor.
Lo sto sviluppando usando C# ed XNA (se no cola cavolo che ne parlavo sotto Xna-Way XD), e per ora si prospetta come un semplice editor di terreni.
Alcune immagini:



Quello che mi sono prefisso di fare è di creare un piccolo editor di livelli, in modo da poter creare delle mappe da poter usare in un gioco o quello che ci pare.
I "livelli" per ora composti solo dal terreno, sono costruti partendo da delle immagini (usate come Height Map), in modo da poter usare i colori per posizionare i vertici.
In seguito voglio aggiungere altre caratteristiche, tra le quali per ora ho messo:
- editare il terreno (se no che Terrain editor sarebbe...) (già in parte implementato)
- definire zone in cui è possibile camminare o meno
- possibilità di aggiungere oggetti al livello e posizionarli nella scena
- Multitexturing del terreno (questo già in parte implementato)

poi mano a mano che mi vengono in mente le aggiungerò.
Quando avrò tempo credo che posterò qualche pezzo di codice più interessante (non che per il momendo ce ne sia poi molto).
Spero che il progetto vi piaccia (e nel caso possa usarlo come progetto d'esame che piaccia anche al prof!).

Un salutone!
A presto!
Continua a leggere!

The Xna-Way: Avviso

E' con dispiacere che informo, chi è interessato, chi mi segue, e quei pochi che capitano su queste pagine (forse pure per errore), che non credo aggiungerò altri tutorial/codice/guide su XNA per minimo un mese.

Motivo?
Studio, università, lavori da consegnare, progetti da completare e discutere, problemi vari, e tanto altro ancora!
Se ce la farò vedrò di pubbliacare qualche post di commento/recensione, ma non prometto nulla.

Per chi volesse contattarmi o simili vi rammento che sono su msn e rispondo a questo indirizzo e-mail.
odinoa@hotmail.it

Saluti! Continua a leggere!

FUUUUUU.... cioè quando non ti resta altro da fare!

Vi è mai capitato di non sapere dove sbattere la testa?
Di avere delle cose da fare ma altre vi si sovrappongono e dovete rimandare?
Oppure solo di provare una forte rabbia per qualcosa che non va per il verso giusto?

Bè ecco come mi sento quando provo cose del genere!


Sinceramente non saprei in qualche altro modo esprimere la rabbia e la frustrazione che alle volte si prova!
E questa immagine rende bene come ci si sente XD

Il soggetto non è mio! Il FUUUU come viene chiamato è nato sulle Chan (se ricordo bene) e avendo passato una giornata pesa, persa a compilare della cavolo di librerie che non ne volevano sapere di partire, quando poi ce l'ho fatta per liberarmi un po' ho fatto questa... cosa (XD) in zBrush.
Circa 40 minuti di lavoro... o meno... bo non lo so (intanto facevo anche altre cavolate).
Se qualcuno lo vuole mi chieda il file e glielo invio per posta elettronica.

Buon FUUUU a tutti!
Meglio un FUUUU che spaccare i mobili di casa XD

Alla prossima!
Continua a leggere!

The Xna-Way: Tutorial 9: Fractal Generator

Come avevo preannunciato nell'ultimo post, ho realizzato un piccolo componente che genera alcuni frattali.
Il tutto è scritto in .Net ed utilizza gli strumenti forniti da XNA per creare e manipolare le immagini usate per la generazione dei frattali.
Il "programma" che illustrerò è abbastanza lunghetto rispetto agli altri, ma vedrò nel possibile di spiegarlo al meglio delle mie capacità.



Come sempre vi esorto a farmi notare se ho detto delle boiate immani!

Nota: nell'ultimo post avevo fatto vedere diverse immagini di frattali realizzate con il codice che andrò ad illustrare, però il codice che vi fornirò adesso potrà generare un solo tipo di frattale, e cioè il frattale di Mandelbrot.
Gli altri non li metterò per ora, anche se il codice è molto simile a quello che userò qua.

Intanto cominciamo col dire come ho pensato il tutto:
>il calcolo che dobbiamo fare è dato dalla successione:
z(n+1) = z(n)^2 + c
dove z è il valore del punto che vogliamo calcolare, e c è una costante che dobbiamo sommare di volta in volta
per z(0) valore sarà c
per z(1) il valore sarà c^2 + c
e così via.

>i punti su cui calcoliamo la successione sono quelli del piano complesso, quindi dovremo fare tutti i calcoli utilizzando l'algebra dei numeri complessi

>il valore di c cambia a seconda di quale punto del piano complesso stiamo calcolando il valore

>un punto appertiene all'insieme di Mandelbrot se Zn è in modulo minore di 2, dove n indica per quante volte dobbiamo ripetere il calcolo prima di considerare il punto in questione appartenente all'insieme. Quindi se dopo un numero i di ripetizioni del calcolo della successione il valore supera 2, il punto non appartiene all'insieme e verrà colorato in modo particolare, mentre se il punto appartiene all'insieme sarà colorato di nero.

NOTA: per la gestione dei calcoli con i numeri complessi ho usato una classe che ho trovato su internet, del quale ho fatto brutalmente copy-paste. Lo che di solito non si fa così, ma non era la parte dui numeri complessi che mi interessava implementare. Sicuramente l'uso di questa classe può aggiungere un po' di tempo di calcolo in più, quindi per velocizzare avrei potuto implementare il calcolo a manina, ma la "complessità" dei numeri complessi (scusate il gioco di parole XD) mi ha tolto la voglia.

Avrò quindi bisono di sapere in quale zona del piano complesso sto andando a calcolare la successione, quindi dovrò definire il limite inferiore e superiore per l'asse reale (considerato l'asse delle ascisse) e l'asse complesso (considerato delle ordinate).
Poi dovrò sapere quanto è lungo il lato delle ascisse e delle ordinate del piano (cioè la differenza tra il limite superiore ed inferiore degli assi), dato che questi valori poi mi servono per calcolare il valore di incremento. Si deve considerare che la texture (che rappresenta il frattale) sarà una "approssimazione" del piano complesso, e dato che non posso avere tanti pixel quanti sono i punti del piano (dato che sarebbero infiniti) devo assegnare ad ogni pixel un punto del piano e calcolare il valore per quel punto, e per fare ciò, quando passo da un pixel al successivo, devo sapere di quando avando/devo incrementare per passare al punto successivo.

Spieghiamo meglio questa cosa dei pixel...
Come forse saprete i punti del piano sono infiniti, mentre per quanto possano essere piccoli e fitti i pixel di un'immagine essi sono in numero ben finito.
Se ipotizzo i pixel dell'immagine come una "discretizzazione" del piano complesso (passatemi questo brutto termine che a molti non piace), allora devo assegnare ad ogni pixel un certo punto del piano, fare i calcoli su quel punto, e colorare il pixel a seconda del risultato ottenuto.
Ora prendiamo il primo pixel dell'immagine, quello che sta in alto a sinistra per interci (perchè nelle immagini l'asse delle X va da sinistra a destra e quello delle Y dall'alto verso il basso), e diamogli come punto quello identificato dall'estremo inferiore per l'asse X e dall'estremo superiore per l'alle Y. Quando poi vogliamo passare al punto successivo (per ora considero lo spostamento solo sull'asse reale, cioè delle X) dovrò incrementare di una certa quantità.
Questa quantità che devo sommare per passare da un punto all'altro la posso calcolare sapendo quanto è lungo il lato reale che sto prendendo in cosiderazione (quindi estremo superiore di X - estremo inferirio di X) e va diviso per la larghezza dell'immagine (in pixel naturalmente). In questo modo per passare da un punto a l'altro si fa una semplice somma.
Notate che la stessa cosa va fatta/calcolta per l'asse delle Y, trovando la quantità di incremento dividendo il lato verticale del piano per il numero di pixel dell'altezza.

Poi ho bisongno del massimo numero di iterazioni da calcolare prima di considerare il punto come appartenente all'insieme. Ricordo che un punto viene considerato parte dell'insieme di Madelbrot e quindi colorato di nero, solo se dopo N iterazioni (con N numero massimo di iterazioni) del calcolo della successione, il valore rispetta ancora la legge.
Naturalmente avrò bisogno anche di altre variabili: per esempio dovrò poter memorizzare il valore di ogni punto del piano di cui sto calcolando la successione, il numero di iterazioni fatte per ogni punto calcolato, e intanto che ci siamo anche per quali indici/pixel/punto devo ancora continuare a calcolare la successione.
Le variabili definite a questo scopo sono:

protected double infx = -2, supx = 2, infy = -2, supy = 2; //limiti del piano complesso su cui calcoare la successione
protected double latox, latoy, incx, incy; //lunghezza dei lati e di quando devo incrementare il valore
//da un pixel e l'altro
protected int maxIteration = 250; //numero massimo di iterazione

protected Texture2D fractal; //texture
protected bool complete = true; //indica se il calcolo è completo o no
protected int width, height; //altezza e larghezza della texture
protected Color[] pixData; //vettore contenente il colore dei pixel della texture
protected int total; // numero totale dei pixel della texture

protected Queue<int> indici = new Queue<int>(); //indice del pixel che devo calcolare
protected int[,] iterazioni; //numero di iterazioni per ogni punto
protected Cmplx[,] valori; //valore di ogni punto
protected Cmplx zCm = new Cmplx(), cCm = new Cmplx(); //numeri complessi per il calcolo

NOTA: il perchè ho usato una queue (struttura dati che implementa una coda, cioè una "lista" di elementi con estrazione in testa testa ed inserimento in coda) sarà chiaro in seguito.

La classe MandelBrotFractal è figlia di GameComponent, in questo modo potrà avere il suo metodo update e eseguire parte del calcolo ad ogni chiamata del metodo. Inoltre implementerà un'interfaccia da me definita che esporrà i metodi per agire sul frattale.
public interface FractalI
{
Texture2D Fractal { get; }
void resizeTexture(int width, int height);
bool Complete { get; }
int Width { get; }
int Heigth { get; }
void UpdateFractalDouble(double infx, double supx, double infy, double supy, int MAX);
}

Il significato mi pare abbastanza esplicito, comunque quando si vedrà come vengono usati i metodi sarà ancora più chiaro.

Il codice completo della classe che genera il MandelBrot è questo:
Show/Hide


Preferisco soffermarmi sul metodo calcolaFrattale() e su quello che fa:
quello che facciamo è controllare quanti elementi sono presenti nella coda degli indici (punti) per cu idevo calcolare il prossimo passo della successione (in questo modo so quante estrazioni fare).
Quindi comincio con estrarre l'elemento in testa alla coda, e calcolati l'indice di riga e di colonna trovo il valore della costante C da usare nel calcolo della successione per quel punto.
Il valore di C cambia a seconda del punto che stiamo considerando.
Poi recuperiamo il valore precedente per Z, e controlliamo se in modulo è minore di 4, o se non abbiamo già eseguito per il quel punto il massimo numero di iterazioni.
Se il punto ha valore in modulo maggiore di 4 non fa parte dell'insieme, quindi va colorato in modo oppurtuno. Se invece ho fatto il massimo numero di iterazioni e il valore del punto è ancora minore di 4 lo considero come appartenente all'insieme di Madelbrot e lo coloro di nero.
Per la colorazione del punto, uso il rapporto tra il numero di iterazioni fatte prima di trovare che il punto diverge e il numero massimo di iterazioni come parametro nella funzione che trasforma un colore in scala HSV in RGB (dove il rapporto è usato come H, cioè Hue, cioè la tonalità del colore).
Cambiando il modo in cui si usa il numero di iterazioni fatte nel calcolo del colore del pixel possono ottenere scale di colore diverse.

Come potete vedere osservando il codice, ogni volta che eseguiamo il metodo calcolaFrattale, viene calcolato un passo per ogni punto che ancora non è stato considerato non appartenente all'insieme. Questo vuol dire che mano a mano che si procede nel calcolo avrò sempre meno punti su cui calcolare la successione, e quindi il calcolo tenderà a diventare più veloce!

NOTA: perchè per ogni esecuzione del metodo calcolo un solo passo? Non posso calcolare tutto il frattale in una volta sola?
Certo si poteva fare anche in quel modo, ma poi non avrei potuto renderizzare lo stato intermedio del calcolo: in parole semplici avrei dovuto aspettare che il calcolo fosse concluso per poter far vedere il frattale, mentre in questo modo lo posso renderizzare anche quando è in fase di costruzione. In questo modo l'attesa per la completazione del frattale sarà più sopportabile ^^

Diamo adesso una piccola spiegazione sull'implementazione del metodo UpdateFractal():
questo metodo non fa altro che aggiornare lo stato del componente con i valori passati, e fa ripartire il cacolo del frattale con i nuovi dati.
Adesso io volevo (ed ho poi fatto) un effetto di transizione tra un'immagine di un fratale e quella successiva, solo che non "sapevo" dove metterla e alla fine l'ho messa in questo metodo.
Analizziamo in dettaglio ciò:

for (int i = 0; i < total; i++)
{
int r = i / width;
int c = i % width;
indici.Enqueue(i);
iterazioni[r, c] = 0;
valori[r, c].set(0, 0);
pixData[i] = Color.Lerp(pixData[i], Color.Black, 0.7f);
}

in questo pezzo di codice scorro il vettore che contiene il colore di ogni pixel dell'immagine. All'inizio impostavo tutti i pixel a nero, solo che così il passaggio tra un'immagine e la successiva era troppo netta (almeno per i miei gusti), e la cancellazione istantanea dell'immagine mi dava noia.
Quindi ho deciso di scurire tutta l'immagine facendo una semplice interpolazione tra il colore attuale de pixel ed il colore nero. Successivamente, quando il calcolo del frattale verrà riavviato, si andrà a lavorare di nuovo sulla stessa texture, colorando in modo diverso i pixel. Si avrà quindi un effetto di transizione tra un'immagine e l'altra.

Spero di essere stato chiaro fino ad ora, dato che adesso viene la parte più incasinata, e cioè gestire ed agire sul frattale tramite gli strumenti offerti da XNA.
Quello che voglio fare è riuscire, con il mouse, a selezionare una zona del frattale su cui fare zoom, quindi modificare gli estremi della zona del piano su cui stiamo calcolando la successione.
Voglio poi poter incrementare e drecrementare il numero massimo di iterazioni da fare come la risoluzione della texture su cui calcolo il frattale (più pixel ho più punti dovrò considerare, quindi avrò una maggiore precisione).

Invece di stare a schiaffarvi qui il codice dell'applicazione ve lo lascio la leggere direttamente dal sorgente, dato che la cosa che mi ero proposto di fare era spiegarvi come avevo implementanto il calcolo del frattale.
Però il codice sarà abbastanza commentanto, in questo modo non dovreste avere difficoltà!

Ecco il link al file
XNA-Mandelbrot.rar

Spero di essere stato il più chiaro possibile...
in caso non lo sia stato (cosa più che probabile XD) non esitate a chidere chiarimenti, a dirmi dove ho sbagliato, o anche a mandarmi a quel paese se volete!

Ciauz! Alla prossima da Odino!
Continua a leggere!

XNA - Frattali

Tutto ciò è colpa di un mio professore dell'università...
E' lui che ha fatto accadere tutto ciò ?_?
Non ve la prendete con me ?_?

Seguendo il corso di Costruzione di Interfacce il nostro professore ci ha fatto vedere un'applicazione che fatto lui: si tratta di un programma che permette di calcolare e visualizzare il frattale di Mandelbrot.
Il frattale di MandelBrot è uno dei più famosi frattali (lo so dire ora, ma prima che ce lo facesse vedere lui manco sapevo chi fosse XD), e devo dire che con i frattali ci si può "divertire". Tutto ciò mi ha fatto tornare alla mente quando, da piccolo, mio padre mi fece vedere un programma per calcolare queste strane immagini, dove io potevo selezionare una parte piccola piccola, e l'immagine non "perdeva di dettaglio"... Ah beata innocenza XD

Sta di fatto che dopo aver visto questo programma fatto dal nostro professore mi sono deciso a farne uno mio. Dato che sto lavorando con XNA ho deciso di farne uno che utilizzasse XNA per calcolare e visualizzare i frattali.
Ci sto ancora lavorando, e devo implementare alcuni particolari, ma direi che il grosso è fatto.
Quindi se vi chiedete che fine ho fatto, o sono dentro un frattale(XD) o sto studiando per un esame (che voglia eh XD).

Intanto vi lascio con qualche immagine ottenuta da questo generatore di frattali che ho fatto ^_^
Spero vi piacciano :)
Quando sarà finito posterò qualcosa del codice che ho fatto!











A presto :)

Continua a leggere!

Donazioni

My Menu'