2010-07-31 23 views
14

Non voglio entrare nella trigonometria complessa per calcolare le rotazioni e cose del genere per il mio mondo 3D, quindi gluLookAt sembra una buona alternativa. Secondo la documentazione tutto quello che devo fare è posizionare 3 coordinate per la posizione delle telecamere, tre per quello che dovrei guardare e una posizione "su". L'ultimo non aveva senso finché non pensavo che dovesse essere ad angolo retto con la linea di vista nella direzione in cui dovrebbe essere la parte superiore dello schermo.Come si usa gluLookAt correttamente?

Non funziona del tutto. Ho un po 'di codice Python. Questo è il codice che inizializza alcuni dati e codice modalità per quando entro questa parte del gioco:

def init(self): 
    self.game_over = False 
    self.z = -30 
    self.x = 0 
def transfer(self): 
    #Make OpenGL use 3D 
    game.engage_3d(45,0.1,100) 
    gluLookAt(0,0,-30,0,0,0,0,1,0) 

"game.engage_3d (45,0.1,100)" sostanzialmente imposta la matrice di proiezione di avere un Angolo di visuale di 45 gradi e coordinate vicine e lontane tra 0,1 e 100.

Il primo gluLookAt posiziona correttamente la telecamera nella posizione corretta.

Ho un cubo disegnato con il centro di (0,0,0) e funziona bene senza gluLookAt. Prima di giungere che ho questo codice:

gluLookAt(self.x,0,self.z,0,0,0,0,1,0) 
if game.key(KEY_UP): 
    self.z += 2.0/game.get_fps() 
if game.key(KEY_DOWN): 
    self.z -= 2.0/game.get_fps() 
if game.key(KEY_LEFT): 
    self.x += 2.0/game.get_fps() 
if game.key(KEY_RIGHT): 
    self.x -= 2.0/game.get_fps() 

Ora questo, la posizione fino dovrebbe sempre essere la stessa che è sempre ad angolo retto. Quello che avrei pensato sarebbe stato spostare avanti e indietro l'asse z con i tasti su e giù e sinistra e destra attraverso l'asse x con i tasti sinistro e destro. Quello che succede in realtà, è quando uso i tasti sinistro e destro, il cubo ruoterà attorno all'occhio che viene accelerato dai tasti. Il tasto su fa in modo che un altro cubo dal nulla taglia lo schermo e colpisca il primo cubo. La chiave giù riporta indietro il misterioso cubo clonato. Questo può essere combinato con la rotazione per dare un risultato completamente diverso come si presenterebbe nella documentazione.

Cosa diavolo è sbagliato?

Grazie.

risposta

37

(L'intuizione dietro il vettore "su" in gluLookAt è semplice: guarda qualsiasi cosa Ora inclina la testa di 90 gradi Dove non sei cambiato, la direzione che stai guardando non è cambiata, ma l'immagine nella tua retina ha chiaramente Qual è la differenza? Dove punta la tua testa. Quello è il vettore in su.)

Ma per rispondere alla tua domanda: le chiamate gluLookAt non dovrebbero essere concatenate. In altre parole, l'unico modello in cui è OK per utilizzare gluLookAt se non si sa esattamente come funziona è la seguente:

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
gluLookAt(...); 
# do not touch the modelview matrix anymore! 

Sembra dal codice che si sta facendo qualcosa di simile:

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
gluLookAt(...); 
# some stuff.. 
gluLookAt(...); 

Questo genererà risultati strani, perché gluLookAt moltiplica la matrice corrente per la matrice di visualizzazione che calcola. Se vuoi concatenare le trasformazioni, è molto meglio capire come fare a glTranslate, glScale e glRotatef per te. Ancora meglio, dovresti imparare come funzionano le trasformazioni di coordinate e attenersi a glMultMatrix.

+0

Grazie mille. Funziona perfettamente ora. Posso passare ora a cose più avanzate. Ma stai dicendo che gluLookAt è lento? –

+2

Non è che sia lento. È che gluLookAt nasconde alcune cose che dovresti sapere quando stai facendo una seria programmazione OpenGL. In particolare, dovresti imparare a combinare diverse trasformazioni di coordinate.A questo ci si abitua, ed è alquanto frustrante all'inizio, ma alla fine si ripaga: molte tecniche grafiche sono costruite in modo intelligente sulla trasformazione dei sistemi di coordinate. –

+36

+1 se in realtà inclini la testa :-) –