OpenGL: VBO o glBegin () + glEnd ()?


16

Recentemente mi è stato dato questo link a un sito tutorial da qualcuno a cui ho dato il Redbook OGL originale. La terza intestazione in basso dice chiaramente di dimenticare glBegin () & glEnd () come il tipico metodo di rendering. Ho imparato tramite il metodo del Redbook, ma vedo alcuni vantaggi nei VBO. È davvero questa la strada da percorrere e, in tal caso, esiste un modo per convertire facilmente il codice di rendering e i successivi shader in VBO e tipi di dati successivi?

Risposte:


27

Con i moderni VBO di OpenGL sono la strada da percorrere, roba con funzioni fisse (tra cui glBegin / glEnd e le cose in mezzo) è stata deprecata dal 3.0 e rimossa dal 3.1.

Con il profilo principale OpenGL, OpenGL ES 2.0+ e WebGL non hai nemmeno accesso alle cose vecchie.

Alcune persone pensano che imparare prima le cose vecchie sia meglio perché è un po 'più facile, ma quelle cose che impari sono per lo più inutili e quindi cose che devi disimparare.

Tuttavia, non sono solo i VBO, è necessario utilizzare shader per tutto e fare trasformazioni di matrici (o utilizzare GLM).

L'unico motivo per usare le vecchie cose sarebbe se volessi scegliere come target OpenGL prima della 2.0. che è stato rilasciato nel 2003. Ci sono alcuni chipset per netbook embedded davvero scadenti che sono 1.5 ma anche 1.5 dovrebbero supportare i VBO non solo shader. Oppure OpenGL ES 1.x che si basa sulla pipeline a funzioni fisse (ad esempio, viene utilizzato su iPhone meno recenti). O OpenGL SC (per sistemi critici per la sicurezza).

Le seguenti funzioni di uso comune sono tutte obsolete:

  • glBegin
  • glEnd
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

I tutorial di opengl-tutorial.org hanno quello che penso sia il modo migliore per imparare OpenGL. Si basano su alcune delle cose di compatibilità legacy ma in realtà non te lo insegnano. Ad esempio, non dovresti renderizzare nulla senza uno shader, ma funziona. E devi gestire da solo le operazioni con le matrici (ruota, traduci, ecc.) Ma per impostazione predefinita otterrai una vista 2D piatta di base.

Oltre a evitare le cose deprecate, ci sono un sacco di funzioni che rendono la codifica di OpenGL molto più piacevole, ma con molte di esse devi decidere se sei d'accordo con la necessità di nuove versioni 3.x + di OpenGL e hardware compatibile.

Ci sono più informazioni in un post che ho scritto qui .

Se è necessario supportare OpenGL meno recente per qualche motivo, è possibile utilizzare i VBO quando possibile e, in caso contrario, fornire un fallback che utilizza glBegin / glEnd e scorrere i dati del vertice.

D'altra parte, non esiste un vero modo "facile" per convertire il vecchio codice di rendering. Potresti forse implementare la tua versione delle funzioni che aggiungono i vertici a un array / vettore che poi lo scarica in un VBO e lo disegna quando viene chiamato un falso glEnd. ma sarebbe molto inefficiente dal momento che lo farebbe ogni frame (a meno che non si verifichi un controllo per farlo solo una volta ma che non funziona per gli oggetti animati) e probabilmente sarebbe più lavoro che passare ai VBO. Suppongo che se avessi molto codice questo approccio potrebbe funzionare.


7

Con i VBO hai generalmente due vantaggi principali.

Il vantaggio 1 riguarda dati completamente statici e deriva dalla capacità di mantenere in memoria i dati dei vertici più ottimali per la GPU.

Il vantaggio 2 si riferisce ai dati dinamici e deriva dalla possibilità di specificare i dati del vertice in qualsiasi momento prima di utilizzarli per il rendering, il che può consentire una pipeline migliore.

Un terzo vantaggio deriva dal richiamo del batch di chiamate, ma è anche condiviso con array di vertici della vecchia scuola, quindi non lo chiamerò specificamente per i VBO. L'invio di dati a una GPU (o l'utilizzo di dati già presenti sulla GPU) è simile in molti modi all'I / O del disco e al traffico di rete: se si dispone di alcuni batch di grandi dimensioni, è più efficiente di molti piccoli batch.

Una buona analogia (non accurata al 100% ma sufficiente per aiutarti a capire l'idea) è se sei un autista di autobus che deve portare 50 persone da una città all'altra. Puoi caricarli uno alla volta ed effettuare 50 viaggi separati: questo è glBegin / glEnd. In alternativa, puoi metterli tutti e 50 sul bus e fare un solo viaggio - che è raggruppato con array di vertici o VBO (nel caso VBO le 50 persone sarebbero già sul bus;)).

Questo ha un prezzo però, e qui il prezzo è che perdi la possibilità di specificare solo i dati del vertice man mano che li richiedi. Bene, OK, puoi farlo (con qualche lavoro aggiuntivo), ma non otterrai le prestazioni complete dal tuo codice. Invece devi pensare di più ai tuoi dati di vertice, a come vengono utilizzati, come (e se) devono essere aggiornati, se eventuali animazioni possono essere fatte in uno shader (consentendo così ai dati di rimanere statici - I VBO hanno davvero bisogno di shader per un molti casi di animazione per funzionare bene) o se devi rispecificare i dati dei vertici per ogni frame, strategie di aggiornamento efficienti se quest'ultimo, ecc. Se non lo fai e implementi una conversione ingenua hai un rischio molto elevato di mettere in un sacco di lavoro solo per il risultato finale di correre più lentamente!

Questo può sembrare un sacco di lavoro quando lo incontri per la prima volta, ma non lo è, davvero. Una volta entrato nel modo di pensare in questo modo, scoprirai che è incredibilmente facile e quasi naturale. Ma potresti rovinare i tuoi primi tentativi e non dovresti scoraggiarti se è così: sbagliare è un'opportunità per imparare da ciò che hai fatto di sbagliato.

Alcuni pensieri finali.

Avere i dati del tuo modello in un formato che può essere facilmente caricato in un VBO può aiutarti a rendere l'intero processo molto più semplice per te. Ciò significa che dovresti evitare formati più complessi o esotici, almeno all'inizio (e fino a quando non ti sentirai più a tuo agio con il processo); mantieni le cose il più semplici e basilari possibile durante l'apprendimento e ci saranno meno cose da sbagliare e meno posti in cui cercare errori se (o quando!) le cose vanno male.

Le persone a volte vengono rimandate se vedono un'implementazione di VBO che utilizza più memoria di un'implementazione glBegin / glEnd ottimizzata / compressa (possono anche riferirsi ad essa come "spreco"). Non essere così. Tranne in casi estremi, l'utilizzo della memoria non è davvero questo importante. È un chiaro compromesso qui: stai accettando un utilizzo della memoria potenzialmente più elevato in cambio di prestazioni sostanzialmente più elevate. Aiuta anche a sviluppare la mentalità secondo cui la memoria è una risorsa economica e abbondante che è lì per essere utilizzata; le prestazioni non lo sono.

E infine la vecchia castagna - se è già abbastanza veloce, il tuo lavoro è finito. Se stai colpendo il tuo framerate target, se hai spazio per le condizioni transitorie, allora è abbastanza buono e puoi passare al passaggio successivo. Puoi perdere un sacco di tempo ed energia spremendo un ulteriore 10% da qualcosa che non ne ha davvero bisogno (ci sei stato, fatto, cadi ancora nella trappola) quindi considera sempre quale sia l'uso ottimale del tuo tempo - perché il tempo del programmatore è ancora meno economico e meno abbondante delle prestazioni!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.