In giro per un mappamondo libero: introduzione ad OpenStreetMap - Martin Kop...
Relazione esame informatica grafica
1. Compagnone Simone - Matricola 709649 email: s.compagnone1@campus.unimib.it
Zapata Flores Francklin Eduardo - Matricola 711223 email: f.zapataflores@campus.unimib.it
Progetto per l'esame di Elementi di Informatica
Grafica
Appello di Giugno 2010
Realizzazione di un' applicazione per la navigazione in una cittadina.
Abbiamo realizzato una rudimentale applicazione, utilizzando le OpenGl in c ++, per
simulare la navigazione immersiva in una mappa che viene creata passato in input al
nostro programma una immagine (deve essere nel formato .tga).
Per poter utilizzare il nostro programma:
1. Estrazione dell'archivio in una directory che già contiente le cartelle CGUtils
(se si lavora in ambiene windows deve esserci anche la cartella freeglut).
2. Entrare,da riga di comando, nella directory del nostro programma ed eseguire i
seguenti comandi:
• make
• ./esame.exe cittadina.tga (Cittadina.tga è una immagine che ci è stata fornita in allegato al
testo del progetto.)
OPPURE:
• make
• ./esame.exe prova.tga (immagine creata come secondo test per l'esame.)
Se si volesse provare l'applicazione con una nuova immagine, che deve essere
presente nella directory principale del programma, lanciare il programma:
• ./esame.exe <nome nuova immagine>.tga
e le caratteristiche della nuova immagine devono essere:
1. Deve essere nel formato .tga.
2. I colori che vengono gestiti nella nostra applicazione sono:
• un pixel nero (0,0,0) rappresenta il terreno asfaltato.
• un pixel bianco (255,255,255) rappresenta una parte di edificio.
• un pixel rosso (255,0,0) rappresenta il punto di partenza della vostra visita immersiva.
• un pixel verde (0,255,0) rappresenta una zona di terreno erboso.
• un pixel blu (0,255,0) rappresenta una zona ricoperta da acqua (mare/lago)
• un pixel rosso scuromarroncino (125,0,0) rappresenta un albero.
Altri colori non vengono gestiti dal programma in quanto non richiesti nel progetto.
2. Comandi per la navigazione:
• Tasto f : abilita / disabilita la navigazione nella mappa 3D.
• Tasto q : esce dal programma.
• Tasto s : abilita/disabilita la modalità “solid” della scena.
• Tasto g : abilita/disabilita la nebbia nella scena.
• Tasto f10-f11-f12 : modificano l'intensità della nebbia nella scena.
• Tasto 1-2: modifica l'intensità della luce dell'osservatore.
• Tasto Key_up : permette all'utente di muoversi avanti durante la navigazione
nella mappa.
• Tasto Key_down : permette all'utente di muoversi all'indietro
durante la navigazione nella mappa.
• Tasto Key_left : permette all'utente di muoversi verso sinistra durante la
navigazione nella mappa.
• Tasto Key_right : permette all'utente di muoversi verso destra durante la
navigazione nella mappa.
Descrizione struttura del progetto :
Per il nostro progetto abbiamo deciso di strutturare il codice in modo tale che possa
essere il più possibile “pulito” cercando di separare le funzioni utilizzate in diversi
file, lasciando il main semplice e chiaro.
La directory principale contiene :
• Makefile: per poter compilare il codice.
• Cittadina.tga/prova.tga: immagini usate per testare il programma che realizza
mappe 3D.
• Mappa.cpp: è il file che contiene il main dell'applicazione.
• Directory Obj : contiene tutti i file Obj che vengono utilizzati nel progetto.
• Directory Texture: contiene tutte le texture utilizzate nel progetto.
• Directory Tools:
1. Mouse.h : contiene tutte le funzioni per permettere all'utente di utlizzare il mouse.
2. Tastiera.h: contiene le funzioni che danno la possibilità all'utente di interagire , tramite la
tastiera , con il programma.
3. cOggetti.h : gestisce la lettura degli obj e il disegno dell'oggetto contenuto.
4. cTerreno.h: gestisce il caricamente delle texture, degli oggetti come insieme di file obj,
infine disegna la mappa 3D e vi posizione gli oggetti.
3. Scelte implementative e descrizione dei file principali :
La prima decisione che abbiamo preso sul progetto riguarda l'immagine che verrà
utilizzata per creare la mappa 3D. Abbiamo scelto che sarà l'utente a passare in input
al nostro programma l'immagine che vorrà utilizzare (la nostra gestione permette
anche di utilizzare immagini RGBA oltre che RGB ma sempre nel formato .tga), in
questo modo è possibile rendere indipendente il programma dall'immagine
“cittadina.tga” che ci è stata fornita con il testo del progetto.
L'applicazione come primo passo fondamentale carica la .tga passata in input e crea
una matrice associata che avrà le stesse dimensioni della immagine in pixel.
Ad ogni cella della matrice viene fatto corrispondere un identificativo che indica il
colore del pixel a cui fa riferimento.
Nello specifico abbiamo deciso di utilizzare i seguenti identificativi all'interno della
matrice:
• S : è l'identificativo associato al colore nero usato per la strada, alla quale verrà
associata la texture “asfalto.tga”.
• E : è l'identificativo associato al colore bianco usato per identificare i palazzi
che poi verranno caricati con file Obj e con la texure “terreno.tga”.
• R : è l'identificativo associato al colore rosso usato per decidere il punto di
partenza per la navigazione .
• P : è l'identificativo associato al colore verde usato per identificare il prato, al
quale verrà associato la texture “grass.tga”.
• B : è l'identificativo associato al colore blu usato per identificare il mare/lago,
al quale verrà associato la texture “acqua.tga”.
• M: è l'identificativo associato al colore marrone usato per identificare gli alberi
che verranno poi caricati con file Obj e con la texure associata al prato.
Successivamente vengono caricate le texture del prato, mare , punto di partenza,
strada , terreno degli edifici e si costruisce il terreno della mappa andando a leggere
la matrice appena creata e associando ad ogni “zolla” la texture corrispondente.
Naturalmente la grandezza della mappa dipende dalle dimensioni dell'immagine
passata in input dal programma e dalla variabile che abbiamo chiamato DELTA
dichiarata in mappa.cpp .
Una volta creata la mappa 3D ci siamo posti il problema di come caricare più file di
tipo .obj per gli alberi ( nella mappa non c'è un solo albero ripetuto n volte ma gli
alberi sono diversi) e di come posizionarli nelle giuste posizioni.
Quindi abbiamo deciso di creare due liste di oggetti una per gli alberi e una per gli
edifici.
Durante la lettura della matrice fatta precedentemente abbiamo salvato le posizioni
degli alberi in un array, che successivamente andiamo a leggere per posizionare uno
degli alberi contenuti nella lista descritta prima. ( la scelta dell'albero da posizionare
4. avviene in modo casuale, tramite una funzione random.).
Una volta posizionati gli alberi ci siamo chiesti come avremmo potuto creare palazzi
con altezze e grandezze differenti a seconda del numero di pixel bianchi vicini.
Come prima cosa abbiamo copiato la matrice usata precedentemente in una seconda
matrice che andiamo a modificare ogni volta che troviamo un palazzo.
Infatti andiamo a leggere la matrice ,dall'alto al basso e da sinistra verso destra, e
ogni volta che troviamo una cella contrassegnata con la lettera E ( identificativo usato
per gli edifici o meglio per i pixel bianchi dell'immagine in input) modifichiamo il
contenuto della cella con la lettera X salvando prima le coordinate (x,y) di tale cella.
Avendo supposto che ogni edificio sia sempre un quadrilatero, cerchiamo le
componenti connesse bianche della cella ,modificandone il valore con la lettera X e
salvando le coordinate dell'ultimo pixel in basso a destra bianco.
Le coordinate vengono salvate all'interno di una lista, i cui elementi contengono la
posizione iniziale e finale di ogni edificio(per definire un quadrilatero sono sufficienti
due veritici), nella mappa 3D.
Una volta conosciute tutte le coordinate , scorro la lista per andare a disegnare nelle
giuste posizioni uno degli stabili precedentemente caricati ( la scelta dell'edificio da
posizionare è identica a quella usata per gli alberi.).
Gli edifici vengono disegnati e scalati secondo la dimensione del quadrilatero che
devono occupare.
Il nostro programma gestisce anche le collisioni , infatti non è possibile uscire dalla
mappa e oltrepassare i muri degli edifici.
Tutto questo è stato possibile riutilizzando la lista di coordinate precedentemente
creata per gli edifici infatti ogni volta che l'utente si sposta durante la navigazione
viene scandagliata la lista per capire se il movimento fatto è ammissibile oppure se
tenta di collidere con un palazzo.
Note:
Dopo aver testato il nostro progetto nei computer dei Laboratori, dove abbiamo
svolto le esercitazioni, abbiamo notato che quest'ultimi fanno una certa fatica a far
girare il programma, ciò è probabilmente dovuto alla mancanza dei driver per
l'accelerazione 3D. Quindi, si consiglia, per non incombere in questo problema, di
utilizzare un computer in grado di gestire almeno l'accelerazione 3D.