Note
Struttura
Costruzione di Interfacce
Lezione 7
Esercitazione Trasformazioni
cignoni@iei.pi.cnr.it
http://vcg.iei.pi.cnr.it/~cignoni
Skeleton Glut
#include<stdio.h>
#include<GL/glut.h>
void myRedrawFunc()
{
glClear(GL_COLOR_BUFFER_BIT);
// Draw something
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutCreateWindow("sierp");
glutDisplayFunc(myRedrawFunc);
glutMainLoop(); //Passare al SO il controllo.
}
Aggiungiamo un cubo
Grazie a Glut….
Usage
void glutSolidCube(GLdouble size);
void glutWireCube(GLdouble size);
size Length of each edge.
Description
glutSolidCube and glutWireCube render a solid or wireframe cube respectively. The cube is centered at the modeling coordinates origin with sides of length size.
Ruotiamo il cubo
Ruotare il cubo significa
Risposta semplice
faccio una glRotate prima di disegnare il cubo
Risposta vera
Cambio il sistema di riferimento della camera rispetto al sistema di riferimento del cubo.
Nota:
Perche’ facciamo loadidentity()?
glRotate come tutte le trasf fatte da opengl modifica la matrice corrente
Composizione di trasformazioni
Fare
glRotate
glTranslate
E’ ben  diverso di
glTranslate
glRotate
Poiché le matrici si compongono per post moltiplicazione l’ordine sembra quello inverso…
Trucco: per visualizzare il risultato partire dall’ultima trasformazione e applicarle all’indietro…
Proviamo a disegnare un anello
Disegnamo n volte un cubo
for(i=0;i<18;++i)
{
glLoadIdentity();
glRotatef(i*20,0,0,1);
glTranslatef(1,0,0);
glutWireCube(.5);
}
Migliore inquadratura
Aggiungiamo uno scaling e una rotazione generale cioe’ di tutta la scena
Devono essere la prima cosa che faccio (devono essere applicate a tutto l’anello)
Inutile farle tutte le volte, più educato salvare lo stato…
Esercizio
Trasformare l’anello in una striscia sottile
Hint: l’operazione di scalatura può essere non uniforme (e.g. schiaccio solo lungo un asse…)
Esercizio 2
Trasformare la striscia in un anello di Moebius.
hint: basta solo una rotazione…
Wire vs Solid
Quando si disegna un oggetto mostrandone solo gli spigoli si dice che si disegna in modadlità WIREFRAME
Cosa succede se si usava glutSolidCube?
Nota: glutSolidCube e glutWireCube sono funzioni di glut e NON di Opengl.
Hidden surface
Non appena si passa ad una modalità non wireframe si deve gestire il problema delle  superfici nascoste.
Totalmente gestito da opengl purchè
Il nostro contesto abbia uno Zbuffer
Si pulisca lo zbuffer ogni volta
Si abiliti il test sullo zbuffer durante il disegno.
Lighting
Per ora ne sapete poco…
Sfruttiamo per quanto possibile i default di OpenGL.
Di Default Opengl ha una luce direzionale che illumina lungo la z negativa.
Purtoppo il volume di vista iniziale è il cubo unitario, ma la direzione di vista e’ quella sbagliata
Meglio settare la vista ortografica a mano
glOrtho(-1,1,-1,1,-1,1);
Lighting 2
Quindi
MatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
e sostituire a
glutWireCube -> glutSolidCube
Memento Frame
Di default come trasf di proiezione mette l’identica, che corrisponde ad una camera ortografica sul volume di default (Box centrato rispetto all’origine, di lato 2), o quasi…
Infatti la camera ortografica del volume di default è
Animazione
Come si fa animazione in un’applicazione event driven?
Vietato disegnare continuamente un frame dopo l’altro senza mai uscire dalla callback di display!!
Si deve chiedere al so di dirci quando non ha nulla di piu’ importante da fare e allora disegnare il frame successivo
void myIdle()
{ glutPostRedisplay();}
Idle Processing
Tutti i so mettono a disposizione una callback (evento) che scatta scattare quando non hanno nulla da fare (idle processing)
Le varie app vengono cosi chiamate ogni qual volta il so non ha altro da fare.
NOTA: Non si ha alcuna garanzia di QUANDO si viene chiamati…
Idle processing
Tutti i calcoli relativi alle posizioni, orientamento durante le animazioni DEVONO essere temporizzati.
Per rendere il cambio di fotogramma stabile, si usa la tecnica del double buffering;
Si disegna la scena in un buffer nascosto e si mostra solo quando abbiamo finito.
glutSwapBuffers();
Si deve chiedere al momento dell’apertura della finestra (contesto)
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
Sempre piu’ difficile
Aggiungiamo nell’ordine
L’anello che e’ formato da una doppia striscia
Una pallina che rotola sull’anello
L’anello che ruota su se stesso