Informatica Grafica ][ Texture in DirectX Marco Gribaudo marcog@di.unito.it DirectX supporta le texture in numerosi punti della sua Pipeline. In particolare, le DirectX 8, possono supportare fino a 8 texture diverse per generare i colori dei pixel degli oggetti, attraverso i PixelShader Ogni vertice, puo' quindi essere accompagnato da fino ad 8 coordinate UV distinte (una per texture). Le texture devono essere salvate su disco in formato.bmp E' anche possibile caricare texture salvate in file con formati differenti - ma e' decisamente piu' complicato. In questo corso ci limiteremo a trasformare eventuali formati grafici differenti in.bmp utilizzando strumenti esterni (come ad es. Photoshop). Per introdurre le texture, bisogna innanzi tutto modificiare i formati dei vertici per includere le coordinate UV. Di conseguenza anche le procedure per creare i vertici...... ed il comando per impostare il formato di vertici desiderato. occorre scrivere 1-V, perche il sistema di coordinate utilizzato dalle DirectX e' opposto rispetto a quello adottato da Maya.
Si devono poi aggiungere le variabili in cui memorizzare la texture, e la libreria di supporto per poterla caricare. Si inserisce quindi il codice per caricare la texture nella fase di inizializzazione dell'applicazione. Set D3DX = New D3DX8 Set texture = D3DX.CreateTextureFromFileEx(D3DDevice, _ "texture.bmp", D3DX_DEFAULT, _ D3DX_DEFAULT, _ 1, 0, D3DFMT_UNKNOWN, _ D3DPOOL_MANAGED, _ D3DX_FILTER_POINT, _ D3DX_FILTER_POINT, &HFF000000, _ ByVal 0, ByVal 0) Il nome tra virgolette, si riferisce al nome del file.bmp in cui e' contenuta la texture da caricare. E nel ciclo di rendering si aggiunge il comando per associare la texture corretta all'oggetto che si sta per disegnare. Il colore delle superfici viene ottenuto moltiplicando il colore della texture per quello del materiale. Per questo all'oggetto e' stato associato un materiale di colore bianco. Nell'operazione di applicazione delle texture, le DirectX devono distorcere l'immagine in esse contenuta. In tale processo, alcuni colori devono essere ricavati in base a quelli vicini.
Normalmente viene selezionato il texel piu' vicino alla posizione specificata dalla coordinata UV relativa al pixel che sta venendo disegnato. Queto procedimento pero', rischia di creare immagini spigolose e poco dettagliate. Per ovviare a questo problema le DirectX mettono a disposizione il filtraggio. Filtrare una texture, vuole dire applicare opportune formule matematiche per determinare tramite interpolazione i colori intermedi dei texel, quando questi non corrispondano esattamente con dei pixel. La formula piu' semplice e' l'interpolazione bilineare, attraverso la quale il colore di un texel viene determinato miscelando opprotunamente i 4 texel effettivi piu' vicini. In DirectX e' possibile abilitare il filtraggio bilineare delle texture con il seguente comando: Sebbene il filtraggio migliori notevolmente la qualita' delle texture, esso riduce pesantemente le prestazioni. Inoltre esso non risolve i problemi legati alla perdita di dettaglio durante la riduzione di una immagine. Per migliorare questa situazione sono state introdotte le MIPmap.
Una MIPmap (m u l t u m i n p a r v o) e' una sequenza di immagini rappresentanti la stessa figura, ognuna di dimensione dimezzata rispetto alla precedente. Una MIPmap occupa il 33% in piu' rispetto all'immagine semplice (per dimostrarlo basta immaginare di separare i canali dei colori rosso, verde e blu). Le copie rimpicciolite, vengono create automaticamente nella fase di caricamento dell'immagine originale. Durante la mappatura dei triangoli sullo schermo, la libreria grafica seleziona i Texel dall copia la cui dimensione risulti piu' idonea alla distanza dall'ossrevatore corrispondente. Per attivare le MIPmap nelle DirectX, occorre cambiare leggermente il comando di caricamento della texture (in modo da generare le copie rimpicciolite)... Ed aggiungere il seguente comando per abilitarne l'utilizzo. I modelli rappresentati fino ad ora, erano sempre definiti specficando le caratteristiche di vertici e spigoli direttamente in Visual Basic. Sebbene la tecnica funzioni bene per modelli molto piccoli, essa pone forti limitazioni all'utilizzo di modelli piu' complessi. Per risolvere questo problema, occorre poter caricare modelli creati con software di grafica 3D tipo Maya o 3d studio.
Solitamente l'operazione di importazione dei modelli si esegue salvando le geometrie su opportuni file. Occorre quindi un f i l t r o d i e s p o r t a z i o n e sul software di modellazione, ed un f i l t r o d i i m p o r t a z i o n e nel programma che utilizza le DirectX. Vi sono tre metodologie di importazione - esportazione con le DirectX: Parsificazione di formati noti Creazione di un formato proprietario Utilizzo del formato.x La p a r s i f i c a z i o n e d i f o r m a t i n o t i consiste nella lettura diretta di file salvati dagli applicativi di grafica (.3ds,.max,.ma,.mb) I vantaggi di tale tecnica risiedono nel fatto che si possono importare tutte le caratteristiche che un software di modellazione e' in grado di specificare. Gli svantaggi sono due: la scrittura della componente Visual Basic capace di importare i file di una applicazione e' decisamente complessa. Il lavoro viene legato fortemente ad una applicazione. Sostituire il programma di modellazione puo' implicare la riscrittura del codice di importazione. La c r e a z i o n e d i u n f o r m a t o p r o p r i e t a r i o consiste nel definre un proprio modo di salvare i dati, e nello scrivere uno script per il software (Maya, 3D studio, etc), ed una procedura di importazione in Visual Basic. La scrittura di tali moduli risulta notevolmente piu' semplice che quella di un parsificatore di un formato noto. Inoltre il cambiamento dello strumento di modellazione comporta la riscrittura solamente della componente di esportazione. Lo svantaggio riesiede nel fatto che occorre comunque un bravo programmatore per scrivere entrambe i moduli. Le DirectX hanno definito un loro formato di interscambio: il formato.x. Molti programmi di grafica hanno gia' incluse le funzionalita di esportazione in formato.x, e le DirectX posseggono funzioni per leggerli direttamente. Questo e' il modo piu' semplice per trasferire oggetti grafici. Esso pero' limita l'utilizzabilita' degli oggetti 3D ai soli programmi scritti per le DirectX. Inoltre non consente di esportare funzionalita' non supportate direttamente dalla libreria stessa. In questo corso ricorreremo alla creazione di un formato proprietario. Parsificazione di formati noti Creazione di un formato proprietario Utilizzo del formato.x
Prima di scrivere il codice per importare modelli, si deve definire il formato di esportazione. Il formato che adotteremo si ispirera' direttamente al codice utilizzato fino ad ora. Gli oggetti visualizzati sono memorizzati attraverso TRIANGLE_LIST, in cui vertici vengono creati attraverso la procedura MakeVe r t e x (da noi definita)... E gli spigoli specificati direttamente. In piu' occorre sapere quanti vertici e quanti spigoli compongono la nostra figura. Il formato da noi utilizzato, salvera' quindi prima il numero di vertici e di spigoli che compongono la figura. Poi l'elenco dei vertici, uno per riga. Ogni riga conterra' le informazioni relative alle posizioni x,y,z, alle normali nx,ny,nz ed alle coordinate di mappatura u,v.
Quindi l'elenco degli spigoli, 3 per riga (in questo modo ogni riga codifica un triangolo). Per prima cosa dovremo definire le variabili che memorizzano la geometria come variabili globali (quindi fuori dall'evento OnLoad), ed aggiungerne due per memorizzare il numero di vertici e di spigoli caricati. Quindi inseriremo la procedura per il caricamento del file: Private Sub LoadObject(FileName As String) Dim X, Y, Z, Nx, Ny, Nz, tu, tv As Single Dim I1, I2, I3 As Integer TotV = 0 TotI = 0 Open FileName For Input As #1 Input #1, TotV, TotI For T = 0 To TotI - 1 Step 3 Input #1, I1, I2, I3 I(T) = I1 I(T + 1) = I2 I(T + 2) = I3 Next Close #1 End Sub Inseriamo quindi il comando per richiamare la procedura che carica il file contenente le informazioni dell'oggetto esportato. Il nome tra parentesi indica il nome del file da importare. ReDim V(TotV), I(TotI) For T = 0 To TotV - 1 Input #1, X, Y, Z, Nx, Ny, Nz, tu, tv V(T) = MakeVertex(X, Y, Z, Nx, Ny, Nz, tu, tv) Next Ed infine modificheremo il codice per visualizzare l'oggetto, in modo che legga il numero di triangoli e di vertici dalle variabili prima impostate.