Possiamo manipolare le coordinate di texture di una operazione Draw usando il parametro source rectangle
. Possiamo ad esempio selezionare la porzione di texture da disegnare, oppure quanto ripetere la texture.
Il source rectangle, per comodità, è inteso in pixel e non (come le coordinate di texture) in valori normalizzati nell'intervallo [0..1]
. Se vogliamo prendere solo il quadrante superiore sinistro di una texture di dimensione w×h
, allora dovremo usare un source rectangle [0,0,w/2,h/2]
; se volessimo il quadrante inferiore sinistro, allora dovremmo usare [0,h/2,w/2,h/2]
come source rectangle; per ripetere la texture due volte sull'asse orizzontale, il source rectangle sarà [0,0,w×2,h]
, e così via.
Per disegnare immagini con valori di coordinate di texture maggiori di 1, ossia in cui la texture si ripete, dovremo attivare il wrapping delle coordinate di texture. Il tipo di gestione delle coordinate di texture viene determinato dal terzo parametro della funzione SpriteBatch.Begin
:
sprite_batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, null, null);
Questa chiamata attiva lo SpriteBatch
e imposta tutti i parametri al loro valore di default, tranne la gestione delle coordinate di texture, che vengono impostate a LinearWrap
.
Le coordinate di texture hanno due tipologie di gestione: una determina come vengono calcolati i colori dei pixel quando le coordinate di texture cadrebbero in mezzo tra quattro pixel (ossia come vengono calcolati i pixel intermedi), e l'altra determina come vengono individuati i pixel "fuori" dalla texture, ossia per valori di coordinate di texture negative o maggiori di 1.
Le principali possibilità di interpolazione (la gestione dei pixel intermedi) sono:
Interpolazione | Descrizione | Prestazioni |
---|---|---|
Point | sceglie il pixel più vicino | velocissimo ma bassa qualità |
Linear | interpola tra i quattro pixel più vicini | veloce e alta qualità |
Anisotropic | interpolazione ad alta qualità su vari pixel vicini, secondo l'inclinazione del piano su cui la superficie sta venendo disegnata | lento e altissima qualità |
Quest'ultima modalità non ha senso per superfici 2D come quelle disegnate con lo SpriteBatch
mentre ha senso per scene con ampi triangoli quasi perpendicolari al piano dello schermo.
Le principali possibilità di gestione dei valori negativi o maggiori di 1 sono:
Modalità | Descrizione |
---|---|
Clamp | se il valore è negativo lo forza a 0, se maggiore di 1 lo forza a 1 |
Wrap | usa solo la parte frazionaria del numero |
Gli stati precostituiti che combinano queste opzioni sono accessibili da proprietà statiche della classe SamplerState
:
SamplerState AnisotropicClamp;
SamplerState AnisotropicWrap;
SamplerState LinearClamp;
SamplerState LinearWrap;
SamplerState PointClamp;
SamplerState PointWrap;
Esistono altre opzioni di campionamento che possono essere combinate costruendo manualmente un SamplerState
.
Dopo aver inizializzato lo SpriteBatch in modo da fare interpolazione lineare con ripetizione, possiamo disegnare la scena: ecco il disegno di una porzione di una texture molto grande (stars) su tutto lo schermo:
sprite_batch.Draw(stars, new Rectangle(0, 0, 800, 480),
new Rectangle(0, 0, 400, 200), Color.White);
e l'asteroide ripetuto 10×7
volte:
sprite_batch.Draw(asteroid, new Rectangle(0, 0, 800, 480), new Rectangle(0, 0, asteroid.Width * 10, asteroid.Height * 7), Color.White);
Il risultato è: