The Xna-Way: Tutorial 1: FPS Counter

Salve a tutti!
Ho deciso di cominciare il prima possibile a scrivere qualcosa riguardante il magnifico mondo dell'XNA.
Le mie conoscenze a riguardo sono per ora esigue, ed è per questo che ho deciso di scrivere qui quello che produrrò di "utile" di volta in volta, in modo da poter rendere diponibile ad altri quel poco che imparerò e per fare in modo che gli sventurati che capiteranno da queste parti e che ne sanno più di me, vedendo i miei strafaciolni, possano (se vogliono) correggermi!

Detto questo cominciamo! ^^

Dato che ho appena incominciato ad avventurarmi in questo mondo non andrò a buttarmi in spiegazioni troppo complicate o astruse...
Anche perchè il mio "sapere" aumenterà mano a mano che proseguirò con la lettura del manuale! Quindi per ora sono un po' a secco...

Cosa abbiamo appreso intanto?
Bè dopo aver scaricato dal sito della microsoft l'ultimo Microsoft Visual C# 2008 Express Edition e XNA 3.1, ho deciso di mettermi all'opera.
Nota: io non ho una X-Box 360 (eh lo so sono stronzo ?_?), quindi tutto il codice che andrò a scrivere sarà per Windows.
Naturalmente il codice potrà funzionare anche su una 360, solo che alle volte si dovranno fare delle modifiche. Quello che conta è che il concetto che sta dietro è lo stesso.

Dopo la creazione di un nuovo progetto di prova quello che appare è un file Game1.cs contenente il seguente codice:
 public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void UnloadContent()
{
}

protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

base.Draw(gameTime);
}
}

A cosa sono questi metodi a grandi linee?
Il Game1() è il costrutture della nostra classe Game1, nella quale andremo a creare tutti gli oggetti che ci serviranno per la nostra applicazione.
Inizialize() è il metodo che viene chiamato dopo il costruttore, e qui andremo ad inizializzare tutti i valori che ci servono.
Il LoadContent() viene chiamato dopo l'Initialize() e sarà il metodo dove inseriremo il caricamento dei file che ci servono, come i file audio, i modelli 3D, le immagini, etc. Insomma di tutta quella roba che sfrutta il il ContentPipeline di XNA per il caricamento degli elementi del gioco.
Dal contempo l'UnloadContent viene chiamato alla chiusura dell'applicazione serve a liverare la memoria occupata dai file caricati.
Il "cuore" della nostra applicazione sono i metodi Update() e Draw().
Questi metodi vengono chiamati a ripetizione, cioè Upadate()-Draw()-Update()-Draw() e così via fino a quando non viene chiusa l'appliacazione.
In Update() verrà messo il codice che serve ad aggiornare lo stato del nostro gioco, come la posizione della telecamera, la posizione dei nemici,...
Nel metodo Draw() tutto il codice che serve a disegnare, a renderizzare, la scena del gioco a schermo.

Se facciamo partire il programma adesso l'unica cosa che vedremo è una scena vuota a tinta unita.

Cosa vogliamo fare adesso?
Bè io intanto volevo vedere gli FPS della scena, anche per rendermi conto quando va veloce il tutto ^^

Si potrebbe pensare di mettere tutto il codice che ci serve nel file Game1.cs.
Certo funzionerebbe, ma dopo che avevo cominciato a scrivere qualcosa mi sono renso conto di questo: adesso metto il conteggio dei frame nel Draw(), poi dovrò renderizzare altri elementi quando mi servono, poi potrei voler fare qualche altra cosa etc.
Tutto questo dopo un po' renderebbe le cose confusionarie, portanto il codice ad una cattiva lettura e bassa possibilità di fare manutenzione e correzione.
Poi diciamocelo, C# è un linguaggio ad oggetti e ci sarà pure il modo di fare fare un oggetto che mi faccia il conto degli FPS da solo e possibilmente in automatico!
Meglio quindi cercare una soluzione più comoda e al contempo performante, cercando al contempo di suddividere il codice in più unità logiche cooperanti.

Con XNA possiamo utilizzare i GameComponents. Con i GameComponent possiamo organizzare al loro interno parte delle operazioni che vogliamo far fare al nostro gioco, e queste operazioni saranno poi richiamate automaticamente dal Framework di XNA.
Infatti XNA ci da la possibilità di gestire una collezione di GameComponents, alla quale possiamo aggiungere gli elementi che vogliamo siano gestiti come GameComponent.
Quindi in questo caso possiamo creare un GameComponent per il calcolo degli FPS, un GameComponent per la gestione e il movimento della telecamera, etc.
Però non dobbiamo pensare che per ogni oggetto che vogliamo gestire si possa creare un GameComponent non va bene. Ma per ora questa cosa non ci tocca. Si affronterà in seguito.
Andiamo quindi a creare il codice del nostro FPS Counter.

Per avere un'ulteriore suddivisione tra il codice del gioco e dei vari elementi che andremo a creare ho deciso di mettere tutti gli elementi in una GameLibrary (nel mio caso una WindowsGameLibrary, chi volesse provare il codice su una 360 devrà creare una X-BOX 360 Library).

Ho quindi creato il mio progetto libreria, chiamato myLibrary (che fantasia -.-).
Aggiungiamo un nuovo elemento al progetto, aggiungendo un GameComponent e chiamiamolo FPSCounter.
Fatto questo invece di far derivare FPSCounter da GameComponent facciamolo derivare da DrawableGameComponent, in questo modo il nostro FPSCount avrà il suo metodo Draw che verrà chiamato in automatico da XNA! (invece il GameComponent classico non offre questo metodo). E voi come direte... e ce ne importa del metodo Draw()?
Bè per contare gli FPS ci serve il metodo Draw() dato che gli FPS indicano il numero di volte al secondo che una scena viene renderizzata.

Per calcolare il valore FPS ci servono le seguenti variabili:
una variabile per tenere a mente il numero di volte che abbiamo renderizzato la scena (frameCount)
una varibile per tenere a mente quando abbiamo renderizzato l'ultima volta la scena (timeLastDraw)
Quelle che ho usato io, e che ho definito nella classe FPSCounter sono:
private int frameCount = 0;
private float intervall;
private float elapsedTime;
private float timeLastDraw;
private float fpsValue;

Dove intervall è l'intervallo in cui voglio misurare il numero di frame (in questo caso un secondo).
elapsedTime contiene il tempo che è passato dall'ultima invocazione di Draw().
fpsValue non credo che abbia bisogno di spiegazioni ^^.

L'unico metodo che ci interessa è il Draw(), ed è questo che andremo a ridefinire.
Tutti gli altri, costruttore a parte, possono essere cancellati.
Per ora nel costruttore mettiamo solo
intervall = 1.0f;


mentre il metodo Draw() sarà così fatto:
elapsedTime = (float)gameTime.ElapsedRealTime.TotalSeconds;
frameCount++;
timeLastDraw += elapsedTime;
if (timeLastDraw > intervall)
{
fpsValue = frameCount / intervall;
frameCount = 0;
timeLastDraw -= intervall;
Game.Window.Title = fpsValue.ToString();
}
base.Draw(gameTime);

prima ci calcoliamo quanto tempo è passato dall'ultima invocazione di Draw(), poi incrementiamo il frameCount, ed aggiungiamo il valore di elapsedTime a timeLastDraw, e poi controlliamo il valore di timeLastDraw.
Se il suo valore è maggiore di intervall, quindi di un secondo, calcolo il valore di fpsValue, azzero il frameCount, sottraggo intervall a timeLastDraw.
Come ultima operazione mostro il valore di fpsValue nella barra del titolo della finestra in cui è avviata l'applicazione (questo fa solo su Windows).

Ok fatto questo dobbiamo ora avviare il counter assieme al programma.
Come collegarla con la nostra applicazione, e cioè con il Game1.cs?
Prima di tutto aggiungiamo il riferimento alla nostra libreria: nell'esplora soluzioni facciamo tassto destro su riferimenti->aggiungi riferimento->scheda progetti->selezioniamo il nostro progetto myLibrary.
Fatto questo in vetta al file Game1.cs, sotto tutti gli altri using, mettiamo questa riga:
using myLibrary
Nel file Game1.cs mettiamo una varibile di classe come questa:
FPSCounter counter;

e dentro il costruttore di Game1.cs aggiungiamo:
counter = new FPSCounter(this);
Components.Add(counter);

Queste righe creano un nuovo FPSCounter e lo aggiungono alla collezione di GameComponent del nostro gioco.
Ricordo che i GameComponent vengono eseguiti automaticamente da XNA.

Quello che vi dovrebbe apparire è un valore nella barra del titolo al posto del nome della vostra applicazione.
Dovrebbe apparirivi un valore pari a 60, o che oscilla tra 58 e 60.
Ora dico...
Ho rifatto nuovo il portatile, e avere un "gioco" senza nulla scena che mi da 60 FPS mi pare un po' pochino...

Perchè accade questo?
Perchè XNA è impostato per fare il ciclo di chiamata Update-Draw 60 volte al secondo.
Quindi se anche fosse possibile renderizzare ad una velocità più alta lui la limita.

Come possiamo ovviare a questo limite?
Per renderizzare al massimo della velocità dobbiamo mettere queste righe di codice nel costruttore di FPS:
GraphicsDeviceManager manager = (GraphicsDeviceManager)Game.Services.GetService(typeof(IGraphicsDeviceManager));

manager.SynchronizeWithVerticalRetrace = false;
Game.IsFixedTimeStep = false;

Con queste andiamo a prendere il servizio che fa da gestore per la grafica del gioco,
e con le altre righe gli diciamo che deve renderizzare il più velocemente possibile.
Più precisamente: mettendo a false il valore SynchronizeWithVerticalRetrace dico che non deve sincronizzarsi con la frequenza del monitor, mentre con IsFixedTimeStep a false dico che non deve chiamare il metodo Update alla frequenza di default di 60 volte al secondo.

Facendo rieseguire ora ottengo un valore che si aggira sui 1500 FPS...
Già meglio cavolo :)

Per ora basta gente ^^
Spero di essere stato chiaro.
Come sempre se qualcosa non torna, se volete esprimere un commento, proporre una modifica, etc, siete liberissimi di farlo!

Ecco intanto il codice prodotto fino ad ora!
XNA-tut1.rar

Alla possima!
Continua a leggere!

Fast Modelling 7 - GamePad

Cosa fare quando si è stanchi fisicamente, quando non avete voglia di fare un po' di fatica fisica, quando avete la testa che vi fa male, quando avete la mente assillata da pensieri che non pensavate di avere e che alle volte non vorreste avere?

Ma buttiamoci sulla modellazazione e vediamo di fare qualcosa...

Cosa si realizza oggi?
Avevo accando al pc un gamePad, quindi senza pensarci troppo su ho cominciato a modellare un cavolo di gamePad...

Devo dire che il design non mi piace per niente, poteva essere fatto meglio.
Avrei potuto avere anche un workFlow migliore...
Avrei potuto fare tante cose molto meglio, ma è andata così...
Tempo di realizzazione?
Direi circa 30 minuti, comprendendo controlli a forum e siti nel frattempo...

30 minuti in cui ho tenuto la testa occupata e in cui non ho pensato a nulla?
Magari... 30 minuti passati a modellare sto coso, sempre assillato da questo rumore di sottofondo che è la mia mente, ottenendo solo un qualcosa che mi convince poco e nulla...

Se avrò tempo e voglia vedrò di modificarlo e di fare un rendering (spero decente).

Alla prossima!
Sperando di essere più in forma...
Continua a leggere!

The Xna-Way

Piccola comunicazione.
Dato che adesso ho un po' più di tempo libero davanti a me, causa "vacanze estive" (se così si possono chiamare) ho il tempo di dedicarmi alla lettura e allo studio del manualone sull'XNA.

Quindi molto probabilmente comincerò a scrivere qualche programmino per XNA, e credo che posterò qua i risultati, il codice e se riesco qualche piccolo tutorial o aiuto.
Non per farmi passare per un esperto, solo che cominciando a studiarlo voglio condividere con chi è interessato i miei dubbi, "scoperte" e piccoli passi in avanti.
Così almeno chi ne sa più di me potrà darmi qualche capaccione e rimettermi sulla giusta strada :)

E per questo che in alto è stata aggiunta alla barra la voce Xna-Way, sotto il cui nome andranno tutti i post riguardati questo tema.

Nota: oltre alla voce Xna-Way è stata aggiunta quella per Lightwave, dato che ormai cominciano ad esserci diversi post a riguardo.

Alla prossima, e spero con un po' di nuovo materiale! :)
Continua a leggere!

Fast Modelling 6 - Ampolla

Anche oggi ero in vena di fare alcune prove.
Sto cercando di sbizzarirmi in nuove scene e di vedere come vengono elborate le varie parti.

Anche questa volta la scena è semplicissima:
un'ampolla, con dentro un pianeta o_O
Ok non è che sia proprio il massimo come realismo lo ammetto, ma mi è venuto in mento quando ho ripensato alla scena finale di Men In Black (mitico film :D).
Quindi ho pensato di fare un qualcosa di simile.

Dopo aver creato la scena, ho deciso di mettere più copie dello stesso oggetto, in modo che ottenere anche più riflessioni tra le varie copie.
Come potete vedere l'effetto ottenuto non è che sia proprio realistico, ma guardando le altre ampolle in secondo piano si nota che ci sono i riflessi.
Mi sono fatto un'idea anche di come risulta l'effetto di rifrazione nei materiali trasparenti. Il problema è quando questo effetto è comulativo tra più oggetti int trasparenza.
Per complicare ancola la scena ho voluto che il piano di appoggio funzionasse come uno specchio!
In questo modo si sarebbe visto anche la parte bassa delle ampolle.

Per finire ho provato a dare un effetto di profondità di campo (depth of field): per chi non sa cosa sia pensate a quando mettete a fuoco un oggetto. Tutto quello che sta dietro non è messo a fuoco, ma vi appare sfuocato. Ecco in parole povere cosa volevo ottenere.

Come di nota dall'immagine questo effetto non è che sia propriamente realizzato bene. Infatti avrei voluto fare un altro rendering con impostazioni diverse, ma dopo circa 30 minuti di render non avevo voglia di stare ad aspettare ancora.

Spero di vi piaccia!

Alla prossima. :D
Continua a leggere!

Fast Modelling 5 - Book's heart

Oggi mi giravano come pochi.
Motivo? Esame bocciato, ma questa è un'altra storia di cui non voglio parlare qua per non appestarvi troppo...

Comunque, dopo essermi sfogato, ho detto "abbiamo il piccio nuovo, facciamolo lavorare.... dè" (il dè in fondo ci sta sempre bene! :P)

Ma fare cosa?
Cosa si potrebbe fare di bellino e divertente?

Complice il fatto che sono stato 4 giorni ad solo a Pisa a fracassarmi i così detti, e avendo quindi molto tempo per pensare a tutto e di più (cosa che alle volte odio!), e complice anche le brevi meditazioni che ho fatto (anche quelle dovrei smettere mi sa, più si scava peggio è -.-)... insomma sta di fatto che con la malinconia che mi è presa mi è tornata alla mente una foto che vidi tempo fa su Deviant Art.

La foto consisteva in un anello messo in equilibrio su un libro aperto, con una luce alle spalle...
Bella roba direte voi!
Invece vi posso dire che come immagine è molto bella :)

Io non contento ci ho messo pure una sfera tanto per complicarmi un po' la vita XD
Come si può vedere qua la modellazione è presente solo di nome! Fare una sfera, un anello, un qualcosa che assomiglia ad un libro non è che sia un impegno gravoso...
Ma andiamo avanti va!

Quello che veramente mi interessava era il rendering di questa scena, e come potete capire quello sopra era solo una prova ^^
Dopo svariate prove, quello che ho ottenuto è stato questo!
Nella prima immagine c'è una sola luce, alle "spalle" della sfera (si potrà dire le spalle della sfera? XD), mentre nella seconda le luci sono 3, una alla destra e una alla sinistra della sfera.
Come potete vedere con le ombre proiettate hanno una forma particolare!
Scommetto che non ci avevate pensato eh ^__^

Bè come esercizio non è che fosse complicatissimo.
Volevo solo fare qualche prova con le luci (per la cronaca: le tre luci sono di tipo Spot, per capirci meglio come se fossero proiettate da una torcia), e giocare un po' sulle ombre e trasparenze!

Spero vi piaccia come immagine! :)

Come sempre sentitevi liberi di commentare o di proporre miglioramenti!

Alla prossima gente :D
Continua a leggere!

Windows 7

Cominciamo a dire qualche cosina, e dare le prime impressioni su questo nuovo SO.
Premetto che fino a quando non ho cambiato portatile ho sempre usato XP (ed Ubunto per l'università, ma questa è un'altra cosa).
Quindi pensavo di trovarmi maluccio con win7...

Sul portatile come accade oramai c'era installato Windows Vista... anche se da come andava mi pareva che alla Microsoft abbiano avuto più che altro una grande sVista!
Cioè lento, si bloccava per il trasferimento dei file, poi di default chiede ogni volta la conferma per installare o anche solo copiare un file...
Poi alcune cose sono veramente fatte da cani: per riuscire a raggiungere le proprietà per la configurazione della scheda di rete e mettere un cavolo di indirizzo IP statico si deve fare i salti mortali!

Dove diavolo è finita la semplicità di XP?
Secondo me come è vietato guidare sotto l'effetto dell'alchool o degli stupefacenti dovrebbero pure vietare di programmarci!

Quindi cosa ho fatto?
Mi sono scaricato la ISO di Win7, burnata ed installata.

Prima nota positiva: un partition manager fatto bene!
Per non parlare del fatto che l'installazione è velocissima! Ci mette meno di XP (ok che sono diventati più veloci i pc ^^).

Dopo l'installazione ci vuole un po' per prendere la mano... almeno a me che non ho usato Vista (da cui / ha breso la sua base).
Alcune icoone e funzioni sono state spostate (per esempio il tasto per visualizzare il desktop ora si trova nell'angolo in basso a destra! Che fatica a trovarlo XD).
Prima cosa che si nota: boot velocissimo e sistema stabile e veloce, ultra reattivo!
E' tutto il giorno che è acceso, installa, faccio i benchmark, provo e riprovo e non si è piantato mai una volta!
MAI un rallentamento, un accenno a prendere fiato!

Anche l'aspetto grafico è curato e carino.
Poi anche Areo, che sinceramente pensavo peso ed inutile, è comodo e veloce, e non cunsuma eccesive risorse: se non sapessi che è attivo non me ne accorgerei nemmeno!
Per alcuni effetti mi ricorda molto le ultime distro di Linux, con tutti quegli strani effettini.

Altre note?
Gestione dei programmi veramente buona.
Ho provato a fare dei render che feci tempo fa sul vecchio portatile, e ora il tempo di resa è circa 1/10 o meno di quello precedente (merito anche del processore molto più potente, ma anche il SO operativo aiuta, dato che 7 ha buona gestione della memoria!).
Addirittura sono riuscito a fare un render che prima non sarei riuscito a fare!
Alta risoluzione, anti-Aliasing ed altri effetti (solo per appesantire, tanto la differenza ad occhio si notava poco), e devo dire che è andata bene!
Ci ha messo 20 minuti per renderizzare il tutto, ma nel frattempo navigavo, scrivevo, ascoltavo musica, vedevo un filmato su youTube, installavo AdobeReader, etc... e non si è minimamente impensierito!
Andato avanti fino alla fine senza un tentennamento!

Ho trovato un'unica pecca, e cioè che come vista occupa circa 1 gB di ram...
Ma che ci vogliamo fare, non esistono più i SO che partono in 200 MB di ram ^^

Che dire gente!
Accorrete ed installate!

Ecco i 2 render di prova che ho fatto!

Dimensione: 1800x2400 px
Tempo di resa: circa 80 secondi - contro gli oltre 10 minuti sul vecchi portatile




Dimensione: 2000x2000
Tempo di resa: 20 minuti circa - contro un spegnimento a stronco all'incirca dopo 2 minuti sul vecchio portatile.



Ci sentiamo presto!
Alla prossima!

Continua a leggere!

Si riparte!

Nuovo portatile preso!
Funziona benone, è una potenza!

Si può quindi ricominciare a lavoricchiare... anche se ora c'è da reinstallare ogni cosa...
Con tanta calma di farà tutto! Forza e coraggio! Continua a leggere!

Ancora poco

Finalmente ho comprato un nuovo portatile.
Questo significa che tra poco potrò di nuovo tornare a lavorare.
Datemi solo il tempo di installare i sistemi operativi che mi servono e i vari programmi.

A presto! Continua a leggere!

Una notizia positiva

Sono riuscito a recuperare i dati dall'HD del mio portatile.
Almeno una cosa positiva in questi giorni...
Ora siamo alla ricerca di qualche offerta per un portatile...
Speriamo di non svenarci troppo!
Continua a leggere!

Donazioni

My Menu'