Quello che hai descritto è del tutto adeguato e appropriato per garantire l'indipendenza dalla risoluzione. Tutto ciò che disegni occuperà sempre la stessa proporzione della tua finestra.
Tuttavia, se non fai altro che questo, avrai problemi di proporzioni . Ad esempio, dati i numeri che hai scritto, se disegni un cerchio, verrà schiacciato - più largo di quanto sia alto, perché la tua scala orizzontale è 800 / (50 + 50) = 8 e la tua scala verticale è 600 / (50+ 50) = 6.
Non ci può essere alcuna soluzione automatica a questo problema ; dovrai scegliere quale risultato grafico vuoi e considerare il suo effetto sul gameplay. Alcuni esempi comuni:
In un gioco 3D a proiezione prospettica senza HUD, la solita soluzione semplice (disponibile in OpenGL come parte di gluPerspective
) è quella di fissare il campo visivo della proiezione rispetto alla dimensione verticale . Ciò significa che in un gioco del genere, se ridimensionate la finestra in orizzontale, vedrete più o meno la scena e la parte centrale dell'immagine non cambierà affatto.
La stessa idea può essere applicata anche a una vista 2D / 2.5D.
(Si noti che ciò consente al giocatore di allargare il proprio campo visivo in senso orizzontale creando una finestra ampia ma non alta. Ciò potrebbe essere indesiderato in una partita multiplayer competitiva.)
Se hai una grafica che riempie la finestra con proporzioni fisse (ad esempio, una mappa 2D non scorrevole o un bordo decorativo) o se non riesci altrimenti a modificare il layout, devi fare qualcosa come avere barre nere su due lati per riempire lo spazio inutilizzato.
Oppure puoi creare grafici con materiale di riempimento tematicamente coerente attorno ai bordi che possono essere ritagliati per adattarsi al display senza danneggiare il gameplay.
Se hai un HUD in cima ad altri elementi grafici, puoi decidere che ogni elemento HUD è fissato a una parte della finestra (in alto a sinistra, in basso al centro, ecc.) E calcolarne le coordinate; lo "stiramento" del variare delle proporzioni viene assorbito dallo "spazio bianco" tra gli elementi HUD.
Per quanto riguarda la matematica specifica della questione, dato che stai facendo l'indipendenza dalla risoluzione, tutto ciò di cui hai bisogno è iniziare con le proporzioni, un singolo numero: width / height
. Ad esempio, se la finestra è quadrata sarà 1; se è 800 per 600 sarà 800/600 = 4/3 = 1.333̅.
Ad esempio, supponiamo che tu voglia la proiezione ortografica che hai scritto per guadagnare spazio aggiuntivo sui lati sinistro e destro se la finestra è allargata. Puoi farlo in questo modo:
float aspect = width / height;
glViewport(0, 0, width, height);
glOrtho(-50.0 * aspect, 50.0 * aspect, -50.0, 50.0, 1.0, -1.0);
Ciò garantisce che, per le finestre larghe almeno quanto alte, sarà visibile qualsiasi cosa tu disegni con coordinate xey entro -50 a 50.
D'altra parte, se la finestra è più stretta di quanto sia alta, l'intervallo da -50 a 50 verrà tagliato. Supponiamo che tu voglia assicurarti che sia sempre visibile (in modo che il tuo contenuto abbia le dimensioni massime se la finestra è quadrata, ma altrimenti più piccola); in tal caso, fai semplicemente la stessa cosa all'altezza anziché alla larghezza.
float aspect = width / height;
glViewport(0, 0, width, height);
if (aspect >= 1.0)
glOrtho(-50.0 * aspect, 50.0 * aspect, -50.0, 50.0, 1.0, -1.0);
else
glOrtho(-50.0, 50.0, -50.0 / aspect, 50.0 / aspect, 1.0, -1.0);
Si noti che nel secondo caso dividiamo piuttosto che moltiplicare. Questo semplicemente perché abbiamo calcolato le proporzioni width / height
piuttosto che height / width
; prendi il reciproco se trovi più facile capire in quel modo.
Ancora una volta, questo non è l'unico modo per gestire le proporzioni; questo è molto semplice per assicurarsi che i tuoi contenuti non siano né schiacciati né tagliati. Scopri cosa vuoi che accada quando la tua finestra è larga, alta o altro; quindi elaborarne la matematica.