OpenGL è appena progettato male?

1

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.

    
posta nukeop 12.11.2016 - 01:02
fonte

1 risposta

4

It's extremely popular, dominates on mobile devices, is in active development, and supported on all kinds of GPUs. Why?

Bene ... qual è la tua alternativa?

Ignorando Vulkan, se vuoi scrivere un'applicazione cross-platform per dispositivi mobili e vuoi usare l'hardware 3D, che cosa intendi usare tranne OpenGL ES?

Nessuno ha mai sostenuto (almeno di recente) che OpenGL sia un'API ragionevole e ben progettata. Ma funziona ; fa il lavoro, e non c'è un'alternativa multipiattaforma disponibile in generale.

E ora per un controllo dei fatti:

There is only one "slot" for errors so effectively if you don't check after every function, you will never get to the bottom of it properly, since errors will get lost if there is more than one before checking.

Questo è falso. Gli errori in OpenGL sono in coda . Ogni chiamata a glGetError restituisce l'errore aggiunto meno di recente alla coda . Gli errori OpenGL non vengono persi in OpenGL.

Il problema di non controllare gli errori di frequente è che, se non lo fai, sarà difficile sapere quale funzione è responsabile per quale errore.

such as border=0 in glTexImage2D

Questo esiste perché le trame pre-GL 3.1 potrebbero avere texels di bordo. Ma dal momento che nessun hardware di livello consumer supportava i bordi del bordo, lo rimuovevano dal core OpenGL in 3.1. Ma non puoi semplicemente rimuovere un parametro da una funzione; che avrebbe infranto le ABI dappertutto. Quindi hanno intrapreso il percorso di minor resistenza: mantenere il parametro, ma richiesto che sia zero.

ES lo ha mantenuto per preservare la compatibilità dell'API con il desktop OpenGL.

In generale, praticamente tutte le seccature dell'API OpenGL arrivano fino a un certo livello di "compatibilità con le versioni precedenti".

Absolutely no checking for any kinds of errors at compile time

OpenGL è un'API C. Non c'è molto spazio in C per la verifica della compilazione di materiale.

    
risposta data 12.11.2016 - 01:38
fonte

Leggi altre domande sui tag