Uso OpenGL e OpenGL ES da molto tempo e li conosco abbastanza bene. Sono anche molto, davvero fastidiosi da usare, e non ho mai visto questo discusso da nessuna parte. Ecco alcuni esempi di cattiva progettazione che ho notato:
- Stati globali ovunque. Ci sono stati per ogni caratteristica, spesso implicita, a volte nascosta. Senza leggere la documentazione in dettaglio è difficile capire quali valori sono legali per quali stati e cosa li influenza. Dal momento che sono globali, è un incubo eseguire il debug, anche con un programma a thread singolo.
- La gestione degli errori è probabilmente il peggiore che abbia mai visto in qualsiasi framework. Considero il fatto che gli errori devono essere controllati manualmente da una limitazione hardware, quindi lascerò che diapositiva. Ma ci sono solo un paio di flag di errore. Quelle bandiere sono spesso usate più volte nel contesto di una singola funzione per significare cose diverse, lasciandovi senza opzioni, ma per indovinare perché si verifica. C'è un solo "spazio" per errori così efficacemente che se non si controlla dopo ogni funzione, non si arriva mai al fondo correttamente, poiché gli errori andranno persi se ce ne sono più di uno prima di controllare.
- Le firme delle funzioni sono spesso controintuitive e fuorvianti. Gli argomenti che prendono qualsiasi numero, ma in realtà solo un paio di valori sono legali. Argomenti di enumerazione che hanno un solo valore legale possibile (come border = 0 in glTexImage2D) lasciandoti dubbi sul motivo della loro presenza (compatibilità con le versioni future dell'API? No, non vengono mai modificati per accettare altri valori). Enumerazione ridondante accettata da funzioni che possono comunque gestire solo un tipo di valore, ad esempio GL_TEXTURE_3D per funzioni che operano solo su trame 3D.
- Estensioni richieste per fare quasi tutto. Interrogare la GPU per le estensioni supportate è un grosso problema.
- Nomi di funzioni fuorvianti simili per funzioni che in realtà fanno cose molto diverse, come glGenTextures / glCreateTextures
- Regole oscure e arcane per la completezza del framebuffer (ad esempio quando si desidera eseguire il rendering su una trama). Senza leggere la documentazione in dettaglio ti imbatterai regolarmente in situazioni in cui non sei in grado di capire perché il tuo framebuffer è considerato incompleto. Ciò è ulteriormente aggravato dal fatto che la gestione degli errori è abissale e che i codici di errore sono condivisi da errori diversi. Prova a leggere le regole di completezza degli allegati per avere un'idea di come cattivo sia. Non ci sono inoltre feedback su quale allegato del framebuffer sia cattivo.
- La pipeline di funzioni fisse può essere combinata con la nuova pipeline con shader, portando a un pasticcio enorme
- Assolutamente nessun controllo per qualsiasi tipo di errore in fase di compilazione, anche se apprezzo che la maggior parte di questo sarebbe comunque dipendente dall'hardware
- Un sacco di funzioni ridondanti (basta vedere quante varianti di glUniform o glGet ci sono)
Con tutti questi e molti altri difetti, OpenGL sembra andare bene. È estremamente popolare, domina su dispositivi mobili, è in sviluppo attivo e supportato su tutti i tipi di GPU. Perché? Perché tutto questo è tollerato e, soprattutto, perché è stato progettato in questo modo? So che le GPU sono dispositivi molto particolari e la comunicazione tra CPU, GPU, memoria, ecc. Richiede alcuni vincoli, ma la maggior parte sembra essere dovuta a una progettazione errata che potrebbe essere evitata.