Assicurare i tipi compatibili OpenGL in c ++

Gli oggetti buffer OpenGL supportano vari tipi di dati con larghezza ben definita ( GL_FLOAT è 32 bit, GL_HALF_FLOAT è 16 bit, GL_INT è 32 bit …)

Come si può fare per garantire i tipi cross-platform e futureproof per OpenGL? Ad esempio, l’alimentazione di dati float da un array c ++ a un object buffer e il suo tipo è GL_FLOAT non funzionerà su piattaforms in cui float non è a 32 bit.

Facendo alcune ricerche su questo, ho notato un cambiamento sottile ma interessante nel modo in cui questi tipi sono definiti nelle specifiche GL. Il cambiamento è avvenuto tra OpenGL 4.1 e 4.2.

Fino a OpenGL 4.1, la tabella che elenca i tipi di dati (Tabella 2.2 nei documenti delle specifiche recenti) ha l’intestazione Larghezza di bit minima per la colonna delle dimensioni, e la didascalia della tabella dice (enfasi aggiunta da me):

I tipi GL non sono tipi C. Quindi, ad esempio, GL type int è indicato come GLint al di fuori di questo documento e non è necessariamente equivalente al tipo C int. Un’implementazione può utilizzare più bit rispetto al numero indicato nella tabella per rappresentare un tipo GL. Tuttavia, non è richiesta un’interpretazione corretta dei valori interi al di fuori dell’intervallo minimo.

A partire dalla specifica OpenGL 4.2, l’intestazione della tabella cambia in Larghezza bit e la didascalia della tabella in:

I tipi GL non sono tipi C. Quindi, ad esempio, GL type int è indicato come GLint al di fuori di questo documento e non è necessariamente equivalente al tipo C int. Un’implementazione deve utilizzare esattamente il numero di bit indicato nella tabella per rappresentare un tipo GL.

Questo ha influenzato la risposta alla domanda. Se si utilizza la definizione più recente, è ansible utilizzare definizioni di tipi di dimensioni standard anziché i tipi GL nel codice e assumere in modo sicuro che corrispondano. Ad esempio, è ansible utilizzare int32_t da anziché GLint .

L’utilizzo dei tipi GL è ancora la soluzione più semplice. A seconda dell’architettura del codice e delle preferenze, potrebbe tuttavia essere indesiderabile. Se ti piace dividere il tuo software in componenti e vuoi che il rendering di OpenGL sia isolato in un singolo componente pur fornendo un certo livello di astrazione, probabilmente non vuoi usare i tipi GL in tutto il codice. Tuttavia, una volta che i dati raggiungono il codice di rendering, devono corrispondere ai tipi GL corrispondenti.

Come esempio tipico, diciamo che hai codice computazionale che produce dati che vuoi rendere. Potresti non voler avere tipi GLfloat su tutto il tuo codice computazionale, perché può essere usato indipendentemente da OpenGL. Tuttavia, una volta che sei pronto per visualizzare il risultato del calcolo e vuoi rilasciare i dati in un VBO per il rendering OpenGL, il tipo deve essere lo stesso di GLfloat .

Ci sono vari approcci che puoi usare. Uno è quello che ho menzionato sopra, usando i tipi di dimensioni dei file di intestazione standard di C ++ nel codice di non rendering. Allo stesso modo, puoi definire i tuoi typedef che corrispondono ai tipi usati da OpenGL. Oppure, meno desiderabile per motivi di prestazioni, è ansible convertire i dati laddove necessario, eventualmente basandosi sul confronto tra i valori sizeof() tra i tipi in arrivo e i tipi GL.