2015-01-07 5 views
11

glBufferStorage crea un nuovo archivio dati immutabile per l'oggetto buffer attualmente associato alla destinazione. La dimensione dell'archivio dati è specificata per dimensione. Se sono disponibili dati iniziali, il suo indirizzo può essere fornito nei dati. In caso contrario, per creare un archivio di dati non inizializzati, i dati dovrebbero essere NULL.Qual è la differenza tra glBufferStorage e glBufferData?

Immutabile significa che non posso modificarlo correttamente? Ma poi i "dati non inizializzati" sarebbero inutili.

Ma in realtà non è immutabile, perché siamo in grado di specificare GL_DYNAMIC_STORAGE_BIT​

Allora, qual è la differenza tra glBufferStorage e glBufferData?

risposta

15

Solo per quello che sai, questo è lo stesso principio glTexStorage* (...). Effettivamente, tu firmi un contratto con l'API che dice che non ti sarà mai permesso di cambiare certe proprietà del tuo oggetto e in cambio ciò conferirà all'oggetto uno status immutabile e ti permetterà di fare cose che normalmente non potresti con esso.

Texture Vista sono un esempio interessante, dove i dati di immagine interni di tessitura immutabile possono essere condivise tra più oggetti texture e anche avere i formato/dimensioni reinterpretato (es 1 fetta di una trama di matrice 2D può essere condiviso e usato come se fosse una normale texture 2D).

Per buffer di vertici, stoccaggio immutabile apre una classe di ottimizzazione delle prestazioni (esempio persistente memoria mappata) che non sarebbe possibile se si potrebbe modificare la dimensione del buffer in qualsiasi momento. Si crea un buffer le cui dimensioni non possono mai essere modificate, ma si è comunque liberi di inviarle nuovi dati in qualsiasi momento usando i comandi glBufferSubData* (...) o scrivendo nel buffer mentre è mappato in memoria.

Con glBufferData (...), è possibile chiamare tale comando più volte sullo stesso oggetto e sarà orfana la vecchia memoria e allocare nuova memoria. Con glBufferStorage (...), la dimensione del buffer è impostata per la durata dell'oggetto (immutabile) ed è un errore (GL_INVALID_OPERATION) per chiamare di nuovo glBufferStorage (...) una volta che è stato assegnato immutabilmente.

In breve, è l'archivio dati (caratteristiche di archiviazione) immutabile, non i dati effettivi.

8

Credo che questo parole [https://www.opengl.org/registry/specs/ARB/buffer_storage.txt] mostrano il tasto:

OpenGL sostiene da tempo oggetti buffer come mezzo di memorizzazione dati che può essere utilizzato per sorgente attributi vertice, dati di pixel per le texture, uniformi e altri elementi. Nel GL non esteso, i dati del buffer sono modificabili, ovvero possono essere disallocati o ridimensionati mentre sono in uso . L'estensione GL_ARB_texture_storage ha aggiunto l'archiviazione immutabile per l'oggetto texture (ed è stata successivamente incorporata in OpenGL 4.2). Questa estensione applica ulteriormente il concetto di archiviazione immutabile agli oggetti buffer . Se un'implementazione è a conoscenza dell'immutabilità di un buffer, , potrebbe essere in grado di formulare determinate ipotesi o applicare particolari ottimizzazioni al fine di aumentare le prestazioni o l'affidabilità.

Questi hanno menzionato il buffer mutabile forse de-allocato o ridimensionato e che viene da glBufferData che porta buffer mutabile. Ma glBufferStorage ti mostrerà la possibilità di creare un buffer immutabile.

La chiave qui è "immutabile" significa che non è possibile ridimensionarla o deselezionarla in futuro, ma non significa che non è possibile scrivere/leggere dati in essa.

[Edit] penso che sia anche un bene per aggiungere un po 'di esempio, che possono rendere le parole di spec molto più facile da capire, :)

  • glBufferData qualche volta si possono incontrare le parole 'del buffer orfani' , normalmente vedrai le chiamate simili come (c'è ancora un altro modo di fare buffer orfano come GL_MAP_INVALIDATE_BUFFER_BIT, ecc.):
    glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STREAM_DRAW); GLubyte* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_WRITE_BIT); Foo(ptr, size); glUnmapBuffer(GL_ARRAY_BUFFER);
  • glBufferStorage non consentono di de-allocare lo [notare il parametro 0 in glBufferData, ma mantenere la memoria per la Persistent-mapped Buffer, normalmente si vedrà l'utilizzo è simile al seguente:
    glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferStorage(GL_ARRAY_BUFFER, size, data, GL_MAP_PRESISTENT_BIT|GL_MAP_COHERENT_BIT); GLubyte* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_PRESISTENT_BIT|GL_MAP_COHERENT_BIT); Foo(ptr, size);
    nota, il PTR appena continua indirizzo dello stesso tampone, questo significa che il buffer è persistented nella memoria, e non è necessario per eliminare la mappatura fino a quando davvero non hanno bisogno

Grazie

+0

È possibile utilizzare NULL per i dati con glBufferStorage. Non puoi ridimensionarlo, quindi devi impostare una dimensione fissa. Puoi usare, come hai sottolineato, il puntatore al buffer mappato per scrivere su di esso, ma i dati non devono essere impostati alla chiamata glBufferStorage. – anthom