2013-04-21 16 views
14

Attualmente sto lavorando all'implementazione di un renderer potenziato OpenGL in un motore di gioco 2D.Come trasformare il mondo 2D in coordinate dello schermo OpenGL

Poiché lo spazio di coordinate dello schermo OpenGL è [-1,1], sono un po 'confuso su come dovrebbe essere interfacciato con un sistema di coordinate del mondo cartesiano 2D generico.

Diciamo che il viewport nel mio mondo è [-500, -500] a [1200, 1200], dove [0, 0] è l'origine del mondo. Devo solo tradurre e ridimensionare fino a coordinate tra -1 e 1? O c'è qualche altra forma di trasformazione che deve essere eseguita?

Come si calcola dove disegnare oggetti sullo schermo che hanno posizioni definite nel proprio sistema di coordinate?

Apprezzerei una spiegazione con e senza glOrtho (quindi possiamo usare anche l'asse Z per gli effetti prospettici).

risposta

13

In primo luogo, OpenGL utilizza più sistemi di coordinate, pertanto non esiste "il sistema di coordinate OpenGL". Ciò a cui ti riferisci sono le coordinate normalizzate del dispositivo (NDC), in cui tutte e tre le coordinate sono comprese nell'intervallo [-1, 1]. I diversi sistemi di coordinate e i loro nomi sono spiegati here, nella sezione "9.011 Come vengono trasformate le coordinate? Quali sono i diversi spazi di coordinate?". 1)

In secondo luogo, per evitare confusione, in OpenGL il termine "finestra di visualizzazione" si riferisce alla parte della finestra in cui viene eseguito il rendering e si trova nelle coordinate della finestra. Nella tua domanda lo hai usato per descrivere la porzione (l, r, t, b) = (- 500, -500, 1200, 1200) del tuo mondo che vuoi rendere, che è nelle coordinate del mondo.

Hai chiesto come "calcolare dove disegnare oggetti sullo schermo". Quello che devi fare è definire una trasformazione (una matrice 4x4) che mappa da un sistema di coordinate all'altro. Il tuo mondo 2D è dato in coordinate del mondo, quindi devi definire una matrice che trasforma le coordinate del mondo in NDC, cioè una matrice di proiezione. Nei tuoi shader, quindi, puoi semplicemente moltiplicare i tuoi vertici con questa matrice di proiezione e ottieni NDC. glm::ortho/glOrtho calcola tale matrice di proiezione. Per quanto riguarda la proiezione prospettica, non è chiaro cosa si vuole fare, ma si dovrebbe sperimentare con le funzioni perspective e lookat in glm.

Per essere chiari, si definiscono i vertici in qualsiasi sistema di coordinate desiderato (che è chiamato il sistema di coordinate del mondo) e si disegnano semplicemente questi vertici. Il lavoro del tuo vertex shader consiste nell'applicare la trasformazione che hai definito.

Nota anche che hai specificato un quadrato e in genere non è quello che desideri. I monitor e la maggior parte delle finestre non sono quadrati, quindi se mappi quel quadrato su un tipico viewport, otterresti una visione distorta del tuo mondo. È necessario calcolare il rapporto aspetto (larghezza: altezza) della finestra. Ho provato a spiegare che here.


1) Come nota a margine, le FAQ sono piuttosto vecchie e si riferiscono alle versioni precedenti di OpenGL. Oggigiorno, i programmatori sono previsti e incoraggiati a gestire sia la vista del modello che le matrici di proiezione stesse, dal momento che ne avete bisogno nei vostri shader. Consiglio vivamente lo glm, è solo un'intestazione, quindi è molto facile da integrare, e ha una bella sintassi che rispecchia il GLSL.

+0

Se si utilizza una matrice di proiezione ortografica, la vista può e sarà sempre e solo 2D in quanto ignora l'asse Z, corretto? Per la maggior parte delle cose che sto facendo va bene, ma voglio essere in grado di sperimentare usando l'asse Z per creare prospettive meno piatte su mondi 2D. Quindi, come si definisce la matrice di trasformazione per la prospettiva piuttosto che l'ortogonale? Quali funzioni GL lo fanno? – bgroenks

+0

1) No, non ignora l'asse Z, proietta semplicemente tutto con la stessa coordinata xy sullo stesso pixel. Ma puoi ancora fare test di profondità. 2) 'glm :: perspective'. –

+0

Come usi glm :: perspective? Come interagisce con 'gl_ModelViewProjectionMatrix'? – bgroenks

1

Utilizzare glOrtho sulla matrice di proiezione e quindi disegnare normalmente. Per il tuo esempio, suppongo che tu voglia glOrtho (0, 1000, 0, 3000, -1, 1) che ti dia una vista 1000 unità di larghezza e 3000 unità di altezza

0

Posiziona la scena in qualunque sistema di coordinate tu volere. Raccomando di usare glm (http://glm.g-truc.net/) per inizializzare matrici ed eseguire operazioni matematiche, ecc. Quindi probabilmente hai un motore grafico di scene, in cui gestisci tutti gli oggetti nel tuo mondo 2D/3D. Basta impostare la vista e la proiezione corrette in glm. In realtà, non è necessario alcun dettaglio di implementazione della pipeline grafica, quindi potrebbe esserci una pessima decisione di progettazione nel motore di gioco.

Problemi correlati