Parlando di 3D, spesso si tende a sottovalutare il ruolo che, nell'ambito di una scena tridimensionale, possono giocare semplici oggetti bidimensionali.
Pensiamo ad un gioco spaziale, con astronavi che combattono, sparano diversi tipi di proiettili, prendono fuoco e bruciano producendo fumo ed esplosioni. Certamente gli elementi principali della scena (come le astronavi) sono rappresentati usando modelli tridimensionali, più o meno dettagliati. Al contrario, molti degli effetti speciali utizzati per abbellire o rendere più realistico il gioco sono rappresentati mediante semplici texture bidimensionali, che vengono tuttavia trattate come se fossero oggetti 3D normali (possono essere ruotate, traslate, ecc.).
Si pensi, ad esempio, alle esplosioni, al fumo e agli altri effetti particellari presenti in un videogioco, oppure ad una foresta con migliaia di alberi. Se dovessimo rappresentare ciascuno di questi oggetti (particella, albero, ecc.) con un proprio modello 3D, il carico di lavoro per la nostra GPU diventerebbe presto fatale, dato che dovrebbe calcolare la geometria, il colore, l'illuminazione, e così via, per ciascun singolo modello presente a schermo.
Per questo, nelle prossime pagine vedremo come disegnare e animare una semplice texture bidimensionale in uno spazio tridimensionale (i modelli 3D verranno affrontati nei prossimi articoli), e come impiegare utilmente le molte possibilità offerte da questa tecnica.
Ciò detto, cominciamo il nostro progetto dichiarando uno spritebatch che ci preparerà la geometria texturizzata, un font e un paio di texture:
SpriteBatch sprite_batch;
SpriteFont font;
Texture2D plasma, ship;
Aggiungiamo anche degli effetti per disegnare la nostra geometria e applicarvi le texture, nonché uno shader che si preoccupi del cosiddetto alpha testing:
BasicEffect bfx;
AlphaTestEffect afx;
Per capire di cosa stiamo parlando, immaginiamo che, per ciascun triangolo che compone la scena, la scheda grafica debba sapere, prima di tutto, quali pixel devono essere renderizzati a schermo e quali no. La risposta a questo quesito dipende dal superamento di una serie di test: l'alpha testing in particolare consente, nella sua versione più elementare, di scartare quei pixel che presentino valori di trasparenza troppo elevati (mentre nelle sue versioni più elaborate consente di realizzare una serie di effetti particolari, come nebbia od ombreggiature).
Carichiamo ora dalla Content Pipeline i dati necessari e inizializziamo lo spritebatch nel metodo LoadContent
:
sprite_batch = new SpriteBatch(GraphicsDevice);
font = Content.Load<SpriteFont>("small_font");
plasma = Content.Load<Texture2D>("plasma");
ship = Content.Load<Texture2D>("ship");
Fatto questo, non ci resta che impostare gli effetti affinché usino le impostazioni di disegno che desideriamo. In particolare, abilitiamo per entrambi il colore dei vertici (VertexColorEnabled
), attiviamo le texture per il BasicEffect
(che verranno moltiplicate per il colore dei vertici) e l'alpha per l'AlphaTestEffect
:
bfx = new BasicEffect(GraphicsDevice);
bfx.TextureEnabled = true;
bfx.VertexColorEnabled = true;
afx = new AlphaTestEffect(GraphicsDevice);
afx.Alpha = 1.0f;
afx.VertexColorEnabled = true;