2013-04-12 12 views
5

Quindi, un requisito fondamentale per la programmazione OpenGL è che si archiviano i vertici in modo tale da garantire memoria contigua. Ho letto un paio di libri decenti ultimamente da programmatori grafici professionisti, ed entrambi hanno usato una variazione della stessa idea: i vertici della confezione in un struct di 3 floats, x, y, z, e quindi il confezionamento di più vertici in una c -stile array o std::vector di questi structs. E funziona.Memoria contigua, OpenGL e come state avvolgendo i vostri vertici?

Ma ho visto più e più volte in questo sito che un struct non garantisce la contiguità di memoria. È stato detto che se la tua struct contiene tutti floats allora sarà probabilmente essere contigui, ma non è garantito . Il array e std::vector lo garantiscono, ma ciò è irrilevante se ciò che si sta mettendo nell'array o nel vettore non è contiguo.

Per il codice di produzione, mi aspetto che "probabilmente" non lo tagli. Quindi, nonostante il suggerimento in questi due libri, che sono chiaramente più orientati all'apprendimento, mi piacerebbe sapere quali sono alcune altre buone tecniche per organizzare facilmente i dati dei vertici in modo che garantisca memoria contigua o, accetterei il consiglio che non dovrei preoccuparmi di questo, che probabilmente dovrebbe essere abbastanza buono.

Quali sono altri metodi comuni e validi utilizzati nel campo della grafica?

+0

In aggiunta alle altre precauzioni che potresti prendere, inserisci questo nel tuo codice: 'static_assert (sizeof (vertex) == sizeof (float) * 3," vertice non allineato correttamente ");' - Se, su qualsiasi modifica alla tua catena di strumenti, le tue supposizioni falliscono sempre, sarai informato sulla compilazione. –

+0

Potrebbe non essere garantito dallo standard C++, ma potrebbe essere specificato dallo "standard" ABI su una piattaforma particolare. Il che significa che una volta stabilito che funziona su una piattaforma non cambierà in modo imprevedibile o romperà tutte le librerie compilate. Fondamentalmente lo standard C++ non è l'unico standard applicabile, ogni piattaforma ha uno standard per queste cose. Anche se non è uno standard pubblicato e pubblicato, non sarà ancora facilmente infranto. Certo, devi essere sicuro che quando fai il porting su una piattaforma le tue supposizioni sono corrette, ma dopo non riesco a vederlo infrangere. – jcoder

risposta

5

Quindi, un requisito fondamentale per la programmazione OpenGL è che si archiviano i vertici in modo tale da garantire memoria contigua.

No, non proprio. La memoria contigua risparmia spazio, ma finché la distanza (in byte) tra gli attributi è la stessa tra tutti gli elementi, questa cosa funzionerà.

Quali sono altri metodi comuni e validi utilizzati nel campo grafico?

semplici, semplici, array piatti di tipi di dati primitivi, come std::vector<float>, o std::vector<char> se si vogliono solo un pezzo di memoria in cui stendete i dati manualmente contigously. È possibile eseguire il wrapping di questo in una classe con i metodi getter and setter e le interfacce iteratore che astraggono i calcoli di offset e falcata.

È anche possibile utilizzare una struttura se è possibile utilizzare le estensioni del compilatore per specificare il layout della memoria. Ad esempio GCC's __attribute__((packed)) creerà una struttura stretta degli elementi senza spazi vuoti tra.

+0

Interessante, grazie. Ti capiterà di conoscere qualche buon esempio o codice di esempio che potrebbe includere una classe wrapper come quella che hai menzionato? – johnbakers

2

OpenGL Mathematics Library, glm, ha la garanzia che i suoi vettori sono contigui e semplici nella memoria, che io personalmente uso per memorizzare i vertici in:

std::vector<glm::vec3> positions; 
std::vector<glm::vec2> texCoords; 

Essa ha anche un programma di utilità di lanciare in modo sicuro gli indirizzi delle sue strutture in OpenGL glXXXv funzioni.

Se si desidera avere tutto in un VBO, si dovrebbe creare una sorta di struttura composta, perché temo che sia std::tuple<glm::vec3, glm::vec2>is not up for the challenge, che è un po 'triste.


A quanto pare, the glm behaviour is not backed by the standard, che potrebbe essere cambiato con C++ 11 e alignas() però. Tuttavia, non si può fare di meglio in termini di allineamento delle strutture, immagino, e lo static_assert suggerito dovrebbe impedirti di spararti ai piedi.