TextureBufferObjects
Shader Model 4.0 führt mit der Extension GL_ARB_texture_buffer_object einen zusätzlichen Texturtyp ein: Das TextureBufferObject, oftmals abgekürzt mit TBO. Dabei handelt es sich um eine eindimensionale Textur, welche ihren Speicherbereich nicht selbst enthält, sondern auf den Speicher eines verknüpften BufferObjects zugreift. Bei einem solchen BufferObject kann es sich beispielsweise um ein VertexBufferObject (VBO) handeln. Es steht somit die Flexibilität von Bufferobjekten auch für Texturen zur Verfügung (fast) ohne zusätzliche Schnittstellen.
Im Zusammenhang mit Transform-Feedback aber auch mit Instancing und bei anderen Gelegenheiten erweisen sich TextureBufferObjects als sehr nützlich. Mit Transform-Feedback kann in einen Vertexbuffer geschrieben werden, welcher dann im nächsten Renderpass ohne zusätzliche Kopiervorgänge als Textur benutzt werden kann. Dies wird unter anderem beim Shader Model 4.0 Partikelsystem exzessiv benutzt. Ein Beispiel zu Instancing findet sich in der Shadersammlung.
Im Shader können TextureBufferObjects ausschließlich mit Integer-Koordinaten adressiert werden. Daher findet auch keine Interpolation zwischen Texeln statt. Wer eine Interpolation benötigt kann diese aber einfach selbst im Shader implementieren.
Für TextureBufferObjects muss keine Größe angegeben werden. Die Größe der Textur berechnet sich aus der Gesamtgröße des zugehörigen Bufferobjektes geteilt durch die Größe eines Texels. Die maximale Größe eines TextureBufferObjects beträgt dabei 2^27 = 134.217.728 Texel im Gegensatz zu normalen eindimensionalen Texturen, welche eine maximale Größe von 2^13 = 8.192 Texeln haben. In Kombination mit einem 4x32bit Texelformat (z.B. RGBA32F) bedeutet dies, dass ein TBO theoretisch bis zu 2 GB groß werden darf. Praktisch ist die Größe natürlich durch den Speicher der Grafikkarte begrenzt.
Inhaltsverzeichnis
Verwendung
Verwendung im Programm
Um unser TextureBufferObject zu Erstellen benutzen wir wie bei gewöhnlichen Texturen die Funktion glGenTextures:
GLuint myTBO;
glGenTextures(1, &myTBO);
Das Löschen geschieht genauso gewohnt mit glDeleteTextures:
glDeleteTextures(1, &myTBO);
Um das TextureBufferObject zu verwenden muss es wie eine normale Textur mit glBindTexture gebunden werden. Wir übergeben dabei allerdings die Konstante GL_TEXTURE_BUFFER_ARB als ersten Parameter:
glBindTexture(GL_TEXTURE_BUFFER_ARB, myTBO);
Anschließend geben wir mit glTexBufferARB(enum target, enum internalformat, uint buffer) an, welches BufferObject mit dem TextureBufferObject verknüpft werden soll. Bei diesem BufferObject kann es sich zum Beispiel um ein VertexBufferObject handeln.
glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_RGBA32F_ARB, myVBO);
Der zweite Parameter gibt hierbei den Datentyp unserer Textur an. Als Beispiel wurde hier GL_RGBA32F_ARB gewählt. Damit wird unsere Textur als vierelementiger 32-bit-float-Vektor benutzt (4*4 = 16 Byte pro Texel). Die Tabelle im Abschnitt Texelformate gibt eine Übersicht über die möglichen Formate, welche als zweiter Parameter angegeben werden können.
Verwendung im Shader
Unser TextureBufferObject ist nun erstellt und gebunden. Nun ist es an der Zeit, es im Shader auszulesen. Dafür brauchen wir neue Textursampler-Typen: samplerBuffer, usamplerBuffer oder isamplerBuffer, je nachdem, was unser TextureBufferObject für einen Datentyp repräsentiert: float, unsigned int oder int. Über diesen Sampler greifen wir mit der Funktion texelFetchBuffer(samplerBuffer sampler, uint index) auf unser TextureBufferObject zu:
#extension GL_EXT_gpu_shader4 : require
// ...
uniform samplerBuffer tbo; // Unser Sampler, wir benutzen floats => samplerBuffer
void main()
{
// Wir brauchen einen Array-Index um einen Texel zum Auslesen zu bestimmen.
unsigned int index;
// Wir berechnen unseren Index.
// ...
// Wir holen einen Texel aus unserem TextureBufferObject.
vec4 tmp = texelFetchBuffer(tbo, index);
// Wir machen etwas mit tmp
// ...
}
Texelformate
Die folgende Tabelle aus der Extension-Spezifikation gibt eine Übersicht über die möglichen Texelformate.
Sized Internal Format | Base Type | Components | Norm | Component | |||
---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | ||||
GL_ALPHA8 | ubyte | 1 | Y | A | . | . | . |
GL_ALPHA16 | ushort | 1 | Y | A | . | . | . |
GL_ALPHA16F_ARB | half | 1 | N | A | . | . | . |
GL_ALPHA32F_ARB | float | 1 | N | A | . | . | . |
GL_ALPHA8I_EXT | byte | 1 | N | A | . | . | . |
GL_ALPHA16I_EXT | short | 1 | N | A | . | . | . |
GL_ALPHA32I_EXT | int | 1 | N | A | . | . | . |
GL_ALPHA8UI_EXT | ubyte | 1 | N | A | . | . | . |
GL_ALPHA16UI_EXT | ushort | 1 | N | A | . | . | . |
GL_ALPHA32UI_EXT | uint | 1 | N | A | . | . | . |
GL_LUMINANCE8 | ubyte | 1 | Y | L | . | . | . |
GL_LUMINANCE16 | ushort | 1 | Y | L | . | . | . |
GL_LUMINANCE16F_ARB | half | 1 | N | L | . | . | . |
GL_LUMINANCE32F_ARB | float | 1 | N | L | . | . | . |
GL_LUMINANCE8I_EXT | byte | 1 | N | L | . | . | . |
GL_LUMINANCE16I_EXT | short | 1 | N | L | . | . | . |
GL_LUMINANCE32I_EXT | int | 1 | N | L | . | . | . |
GL_LUMINANCE8UI_EXT | ubyte | 1 | N | L | . | . | . |
GL_LUMINANCE16UI_EXT | ushort | 1 | N | L | . | . | . |
GL_LUMINANCE32UI_EXT | uint | 1 | N | L | . | . | . |
GL_LUMINANCE8_ALPHA8 | ubyte | 2 | Y | L | A | . | . |
GL_LUMINANCE16_ALPHA16 | ushort | 2 | Y | L | A | . | . |
GL_LUMINANCE_ALPHA16F_ARB | half | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA32F_ARB | float | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA8I_EXT | byte | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA16I_EXT | short | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA32I_EXT | int | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA8UI_EXT | ubyte | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA16UI_EXT | ushort | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA32UI_EXT | uint | 2 | N | L | A | . | . |
GL_INTENSITY8 | ubyte | 1 | Y | I | . | . | . |
GL_INTENSITY16 | ushort | 1 | Y | I | . | . | . |
GL_INTENSITY16F_ARB | half | 1 | N | I | . | . | . |
GL_INTENSITY32F_ARB | float | 1 | N | I | . | . | . |
GL_INTENSITY8I_EXT | byte | 1 | N | I | . | . | . |
GL_INTENSITY16I_EXT | short | 1 | N | A | . | . | . |
GL_INTENSITY32I_EXT | int | 1 | N | A | . | . | . |
GL_INTENSITY8UI_EXT | ubyte | 1 | N | A | . | . | . |
GL_INTENSITY16UI_EXT | ushort | 1 | N | A | . | . | . |
GL_INTENSITY32UI_EXT | uint | 1 | N | A | . | . | . |
GL_RGBA8 | ubyte | 4 | Y | R | G | B | A |
GL_RGBA16 | ushort | 4 | Y | R | G | B | A |
GL_RGBA16F_ARB | half | 4 | N | R | G | B | A |
GL_RGBA32F_ARB | float | 4 | N | R | G | B | A |
GL_RGBA8I_EXT | byte | 4 | N | R | G | B | A |
GL_RGBA16I_EXT | short | 4 | N | R | G | B | A |
GL_RGBA32I_EXT | int | 4 | N | R | G | B | A |
GL_RGBA8UI_EXT | ubyte | 4 | N | R | G | B | A |
GL_RGBA16UI_EXT | ushort | 4 | N | R | G | B | A |
GL_RGBA32UI_EXT | uint | 4 | N | R | G | B | A |
Literatur
- ARB_texture_buffer_object (Englisch)