|
|
|
cignoni@iei.pi.cnr.it |
|
http://vcg.iei.pi.cnr.it/~cignoni |
|
|
|
|
|
|
#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. |
|
} |
|
|
|
|
|
|
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. |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
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… |
|
|
|
|
Disegnamo n volte un cubo |
|
for(i=0;i<18;++i) |
|
{ |
|
glLoadIdentity(); |
|
glRotatef(i*20,0,0,1); |
|
glTranslatef(1,0,0); |
|
glutWireCube(.5); |
|
} |
|
|
|
|
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… |
|
|
|
|
|
|
Trasformare l’anello in una striscia sottile |
|
Hint: l’operazione di scalatura può essere non
uniforme (e.g. schiaccio solo lungo un asse…) |
|
|
|
|
|
|
Trasformare la striscia in un anello di Moebius. |
|
hint: basta solo una rotazione… |
|
|
|
|
|
|
|
|
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. |
|
|
|
|
|
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. |
|
|
|
|
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); |
|
|
|
|
|
|
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 |
|
|
|
|
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 è |
|
|
|
|
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();} |
|
|
|
|
|
|
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… |
|
|
|
|
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); |
|
|
|
|
|
|
|
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 |
|