La struttura di una animazione reale, non differisce
molto da questa descrizione. Solitamente, è più facile ridisegnare
l'intero buffer dall'inizio per ogni fotogramma, piuttosto che
cercare di capire cosa deve essere ridisegnato. Ciò è verissimo per
i simulatori di volo, nel quale un cambiamento dell'orientamento del
mezzo, costringe al riposizionamento di tutto ciò che si vede fuori
dall'abitacolo. Nella maggior parte delle animazioni, gli oggetti
sono ridisegnati mediante semplici trasformazioni (un cambio del
punto di vista dell'osservatore, o un veicolo che si muove lungo la
strada, un oggetto ruotato leggermente). Se è necessario un lungo
processo di calcolo per le operazioni non grafiche, il tasso di
fotogrammi subisce un brusco calo. Da tenere in mente quindi, che il
tempo di attesa dopo la routine scambia_i_buffer() , viene
usato per questi calcoli. OpengGL non ha una routine di comando
scambia_i_buffer() in quanto
ciò è legato all'hardware disponibile ed al sistema di gestione
delle finestre nella macchina sulla quale il programma viene
eseguito.
In questo blog si parla di programmazione con il linguaggio C++, i post cercheranno di essere molto esplicativi sull'argomento trattato.
venerdì 29 marzo 2013
domenica 17 marzo 2013
Il Refresh che mette in pausa
Per alcune implementazioni di OpenGL, inoltre la
routine scambia_i_buffer(), oltre a invertire il buffer di memoria in
disegno e quello visualizzato, aspetta sino a quando il periodo di
rinfresco dello schermo non è concluso, e la schermata non viene
visualizzata. Questa routine permette al nuovo buffer di memoria di
essere visualizzato completamente, partendo dall'inizio. Assumendo
una frequenza di 60 volte al secondo questo significa che il numero
di fotogrammi massimi raggiungibili è di 60 frame per second
(fps), e se tutti i frame sono azzerati in meno di un
sessantesimo di secondo, l'animazione scorre fluidamente. Quel che
può accadere solitamente è la costruzione di un fotogramma è
troppo complessa per essere disegnata in 1/60 di secondo, pertanto il
fotogramma vien mostrato più di una volta. Se il tempo necessario
per calcolare è di 1/45 di secondo, la velocità raggiungibile di 30
fps, la grafica ha un tempo di ozio pari a 1/90 di secondo. Inoltre
il tempo di rinfresco dei monitor è costante, pertanto bisogna
aspettarsi delle conseguenze sulle prestazioni dell'applicazione.
Bisogna valutare attentamente le caratteristiche dell'applicazione in
fase di sviluppo, aggiungere delle componenti può non avere alcuna
conseguenza sino ad un certo punto quando un nuovo componente del
programma costringe il sistema a rallentare da 60 fps a 30 fps.
Inoltre se la complessità della scena è prossima al valore intero
(1/60, 1/30, 1/20) può subire variazioni casuali, le quali causano
una visualizzazione irregolare, fastidiosa agli occhi di un
osservatore. In questo caso è necessario semplificare la scena, in
modo che tutti i frame siano abbastanza veloci, o rallentarli tutti
allo stesso valore. Una gestione sofisticata del frame rate si rende
necessaria in queste applicazioni.
venerdì 8 marzo 2013
Animazione con OpenGL
Una delle cose più eccitanti da fare con la grafica
al computer è disegnare immagini in movimento. Che tu sia un
ingegnere che vuole osservare un componente meccanico in tutti i
lati, o un pilota che vuole imparare a far volare un aeroplano usando
una simulazione, o semplicemente un appassionato; l'animazione è una
parte importante della computer grafica. Al cinema il movimento viene
ottenuto mediante una sequenza di immagini proiettate per un
ventiquattresimo di secondo sullo schermo. Ogni immagine viene posta
dietro l'obiettivo, il diaframma si apre e l'immagine vine mostrata;
il diaframma si richiude temporaneamente, e la pellicola viene fatta
avanzare di un fotogramma, quindi il fotogramma vien proiettato e
così via. Se si osservano 24 immagini al secondo, il cervello umano
provvede ad amalgamarle in un'unica sequenza animata. Di fatto i
proiettori moderni mostrano un numero doppio di fotogrammi (48) al
secondo per ridurre l'evanescenza. Le immagini in computer grafica
sono solitamente rinfrescate alla velocità di 60 - 76 fotogrammi al
secondo, il limite massimo è dio 120 fotogrammi al secondo. Ma per
il tempo di risposta dell'occhio umano, superare questo limite non
produce alcun effetto visibile. La ragione per cui i film funzionano
è che ogni immagine è completa quando viene proiettata.
Traducendolo in pseudo-linguaggio, si può scrivere:
apri_finestra();
per (i=0; i < 1000; i++)
{
azzera_finestra();
disegna_fotogramma();
aspetta_tempo_1_24esimo_secondo();
}
Se si aggiunge al sistema il tempo per pulire lo
schermo e disegnare un'immagine, questo programma può dare dei
risultati non graditi in quanto si avvicinano pericolosamente a 1/24
di secondo. Gli oggetti visibili per 1/24 di secondo che presentano
un'immagine solida in teoria, ma quando vengono disegnati dal
computer possono apparire come spettri, in quanto il computer non fa
in tempo ad azzerare l'immagine presente per sostituirla con
un'altra. La maggior parte delle applicazioni OpenbGL consente il
doppio buffering, via hardware o software, in modo da ridurre i tempi
morti. Così mentre un'immagine viene mostrata, la successiva viene
creata in memoria ed i due buffer sono scambiati di posto al termine
della proiezione della prima immagine. Pertanto i due buffer lavorano
in parallelo alternandosi nella proiezione, è come avere due
proiettori contemporanei che proiettano lo stesso film alternandone i
fotogrammi. Una versione modificata del programma si scrive in questo
modo:
apri_finestra_in
doppio_buffer();
per (i=0; i < 1000; i++)
{
azzera_finestra();
disegna_fotogramma();
scambia_i_buffer();
}
lunedì 4 marzo 2013
GLUT, OpenGL Utility Toolkit
Come si sa OpenGL non contiene comandi di rendering,
ma è progettato per essere indipendente dal sistema operativo e
dalla gestione delle finestre. Di conseguenza, non contien comandi
per aprire le finestre, o leggere eventi dal mouse o dalla tastiera.
Sfortunatamente, è impossibile scrivere un programma di grafica
completo senza almeno aprire una finestra, e i programmi più utili
richiedono una forma di input da parte dell'utente per operare i
comandi del sistema operativo e del sistema a finestra. In molti
casi, un programma completo crea gli esempi più interessanti, in
questo GLUT semplifica il sistema di gestione delle finestre,
dell'input e così via. Se si possiede una implementazione di GLUT e
OpenGL sul sistema, gli esempi mostrati saranno eseguiti senza
problemi. Inoltre, i comandi di disegno delle OpenGL sono limitati al
disegno di geometrie semplici quali punti, linee e poligoni; GLUT
include alcune routine che permettono di creare oggetti 3D più
complicati quali sfere, toroidi, teiere. In questo modo le immagini
mostrate dai programmi sono rese più interessanti. GLUT può essere
non molto soddisfacente come applicazione, ma può essere un buon
punto di partenza per imparare OpenGL.
Gestione della Finestra
Cinque routine che eseguono i compiti necessari a gestire la finestra.- glutInit(int *argc, char **argv) inizia GLUT e processa ogni argomento di comando (per X, possono esserci opzioni sullo schermo e la geometria). glutInit() deve essere chiamata come prima GLUT routine.
- glutInitDisplayMode(unsigned int modo) specifica se si vuole usare RGBA o modello di colore indicizzato. Si può anche specificare se si vuole finestra a singolo o doppio buffer. (Se si lavora con la mappa dei colori ne si vorrà caricare uno; usare glutSetColor() per farlo.) Infine si può usare la routine per indicare se si vuole una finestra associata ad un tipo di profondità, tratto, buffer di accumulazione. Per esempio si vuole creare una finestra con doppio buffering, e colore RGBA, bisogna chiamare: glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH).
- glutInitWindowPosition(int x, int y) specifica localizzazione nello schermo partendo dall'angolo in lato a sinistra.
- glutInitWindowSize(int larghezza int taglia) specifica larghezza e altezza della finestra.
- int glutCreateWindow(char *stringa) crea la finestra del contesto OpenGL. Restituisce un indicatore unico per la finestra. Avvertenza, sino a quando glutMainLoop() viene chiamato la finestra non è visualizzata.
Le chiamate alla Visualizzazione
glutDisplayFunc(void (*func)(void)) è la prima e la più importante funzione di chiamata alla visualizzazione. Non appena GLUT determina il contesto della finestra che deve essere visualizzata, la chiamata alla funzione registrata mediante glutDisplayFunc() viene eseguita. Pertanto le routines di cui si ha bisogno per ridisegnare la scena nello schermo attraverso il richiamo della funzione.
Se il programma cambia i contenuti della finestra, a volte bisogna richiamare glutPostRedisplay(void), il quale fornisce una scappatoia a glutMainLoop() funzione per essere richiamata mediante questa nuove opportunità.
Eseguire il programma
L'ultima funzione da richiamare è glutMainLoop(void). Tutte le finestre che sono state create vengono mostrare, e il rendering di queste è ora effettivo. Il processo degli eventi comincia ed avviata la registrazione degli eventi a schermo. Una volta entrati nell'anello, non se ne esce.
domenica 3 marzo 2013
File inclusione OpenGL
Per tutte le
applicazioni OpenGL è necessario includere il file gl.h. Quasi tutte
le applicaizoni OpenGL usano GLU la sopramenzionata OpenGL Utility
Library. Così quasi ogni file sorgente OpenGL inizia con:
#include
<gl.h>
#include<glu.h>
Se si sta accedendo
direttamente alla libreria di interfaccia della finestra per
supportare OpenGL come GLX, AGL, PGL, WGL si devono includere file
addizionali di header. Ad esempio per richiamare GLX può essere
necessario aggiungere le linee di codice:
#include
<X11/xlib.h>
#include<GL/glx.h>
Se invece si sta
utilizzando GLUT per gestire le funzioni della finestra, bisogna
includere il codice:
#include<GL/glut.h>
Non è necessario
includere tutti i file intestazione automaticamente, ma è necessario
sceglierli. GLUT include tutte le funzioni contenute in WGL per
Microsoft Windows.
Iscriviti a:
Post (Atom)