Sviluppo il mio gioco la maggior parte del tempo sotto ArchLinux. Di recente ho deciso di provarlo su Ubuntu 16.04. La situazione in cui mi sono imbattuto era davvero strana:
- No
glGetError()
per niente. - Nessun errore, avvertimento, niente di male nelloutput di debug gl.
- Tutte le asserzioni che ho fatto per tutte le situazioni negative non si sono attivate.
-
glClear
ho cancellato con successo i buffer I specificato, ma: -
glDraw*
non ha disegnato nulla.
Per fortuna ho trovato una soluzione che doveva impostare glViewport
. Tuttavia, non capisco bene, perché è necessario disegnare in Ubuntu ma non è necessario in ArchLinux? La differenza è anche tra gli adattatori grafici: su archlinux utilizzo NVIDIA 1060, su Ubuntu utilizzo HD Graphics P530 integrata (Skylake GT 2 ).
Se è importante, utilizzo SDL2 con opengl 4.4.
Commenti
- It ' è importante che tu ti renda conto che il sistema operativo non è rilevante qui; OpenGL è implementato dal tuo fornitore di GPU nei suoi driver, quindi i fattori importanti sono le tue GPU ei loro driver. Dove il sistema operativo potrebbe essere interessante è se il tuo fornitore di GPU ha basi di codice differenti per SO differenti, ma altrimenti ' non sono informazioni utili.
- @MaximusMinimus questa potrebbe essere la risposta alla domanda.
Risposta
Hai già due buone risposte, ma potrebbero essere difficili da capire per un principiante, quindi io “Ti dirò perché abbiamo davvero bisogno di .
Nel rendering tipico potrebbe sembrare non avere senso: si crea semplicemente una finestra o si esegue il rendering di destinazione e si disegna su di essa, giusto? Direi che oltre il 95% delle app funziona in questo modo.
Ma supponiamo che tu stia scrivendo unapp come 3DS MAX, dove hai la finestra divisa in 4 rendering distinti. Ricordi il tuo posizione di divisione corrente e gestisci gli eventi del mouse, quindi quando passi con il mouse sulla barra di divisione puoi cambiare il cursore del mouse per ridimensionarne uno, ecc. Quando trascini la barra di divisione, ricordi la sua nuova posizione e così via.
Quando si desidera eseguire il rendering delle viste 3D, si chiama glViewport con la posizione e le dimensioni della prima sottofinestra 3D ed eseguire i tipici comandi GL per disegnare qui. OpenGL ridimensionerà automaticamente il rendering in modo che si adatti alla vista data. Fai lo stesso per il resto delle tue viste e alla fine ottieni una finestra con pochi rendering diversi, ciascuno con i propri parametri. In questo modo puoi avere tutti i rendering distinti su una singola finestra / destinazione di rendering che desideri.
Perché non ha funzionato su una macchina?
Le GPU e i relativi driver hanno molti dettagli di implementazione e differenze, quindi in generale è necessario abituarsi a tali problemi. Un semplice esempio: nello shader GLSL puoi creare un vettore zero 2D come questo: vec2(0.0,0.0)
, puoi anche provare a scrivere un valore: vec2(0.0)
e con questo codice alcuni driver la tratteranno come una versione precedente mentre altri restituiranno errori e non renderanno nulla. Tieni presente che i driver di due fornitori differiranno più di due versioni dello stesso driver, quindi “è una buona idea testare il tuo codice su GPU nVidia, ATI e Intel. In questo caso sospetto che nei driver nVidia, quando non impostare la visualizzazione da solo, presumono che tu voglia utilizzare lintero target di rendering, mentre i driver Intel non lo fanno.
Answer
glViewport consente a opengl di sapere come mappare le coordinate NDC alle coordinate del framebuffer.
Per impostazione predefinita è impostato alla dimensione intera del buffer dello schermo. Quindi devi chiamarlo solo quando la finestra viene ridimensionato o si desidera effettivamente cambiarlo.
Commenti
- O quando si esegue il rendering su un framebuffer, assumendo che la dimensione della finestra sia diversa.
Answer
glViewport specifica la trasformazione affine di xx e yy dalle coordinate normalizzate del dispositivo alle coordinate della finestra. Let (xnd , ynd) xndynd be normalized device coord inates. Quindi le coordinate della finestra (xw, yw) xwyw vengono calcolate come segue:
- “xw = (xnd + 1) (width2) + xxw = xnd + 1width2 + x”
- “yw = (ynd + 1) (height2) + yyw = ynd + 1height2 + y”
La larghezza e laltezza della vista sono bloccate silenziosamente a un intervallo che dipende da limplemento. Per interrogare questo intervallo, chiama glGet con largomento “GL_MAX_VIEWPORT_DIMS”
I parametri xey specificano langolo inferiore sinistro della visualizzazione in pixel, mentre larghezza e altezza specificano la larghezza e laltezza della visualizzazione