| VS85 Team 的个人资料XNALearners日志列表留言簿 | 帮助 |
|
|
2009/1/22 SpriteBatch per effetti speciali - parte 4By Davide Luzzu – Webcast by Giuseppe Maggiore
Il (resto del) codice C#
// Generiamo un array di float che sono le altezze (y) dei punti di controllo. var tmp = Enumerable.Range(0, controlPoints.Width) // i ∈[0,controlPoints.Width-1] .Select(i => i / (float)controlPoints.Width) // x ∈[0,1] .Select(x => sin(-4.0f * t + 32.0f * pi * sigmoid(x + 0.5f) * x) * 0.1f + 0.5f) // y é l'altezza di un punto di controllo. La convertiamo in formato integrale. .Select(y => (UInt16)(y * (UInt16.MaxValue - 1))) .ToArray(); // Salviamo l'array di altezze nella texture. controlPoints.SetData<UInt16>(tmp);
Per dare la forma al serpente definiamo i punti di controllo sulle x e sulle y. Per fare ciò ci serviremo delle funzioni sin e sigmoid, che abbiamo definito in precedenza. Definiamo un range da 0 a 256, e ne facciamo il rapporto tra 0 e 1 in modo che x ∈ [0,1]. Dato che x è nel range [0,1] possiamo definire la forma del serpente usando il seno. Tale forma varia in base al tempo ( …4.0f * t…) ed ha, ad ogni istante di tempo, una forma curva definita da “…32.0f * pi * sigmoid(x + 0.5f) * x…”; variando tali parametri determineremo un’alterazione a piacimento della forma o del tempo di esecuzione del serpente. Una delle peculiarità derivanti da questa porzione di codice è il fatto che, ciò che viene disegnato, è ad una dimensione algoritmicamente, ma a due dimensioni visivamente; la x difatti è un seno, e ciò è sufficiente per disegnare il serpente. Ma la x è l’unica variabile da cui dipende effettivamente il controllo dello spazio. Quindi è monodimensionale. A questo punto la y è libera, e la si utilizza per inserire i dati di illuminazione, quelli che avevamo previsto inserendo SurfaceFormat.Luminance16 nella definizione della texture. Convertiamo la y in intero a 16 bit Unsigned, e trasformiamo la struttura in un array. Quindi la variabile “tmp” è un array di interi a 16 bit Unsigned. Non resta che inserire i dati dei punti di controllo nella Texture2D.
// Carichiamo la texture di sfondo. var background = Content.Load<Texture2D>("background"); /// Disegnamo la texture di sfondo. Questa operazione non dipende in alcun modo da come poi disegneremo il serpente.
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState); spriteBatch.Draw(background, new Rectangle(0, 0, 800, 600), Color.White); spriteBatch.End();
Per rendere l’applicazione più gradevole prevediamo uno sfondo, di nostro gradimento, che disegnamo con lo SpriteBatch. Ci preme ribadire che tale operazione non dipende in alcun modo da come disegneremo il serpente.
/// Disegnamo il serpente con il nostro shader in alpha blending sulla scena precedente. L'operazione di disegno genera un serpente che passa per i punti di controllo della texture "controlPoints".
new Vector3[] { new Vector3(0, 1, 1} .Select((color, index) => new {color, index}) .ToList().ForEach(snake => { fx.Parameters["SnakeColor"].SetValue(snake.color);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
fx.Begin(); pass(0, p => p.Begin());
spriteBatch.Draw(controlPoints, new Rectangle(0, 100 + 100 * snake.index, 800, 400), Color.White);
pass(0, p => p.End()); fx.End();
spriteBatch.End(); });
base.Draw(gameTime); }
Finalmente disegnamo il serpente! Definiamo innanzittutto il colore con un vettore, un azzurro tenue. Inseriamo il colore in ogni posizione di un array di Vector3 e lo modifichiamo con la tecnica dello Shader. Il primo passo è impostare il parametro “SnakeColor” dello Shader con l’azzurro appena definito. Iniziamo lo SpriteBatch con il metodo “Begin()” e avviamo il rendering dello shader con
fx.Begin();
che provoca, inoltre, la sostituzione automatica dello Shader di default nello SpriteBatch. A questo punto non resta che aprire il passo zero di rendering con
pass(0, p => p.Begin());
e disegnamo sullo schermo la Texture2D. Chiudiamo il passo e indichiamo che lo shader ha terminato la sua tecnica con
fx.End();
ricordandoci di chiudere anche le funzioni dello SpriteBatch con la funzione “End()”.
评论 (3)
引用通告此日志的引用通告 URL 是: http://vs85team.spaces.live.com/blog/cns!B49FFA0EB319A219!553.trak 引用此项的网络日志
|
|
|