Iniziamo a fare qualcosa di pratico. So che vorreste subito mettere mano al 3D ma prima partiamo dal 2D e parliamo di Font ossia come scrivere il testo sulle finestre. In DirectX10 (lo era anche nel 9) la grafica bidimensionale non esiste: il testo e gli sprite, di cui parlerò prossimamente, sono delle funzioni scritte da microsoft che non fanno altro che posizionare dei poligoni piani su cui inserire le immagini su cui viene elaborato il testo o le immagini (gli sprite). L’utilizzo è abbastanza semplice. Innanzitutto dichiariamo la variabile da utilizzare
ID3DX10Font* font;
HRESULT hr=D3DX10CreateFontA(device, 24, 0, FW_NORMAL, 1, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Arial", & font);
Il primo parametro è il device. Il secondo è l’altezza (non è quella classica che vedete in Word o in Visual Studio, ma è in unità logiche) e la larghezza (mettendo zero inserirà lui quella corretta).
Viene poi il peso, lo spessore del font
FW_BLACK
FW_BOLD
FW_EXTRABOLD
FW_EXTRALIGHT
FW_HEAVY
Ne esistono anche altre, basta vedere nella documentazione del C++.
Seguono il numero di miplevels (inserite 1, dedicherò interi articoli a questo concetto) ed un booleano che specifica se usare o meno il testo corsivo.
Seguono il charset, il tipo di precisione e la qualità (per esempio nel mio caso Antialiased rende il testo molto più nitido e senza seghettature) e l'impostazione per il pitch e la famiglia di font (tutte queste sono impostazioni dei font di windows, non specifiche di DirectX). Infine la cosa più importante, il nome del font passato come stringa e la classe font passata per riferimento). Se l'HRESULT è uguale ad S_OK allora la creazione è andata bene.
Ora è possibile usare il testo per scrivere.
font->DrawText(NULL,text,-1,&rectangle,DT_LEFT,D3DXCOLOR(1,1,1,1));
Il primo parametro è lo Sprite che spiegherò nei prossimi tutorial. Passando NULL utilizzerà un rendering normale, con uno sprite sarà possibile ruotare e deformare il testo come fosse in 3D. Il parametro text è una stringa (char* o il typedef LPCSTR che, per chi non è praticissimo di C++ è solo un modo per chiamarlo in modo diverso ma è lo stesso). Questa sarà la stringa passata. Il successivo indica la lunghezza del testo da stampare (-1 significa fino alla fine). Rectangle è un LPRECT (ossia un puntatore a RECT) e rappresenta la zona in cui sarà inserito il testo. Il successivo parametro è fondamentale in quanto spiega come scrivere il testo. Eccone alcuni (che possono essere combinabili usando l'or logico |).
DT_BOTTOM : da combinare con DT_SINGLELINE, allinea il testo in basso DT_CALCRECT : non scriverà nulla ma calcolerà il rettangolo necessario per il testo inserendolo nel RECT oppure solo l'altezza nel caso di testo disposto in più linee. In questo caso dovrete passare un rect con una posizione valida in larghezza e lui restituirà l'altezza. DT_CENTER : centra il testo orizzontalmente DT_EXPANDTABS : espande i tab DT_LEFT : allinea a destra DT_NOCLIP : il testo non viene tagliato. Aumentano anche le prestazioni DT_RIGHT : allinea il testo a destra DT_RTLREADING : mostra il testo da destra a sinistra per le lingue che hanno la direzione del testo invertita DT_SINGLELINE : forza il testo a stare su una singola linea DT_TOP : allinea il testo in alto DT_VCENTER : centra il testo verticalmente (valido solo per testo su una singola linea) DT_WORDBREAK :manda a capo il testo quando supera la dimensione del rettangolo
Infine c'è il colore. La funzione D3DXCOLOR restituisce il colore utilizzando i colori rosso, verde, blu ed alpha. Quest'ultimo è il livello di opacità. Se mettete un valore inferiore ad uno il testo sarà semitrasparente fino al valore zero in cui non vedrete nulla.
Ci sono altre cose utili da sapere sui font. La prima è come ottenere una descrizione.
D3DX10_FONT_DESC desc;
font->GetDesc(&desc);
desc conterrà tutti i valori con cui avrete creato il font.
Ottimizzare il testo
Il font quando voi gli date l'ordine di effettuare un rendering non fa altro che generare una immagine in memoria con le lettere presenti nel testo e montarle per mostrarle a video. E' possibile aiutare DirectX10 ad ottimizzare tale processo.
font->PreloadCharacters(begin,end);
Questa istruzione fa in modo che il font tenga in memoria i caratteri specificati tramite un range di codici ascii.
font->PreloadText("TEXT",-1);
Questa invece precarica un testo. Se continuerete a scrivere lo stesso testo le prestazioni miglioreranno.
Ricordate che quasi tutte le istruzioni possono utilizzare il formato testo ASCII o UNICODE specificando A o W al termine (esempio DrawTextA). Nel prossimo tutorial inizieremo il 3D.
Demo