2011-09-11 25 views
22

Ho scritto un motore di gioco di base 2D in OpenGL/C++ e ho imparato tutto mentre procedevo. Sono ancora piuttosto confuso sulla definizione dei vertici e la loro "posizione". Cioè, sto ancora cercando di capire il meccanismo di conversione da vertice a pixel di OpenGL. Può essere spiegato brevemente o qualcuno può indicare un articolo o qualcosa che lo spieghi. Grazie!OpenGL definisce la posizione del vertice in pixel

+1

FYI Vertices è il plurale di 'vertice'. In OpenGL, le coordinate del vertice vengono moltiplicate per una serie di matrici per arrivare a una schermata finale X, coordinata Y. –

+1

Sebbene conosca la risposta alla tua domanda, anch'io sono un principiante in OpenGL, quindi non invierò una risposta per timore che dovrei dire qualcosa che non è tecnicamente corretto. Quello che farò è consigliarvi di leggere l'OpenGL superlativo. Risolverà le cose per te. Se non hai paura di matematica, ti consiglio [questo libro online] (http://www.arcsynthesis.org/gltut/). –

+0

Questo non è un tentativo di risposta, ma forse aiuterà a chiarire. Le posizioni dei vertici non hanno nulla a che fare con le posizioni dei pixel a meno che non si abbia a disposizione il proprio viewport/transforms * just * right. I vertici vivono nel loro spazio unitario. Per esempio. se il tuo pezzo di carta è 10x10, allora quanto è grande? Aspetta: 10x10 pollici, centimetri, piedi, miglia ...? –

risposta

26

Questa è una conoscenza piuttosto di base che la tua risorsa di apprendimento OpenGL preferita dovrebbe insegnarti come una delle prime cose. Ma comunque la pipeline OpenGL standard è la seguente:

  1. La posizione del vertice si trasforma da oggetto-spazio (locale a qualche oggetto) nel mondo-spazio (rispetto a qualche sistema di coordinate globale). Questa trasformazione specifica dove il tuo oggetto (a cui appartengono i vertici) si trova nel mondo

  2. Ora la posizione dello spazio del mondo viene trasformata in camera/vista-spazio. Questa trasformazione è determinata dalla posizione e dall'orientamento della telecamera virtuale con la quale si vede la scena. In OpenGL queste due trasformazioni sono in realtà combinate in una, la matrice modelview, che trasforma direttamente i vostri vertici dallo spazio-oggetto allo spazio-vista.

  3. Successivamente viene applicata la trasformazione di proiezione. Mentre la trasformazione del modelview dovrebbe consistere solo in trasformazioni affini (rotazione, traslazione, ridimensionamento), la trasformazione della proiezione può essere una prospettiva, che distorce sostanzialmente gli oggetti per realizzare una prospettiva reale (con oggetti più lontani essendo più piccoli). Ma nel tuo caso di una vista 2D sarà probabilmente una proiezione ortografica, che non fa altro che una traduzione e un ridimensionamento. Questa trasformazione è rappresentata in OpenGL dalla matrice di proiezione.

  4. Dopo queste 3 (o 2) trasformazioni (e quindi dopo la divisione prospettica del componente w, che effettivamente realizza la distorsione prospettica, se presente), ciò che si ha sono coordinate del dispositivo normalizzate. Ciò significa che dopo queste trasformazioni le coordinate degli oggetti visibili devono essere comprese nell'intervallo [-1,1]. Tutto al di fuori di questo intervallo viene ritagliato.

  5. Nella fase finale della trasformazione finestra viene applicato e le coordinate vengono trasformate dalla gamma [-1,1] nel [0,w]x[0,h]x[0,1] cubo (assumendo un glViewport(0, w, 0, h) chiamata), che sono il vertice' posizioni finali nel framebuffer e quindi le sue coordinate di pixel.

Quando si utilizza un vertex shader, punti da 1 a 3 sono effettivamente fatto nel shader e può quindi essere fatto in qualsiasi modo tu voglia, ma di solito uno conforme a questo standard di modelview -> gasdotto di proiezione, anche.

La cosa principale da tenere a mente è che dopo il modelview e la proiezione si trasforma ogni vertice con le coordinate esterne all'intervallo [-1,1] verrà ritagliato. Quindi il [-1,1] -box determina la scena visibile dopo queste due trasformazioni.

Quindi dalla tua domanda presumo vuoi utilizzare un sistema di coordinate 2D con unità di pixel per le coordinate e le trasformazioni del vertice? In questo caso, è consigliabile utilizzare glOrtho(0.0, w, 0.0, h, -1.0, 1.0) con w e h come dimensioni della vista. Questo in pratica neutralizza la trasformazione della viewport e quindi trasforma i tuoi vertici dalla casella [0,w]x[0,h]x[-1,1] nella casella [-1,1], che la trasformazione della viewport quindi trasforma nella casella [0,w]x[0,h]x[0,1].

Queste sono state spiegazioni abbastanza generali senza menzionare che le trasformazioni effettive sono fatte da moltiplicazioni vettoriale matrice e senza parlare di coordinate omogenee, ma avrebbero dovuto spiegare l'essenziale. Questo documentation of gluProject potrebbe anche darti qualche idea, in quanto modella la pipeline di trasformazione per un singolo vertice. Ma in questa documentazione hanno effettivamente dimenticato di menzionare la divisione per componente w (v" = v'/v'(3)) dopo il passaggio v' = P x M x v.

EDIT: Non dimenticare di guardare il first link in risposta di epatel, il che spiega la pipeline di trasformazione un po 'più pratico e dettagliato.

-3

Google per "opengl rendering pipeline". I primi cinque articoli offrono tutti una buona esposizione.

La transizione chiave dai vertici ai pixel (in realtà, i frammenti, ma non sarete troppo distanti se pensate che "pixel") è nella fase di rasterizzazione, che si verifica dopo che tutti i vertici sono stati trasformati da coordinate del mondo per schermare le coordinate e ritagliare.

+5

Non una risposta ... –

+0

@Armen: "Può essere spiegato brevemente o qualcuno può indicare un articolo o qualcosa che lo spieghi." Non l'ho fatto? –

+1

La tua risposta originale a cui fa riferimento il mio commento conteneva solo la prima riga di quella che ora è la tua risposta modificata. Non era una risposta. Era un'istruzione per usare Google. –

11

Si chiama trasformazione.

I vertici sono impostati in coordinate 3D che vengono trasformate in coordinate di una vista (nella visualizzazione finestra). Questa trasformazione può essere impostata in vari modi. La trasformazione ortogonale può essere più semplice da capire come antipasto.

http://www.songho.ca/opengl/gl_transform.html

http://www.opengl.org/wiki/Vertex_Transformation

http://www.falloutsoftware.com/tutorials/gl/gl5.htm

+0

+1 Per il primo collegamento, questo è molto più dettagliato e preciso delle mie spiegazioni. –

3

primo luogo essere consapevoli che OpenGL non utilizza pixel standard di coordinate. Intendo per quello per una particolare risoluzione, es. 800x600 non hai coordinate orizzontali nel range 0-799 o 1-800 calpestato da uno. Piuttosto, le coordinate vanno da -1 a 1 successivamente inviate all'unità di rasterizzazione della scheda grafica e successivamente corrispondono a una particolare risoluzione.

Un passo avanti qui - prima di tutto che si dispone di una matrice ModelViewProjection (o di una matrice di viewProjection in alcuni casi semplici) che prima di tutto ciò che esegue il cast delle coordinate si utilizza su un piano di proiezione. L'uso predefinito è quello di implementare una telecamera che converte lo spazio del mondo in 3D (Vista per posizionare una telecamera nella giusta posizione e Proiezione per colare le coordinate 3D nel piano dello schermo. In ModelViewProjection è anche un passo per collocare un modello nel giusto posto nel mondo).

Un altro caso (ed è possibile utilizzare la matrice di Proiezione in questo modo per ottenere ciò che si desidera) è utilizzare queste matrici per convertire un intervallo di risoluzioni in un altro.

E c'è un trucco che ti servirà. Dovresti leggere su modelViewProjection matrix e camera in openGL se vuoi fare sul serio. Ma per ora ti dirò che con la matrice corretta puoi semplicemente lanciare il tuo sistema di coordinate (e cioè utilizzare intervalli da 0-799 orizzontali e 0-599 verticali) a intervalli standardizzati di -1: 1. In questo modo non vedrai quella sottostante openGL api usa il suo sistema -1 a 1.

Il modo più semplice per ottenere ciò è la funzione glOrtho. Ecco il link alla documentazione: http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

Questo è esempio di un corretto utilizzo: glMatrixMode (GL_PROJECTION) glLoadIdentity(); glOrtho (0, 800, 600, 0, 0, 1) glMatrixMode (GL_MODELVIEW)

Ora è possibile utilizzare proprio modelview matrice vale a dire. per oggetti di traduzione (in movimento) ma non toccare l'esempio di proiezione. Questo codice dovrebbe essere eseguito prima di qualsiasi comando di disegno. (Può essere dopo aver inizializzato opengl, infatti, se non si utilizza la grafica 3d).

Ed ecco esempio funzionante: http://nehe.gamedev.net/tutorial/2d_texture_font/18002/

solo disegnare le vostre figure invece di disegnare testo. E c'è un'altra cosa: glPushMatrix e glPopMatrix per la matrice scelta (in questo esempio la matrice di proiezione) - non lo userai fino a quando non combinerai 3d con il rendering 2D.

E puoi ancora utilizzare la matrice del modello (ad esempio per posizionare le piastrelle da qualche parte nel mondo) e visualizzare la matrice (ad esempio per la visualizzazione zoom o per scorrere il mondo - in questo caso il tuo mondo può essere più grande della risoluzione e potresti ritagliare visualizzare con traduzioni semplici)

Dopo aver visto la mia risposta, vedo che è un po 'caotico, ma se confondete - leggete i modelli, Visualizza e Proiezione dei matix e provate l'esempio con glOrtho. Se sei ancora confuso, non esitare a chiedere.

1

MSDN ha un ottimo explanation. Potrebbe essere in termini di DirectX ma OpenGL è più o meno lo stesso.

+1

Ma sicuramente confonde i principianti con i suoi prodotti a matrice vettoriale dispari invece dei prodotti a matrice di vettore di OpenGL. –

+0

Bene dipende davvero .. se si implementano le classi matrice e vettoriale da soli, allora sono entrambi identici;) – Goz

Problemi correlati