OpenGL ha quattro diverse versioni principali, senza contare le versioni per dispositivi mobili e sistemi integrati (OpenGL | ES) e il Web tramite JavaScript (WebGL). Proprio come Direct3D 11 ha un modo diverso di fare le cose rispetto a Direct3D 8, così OpenGL 3 ha un modo diverso di fare le cose rispetto a OpenGL 1. La grande differenza è che le versioni OpenGL sono principalmente solo componenti aggiuntivi rispetto alle versioni precedenti (ma non interamente).
Oltre alle diverse edizioni e versioni di OpenGL, anche OpenGL principale ha aggiunto il concetto di profili. Vale a dire il profilo di compatibilità (che abilita il supporto per le API dalle versioni precedenti) e il profilo principale (che disabilita quelle vecchie API). Cose come glBegin
semplicemente non funzionano quando si utilizza il profilo principale, ma lo faranno quando si utilizza il profilo di compatibilità (che è l'impostazione predefinita).
Come ulteriore importante complicazione, alcune implementazioni di OpenGL (come quelle di Apple, tra le altre) abiliteranno le nuove funzionalità di OpenGL solo quando si utilizza il profilo principale. Ciò significa che è necessario smettere di utilizzare API più vecchie per utilizzare API più recenti.
Quindi si finiscono con diversi scenari molto confusi per le esercitazioni:
- Il tutorial è vecchio e utilizza solo API obsolete.
- Il tutorial è nuovo e ben scritto e utilizza solo API compatibili con Core.
- Il tutorial è nuovo ma fa l'errore di presumere che stai lavorando con un driver che abilita tutte le API in modalità Compatibilità e mescola liberamente sia le API nuove che quelle vecchie.
- Il tutorial è per una diversa edizione di OpenGL come OpenGL | ES che non supporta affatto le vecchie API, in qualsiasi versione.
Cose come glBegin
fanno parte di quella che a volte viene chiamata API in modalità immediata. Questo è anche molto confuso perché non esiste una modalità mantenuta in OpenGL e "modalità immediata" aveva già una diversa definizione nella grafica. È molto meglio fare riferimento a quelle come API OpenGL 1.x poiché sono obsolete da OpenGL 2.1.
L'API 1.x di OpenGL invierebbe immediatamente i vertici alla pipeline grafica ai vecchi tempi. Funzionava bene quando la velocità dell'hardware che rendeva i vertici era approssimativamente alla pari della velocità della CPU che generava i dati del vertice. OpenGL ha quindi scaricato la rasterizzazione del triangolo e non molto altro.
In questi giorni, la GPU può masticare un numero enorme di vertici a velocità molto elevate mentre esegue la trasformazione avanzata di vertici e pixel e la CPU semplicemente non può nemmeno tenere il passo da remoto. Inoltre, l'interfaccia tra la CPU e la GPU è stata progettata attorno a questa differenza di velocità, il che significa che non è nemmeno più possibile inviare vertici alla GPU uno alla volta.
Tutti i driver GL devono emulare glBegin
allocando internamente un buffer di vertici, inserendo i vertici inviati glVertex
in questo buffer e quindi inviando l'intero buffer in una singola chiamata di disegno quando glEnd
viene chiamato. Il sovraccarico di queste funzioni è di gran lunga maggiore che se si aggiorna da solo il buffer dei vertici, motivo per cui alcuni documenti (erroneamente!) Faranno riferimento ai buffer dei vertici come "un'ottimizzazione" (non è un'ottimizzazione; è l'unico modo per parlare con la GPU).
Esistono varie altre API che sono state deprecate o obsolete in OpenGL nel corso degli anni. La cosiddetta pipeline a funzione fissa è un altro pezzo del genere. Alcuni documenti potrebbero comunque utilizzare questa pipeline o mescolarsi con la pipeline programmabile. La pipeline a funzione fissa viene dai tempi antichi in cui le schede grafiche codificavano per intero tutta la matematica utilizzata per il rendering delle scene 3D e l'API OpenGL si limitava a impostare alcuni valori di configurazione per quella matematica. In questi giorni l'hardware ha pochissima matematica hardcoded e (proprio come la tua CPU) esegue invece programmi forniti dall'utente (spesso chiamati shader).
Ancora una volta i driver devono emulare la vecchia API poiché le funzionalità a funzione fissa semplicemente non sono più presenti sull'hardware. Ciò significa che il driver ha un gruppo di shader di compatibilità integrati che eseguono la vecchia matematica dai giorni a funzione fissa che viene utilizzata quando non si forniscono i propri shader. Le vecchie funzioni OpenGL che modificano il vecchio stato di funzioni fisse (come la vecchia API di illuminazione OpenGL) in realtà utilizzano le moderne funzionalità OpenGL come buffer uniformi per alimentare questi valori agli shader di compatibilità del driver.
I driver che supportano la compatibilità devono fare un sacco di lavoro dietro le quinte solo per capire quando stai usando queste funzionalità obsolete e assicurarti di poterle combinare con funzionalità moderne senza intoppi, il che aggiunge sovraccarico e complica notevolmente il driver. Questo è uno dei motivi per cui alcuni driver ti costringono ad abilitare il profilo principale per accedere alle funzionalità più recenti; semplifica notevolmente i loro driver interni, non dovendo supportare entrambe le API vecchie e nuove utilizzate contemporaneamente.
Molta documentazione può consigliare di iniziare con le vecchie API semplicemente perché è più facile iniziare. Direct3D ha risolto questo problema per i principianti offrendo una libreria di accompagnamento ( DirectX Tool Kit ) che fornisce API di disegno più semplici e shader pre-scritti che possono essere liberamente miscelati con l'utilizzo diretto di Direct3D 11 man mano che la tua esperienza cresce. La più ampia comunità OpenGL è rimasta per lo più attaccata al profilo di compatibilità per i principianti, sfortunatamente, il che è problematico in quanto vi sono ancora sistemi che non consentono di mescolare vecchie API OpenGL con quelle più recenti. Esistono librerie e strumenti non ufficiali per il rendering più semplice sul nuovo OpenGL con diversi livelli di funzionalità e casi d'uso e linguaggi di destinazione ( MonoGame per gli utenti .NET, ad esempio), ma nulla è stato approvato o concordato ufficialmente.
La documentazione che stai trovando potrebbe non essere nemmeno per OpenGL ma potrebbe essere per una delle altre API simili. OpenGL | ES 1.x aveva un rendering a funzione fissa ma non aveva le API OpenGL 1.x per l'invio dei vertici. OpenGL | ES 2.x + e WebGL 1+ non hanno alcuna funzione fissa e non esistono modalità di compatibilità con le versioni precedenti per tali API.
Queste API sembrano molto simili al principale OpenGL; non sono del tutto compatibili, ma ci sono estensioni ufficiali di OpenGL che alcuni driver (non tutti) supportano per diventare compatibili con OpenGL | ES (su cui si basa WebGL). Perché le cose non erano abbastanza confuse prima.