Benutzer:BerndD: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: Achtung: Dies ist nur eine Arbeitsvorlage für die Seiten die ich gerade erstelle. = ARB_vertex_buffer_object = Die Extension wurde in die OpenGL 1.5 Spezifikation aufg...)
 
 
(4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Achtung: Dies ist nur eine Arbeitsvorlage für die Seiten die ich gerade erstelle.
 
 
= ARB_vertex_buffer_object =
 
= ARB_vertex_buffer_object =
Die Extension wurde in die OpenGL 1.5 Spezifikation aufgenommen. Dieser Artikel berücksichtigt dies, indem hier die mit OpenGL 1.5 eingeführten Bezeichner verwendet werden. Diese entsprechen den zugehörigen Bezeichnern der Extension, unter Weglassung des Prefix "ARB". Im Abschnitt [[#Bezeichner Zuordnung]] ist zur besseren Auffindbarkeit des Artikels eine Gegenüberstellung der alten und neuen Bezeichner beigefügt.
+
Die Extension wurde in die OpenGL 1.5 Spezifikation aufgenommen. Dieser Artikel berücksichtigt dies, indem die mit OpenGL 1.5 eingeführten Bezeichner verwendet werden. Diese entsprechen den zugehörigen Bezeichnern der Extension, unter Weglassung des Suffix "ARB". Im den Abschnitten [[#Neue Funktionen]] und [[#Neue Tokens]] werden zur besseren Auffindbarkeit des Artikels die alten Bezeichner mit angegeben.
<br>
+
 
 
== Abfragestring ==
 
== Abfragestring ==
 
GL_ARB_vertex_buffer_object
 
GL_ARB_vertex_buffer_object
  
 
== Beschreibung ==
 
== Beschreibung ==
Diese Erweiterung definiert eine Schnittstelle, mit der verschiedene Arten von Daten im den Speicher des Servers abgelegt werden können. In der Praxis ist der Server oftmals eine Grafikkarte mit eigenen Video Speicher (VRAM). Auf den eigenen VRAM kann die Grafik-Hardware deutlich schneller zugreifen kann, als auf den Client seitigen vorhandenen Hauptspeicher der CPU. Weil es sich bei den Daten oftmals um Vertex-Array-Daten handelt, wurde mit dieser Extension der Begriff "vertex buffer object" abgekürzt VBO eingeführt, was der Extension auch ihren Namen gab.  
+
Diese Erweiterung definiert eine Schnittstelle, mit der verschiedene Arten von Daten im den Speicher des Servers abgelegt werden können. In der Praxis ist der Server oftmals eine Grafikkarte mit eigenem Video Speicher (VRAM). Auf den eigenem VRAM kann die Grafik-Hardware deutlich schneller zugreifen, als auf den clientseitig vorhandenen Hauptspeicher der CPU. Weil es sich bei den abzulegenden Daten hauptsächlich um Vertex-Array-Daten handelt, wurde mit dieser Extension der Begriff "vertex buffer object" abgekürzt VBO eingeführt, was der Extension auch ihren Namen gab.  
  
VBOs sind in ein Speicherblock zusammengefasste Daten, auf die man von der Anwendung aus über die GL zugreifen kann (glBufferData, glBufferSubData, glGetBufferSubData) oder direkt über ein Zeiger auf das Objekt selbst, als würden sich die Daten im Hauptspeicher befinden. Dies wird über eine Technik realisiert, die im Englischen mit "Memory Mapping" und im Deutschen mit "Speichereinblendung" bezeichnet wird.  
+
VBOs sind in ein Speicherblock zusammengefasste Daten, auf die man von der Anwendung aus über die GL zugreifen kann (z.B. '''glBufferData''', '''glBufferSubData''', '''glGetBufferSubData''') oder direkt über ein Zeiger auf das Objekt selbst, als wären die Daten in einen normalen Hauptspeicherbereich abgelegt. Dies wird über eine Technik realisiert, die im Englischen mit "Memory Mapping" und im Deutschen mit "Speichereinblendung" bezeichnet wird. Die API der Extension verdeckt die Details dieser Technik soweit, dass auch für weniger leistungsfähiger Hardware - die das Einblenden von VRAM in den Hauptspeicher nicht unterstützt - ein möglichst optimaler Zugriff gewährleistet werden kann.  
  
 +
=== Verwendung ===
 +
==== VOB initialisieren ====
 +
Zuerst holt man sich sich mit '''glGenBuffers''' für jede VBO einen eindeutigen Namen (Anmerkung: In GL wird ein Handle auf ein Pufferobjekt als Name bezeichnet):
 +
<pascal>(...)
 +
var
 +
  VBO: array[0..2] of TGLuint;
 +
  (...)
  
sseite mittels   Einmal dort gespeichert, können Dadurch kann die Geschwindigkeit der Datenübertragung erhöht werden.  
+
procedure TGLForm.FormCreate(Sender: TObject);
=== '''Verwendung''' ===
+
begin
In diesen Abschnitt gehört, wie neue Konstanten etc. verwendet werden.
+
   // hier GL initialisieren
Nach Möglichkeit sollte Schrittweise allgemein erklärt werden was zu tun ist.
+
  (...)
Anschließend sollten dann die Unterpunkte ausgefüllt werden.
+
  glGenBuffers(3, @VBO);
Nicht alle Unterpunkte müssen immer vorhanden sein.
+
  (...)</pascal>
 +
Im Beispiel werden für drei VBOs die Namen angefordert. Nun kann man sie mit '''glBindBuffer''' an ein Ziel binden:
 +
<pascal>(...)
 +
  // Der Client soll Vertex Arrays bearbeiten können
 +
  glEnableClientState(GL_VERTEX_ARRAY); 
 +
  // Das 1., noch leere, VBO an das Ziel "Vertex-Array" binden
 +
  glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
 +
  (...)</pascal>
 +
Über das Ziel, im Beispiel das Vertex-Array, kann man das VBO mit Daten füllen. Entweder man kopiert in Hauptspeicher bereits im richtigen Format vorhandene Daten hinein...
 +
<pascal>(...)
 +
  // Die in MyData vorhandenen Daten in das VBO ablegen
 +
  glBufferData(GL_ARRAY_BUFFER, SizeOf(MyData), MyData, GL_STATIC_DRAW);
 +
  (...)</pascal>
 +
... dann kümmert '''glBufferData''' sich um das Ein- und Ausblenden des Speichers oder man benutzt die Funktion nur zum Reservieren eines Speicherblocks mit der im 2. Parameter übergebenen Größe. In 3. Parameter wird dann '''nil''' übergeben (keine Daten zum Kopieren vorhanden). Um das VBO in den Arbeitsspeicher einzublenden, benutzt man die Funktion '''glMapBuffer'''. Damit wird ein Zeiger zum Beschreiben des Speicherbereiches angefordert und damit das VBO in den Arbeitsspeicher eingeblendet:
 +
<pascal>(...)
 +
const
 +
  PointCount =1000;
 +
type
 +
  PVertex2f = ^TVertex2f;
 +
  TVertex2f = packed record
 +
    X,Y: TGLFloat;
 +
  end;
 +
  PVertex2fArray = ^TVertex2fArray;
 +
  TVertex2fArray = packed array[0..0] of TVertex2f;
  
=== '''Kombinierungsarten''' ===
+
var
 +
  VBOPointer: PVertex2fArray;
 +
  i: integer;
 +
  Value: double;
 +
begin
 +
  (...)
 +
  // mit glBufferData ein Speicherblock allokieren
 +
  glBufferData(GL_ARRAY_BUFFER, PointCount*SizeOf(TVertex2f), nil, GL_STATIC_DRAW);
  
{| border=1 rules=all
+
  // Zeiger mit Schreibrechten auf das VBO holen
!Art
+
  VBOPointer := glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
!Formel
+
  try
|-
+
    // Vertex-Daten in den VRAM kopieren
|OPENGL_NAME_1
+
    Value := 240;
|Berechnungsformel1
+
    for i := 0 to PointCount-1 do begin
|}
+
      VBOPointer^[i].X := i*5.14;
 +
      VBOPointer^[i].Y := Value;
 +
      Value := Value+Random*50-25;
 +
    end;
 +
  finally
 +
    // Buffer für andere Zugriffe wieder freigeben (VBOPointer ist danach ungültig)
 +
    glUnMapBuffer(GL_ARRAY_BUFFER);
 +
    VBOPointer := nil;
 +
  end;
 +
  (...)</pascal>
 +
Wichtig ist, dass mit glUnMapBuffer das Einblenden der VBO wieder beendet wird, weil im eingeblendeten Zustand die Anwendung über den Zeiger exklusive Zugriffsrechte auf das VBO bekommt und damit eine gleichzeitige Verwendung durch den Server nicht, oder nur eingeschränkt, möglich ist.
 +
==== VOB beim Rendern benutzen ====
 +
VBOs werden beim Rendern genutzt, indem man die Ziele benutzt, an denen sie gebunden sind. Im obigen Beispiel wurde ein VBO an ein Vektor-Array gebunden. Das Vektor-Array kann man Beispielsweise über die Funktion glDrawArrays benutzen:
 +
<pascal>procedure TGLForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
 +
begin
 +
(...)
 +
  // Vertex 0 bis PointCount-1 als Linie zeichnen
 +
  glDrawArrays(GL_LINE_STRIP, 0, PointCount);
 +
  // Vertex 0 bis PointCount-1 als 5x5 Pixel-Punkte zeichnen
 +
  glPointSize(5.0);
 +
  glDrawArrays(GL_POINTS, 0, PointCount);
 +
  (...)</pascal>
  
  
=== '''Operanden''' ===
+
==== VOB freigeben ====
Hier gehören Operandenbeschreibungen hin. Wo werden die Operanden eingesetzt. Die Tabelle enthält dann
+
Mit der Funktion '''glDeleteBuffers''' werden VBOs freigegeben:
genaue Infos.
+
<pascal>(...)
 +
var
 +
  VBO: array[0..2] of TGLuint;
 +
  (...)
  
{| border=1 rules=all
+
procedure TGLForm.FormDestroy(Sender: TObject);
!Operand
+
begin
!Beschreibung
+
  (...)
|-
+
  // freigeben der drei VBOs
|OPENGL_OPERAND_1
+
  glDeleteBuffers(3, VBO);
|Beschreibung
+
  (...)</pascal>
|}
+
Eine Bindung an ein Ziel im selben Thread-Kontext muss nicht vorher gelöst werden. War eine VBO vor Aufruf der Funktion '''glDeleteBuffers''' gebunden, wird die Bindung im Ziel durch den Null-Namen ersetzt. Dies gilt allerdings nur für den Thread-Kontext, in dem die Freigabe erfolgt. Existieren anderen Thread-Kontexten die das VBO nutzen, müssen die Bindungen dort vorher gelöst werden, damit es nicht zu Zugriffen auf die nicht mehr existierende VBO kommt kann.
  
=== Bezeichner Zuordnung ===
+
== Neue Funktionen ==
=== Hinweise ===
+
Die in der OpenGL Spezifikation >=1.5 verwendeten Bezeichner sind verlinkt. In Klammern dahinter die Bezeichner wie sie in der Extension benutzt werden.
 
+
*[[glBindBuffer]]            (glBindBufferARB)             
Hier kommen Hinweise zur Extension(!) rein die gesondert erwähnt werden sollten.
+
*[[glDeleteBuffers]]          (glDeleteBuffersARB)
 +
*[[glGenBuffers]]            (glGenBuffersARB)
 +
*[[glIsBuffer]]              (glIsBufferARB)
 +
*[[glBufferData]]            (glBufferDataARB)
 +
*[[glBufferSubData]]          (glBufferSubDataARB)
 +
*[[glGetBufferSubData]]      (glGetBufferSubDataARB)
 +
*[[glMapBuffer]]              (glMapBufferARB)
 +
*[[glUnmapBuffer]]            (glUnmapBufferARB)
 +
*[[glGetBufferParameteriv]]  (glGetBufferParameterivARB)
 +
*[[glGetBufferPointerv]]      (glGetBufferPointervARB)
  
== Neue Funktionen ==
 
Hier Links auf die neuen Funktionen einfügen
 
  
 
== Neue Tokens ==
 
== Neue Tokens ==
In die folgenden Abschnitte soll eine Auflistung aller neuen Token in der folgenden Form gemacht werden:
+
Die in der OpenGL Spezifikation >=1.5 verwendeten Bezeichner sind hier '''FETT''' hervorgehoben. In Klammern dahinter die Bezeichner wie sie in der Extension benutzt werden. Für nähere Informationen zu den Token-Werten sollte bei der zugehörigen Funktion nachgeschlagen werden.
  
 
=== Neue Parameterwerte ===
 
=== Neue Parameterwerte ===
'''Für <nowiki>[[glEinOGLBefehl]]</nowiki>'''<br>
+
*'''Für den <nowiki><target></nowiki> Parameter der Funktionen [[glBindBuffer | BindBuffer]], [[glBufferData | BufferData]], [[glBufferSubData | BufferSubData]], [[glMapBuffer | MapBuffer]], [[glUnmapBuffer | UnmapBuffer]], [[glGetBufferSubData | GetBufferSubData]], [[glGetBufferParameteriv | GetBufferParameteriv]] und [[glGetBufferPointerv | GetBufferPointerv]] '''<br>
wenn ''pname'' '''GL_PARAMTER_NAME''' ist, dann ist/sind für ''param'' folgende(r) zusätzliche(r) Wert(e) gültig:
+
 
 +
<table border=1 rules=all>
 +
<tr>
 +
<td>'''GL_ARRAY_BUFFER''' (GL_ARRAY_BUFFER_ARB)</td>
 +
<td>0x8892</td>
 +
<td>Das Ziel ist ein [[Vertexarray|Vertex Array]]</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_ELEMENT_ARRAY_BUFFER''' (GL_ELEMENT_ARRAY_BUFFER_ARB)</td>
 +
<td>0x8893</td>
 +
<td>Das Ziel ist ein [[Indexarray | Index Array]]</td>
 +
</tr>
 +
</table>
 +
 
 +
 
 +
*'''Für den <nowiki><pname></nowiki> Parameter der Funktionen [[glGetBooleanv | GetBooleanv]], [[glGetIntegerv | GetIntegerv]], [[glGetFloatv | GetFloatv]] und [[glGetDoublev | GetDoublev]]'''<br>
 +
 
 +
<table border=1 rules=all>
 +
<tr>
 +
<td>'''GL_ARRAY_BUFFER_BINDING''' (GL_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x8894</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_ELEMENT_ARRAY_BUFFER_BINDING''' (GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x8895</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_VERTEX_ARRAY_BUFFER_BINDING''' (GL_VERTEX_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x8896</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_NORMAL_ARRAY_BUFFER_BINDING''' (GL_NORMAL_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x8897</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_COLOR_ARRAY_BUFFER_BINDING''' (GL_COLOR_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x8898</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_INDEX_ARRAY_BUFFER_BINDING''' (GL_INDEX_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x8899</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING''' (GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x889A</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_EDGE_FLAG_ARRAY_BUFFER_BINDING''' (GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x889B</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING''' (GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x889C</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING''' (GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x889D</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_WEIGHT_ARRAY_BUFFER_BINDING''' (GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x889E</td>
 +
</tr>
 +
</table>
 +
 
 +
 
 +
*'''Für den <nowiki><pname></nowiki> Parameter der Funktion [[glGetVertexAttribiv | GetVertexAttribiv]] '''<br>
 +
 
 +
<table border=1 rules=all>
 +
<tr>
 +
<td>'''GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING''' (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB)</td>
 +
<td>0x889F</td>
 +
</tr>
 +
</table>
 +
 
 +
 
 +
*'''Für den <nowiki><usage></nowiki> Parameter der Funktion [[glBufferData | BufferData]] '''<br>
 +
 
 +
<table border=1 rules=all>
 +
<tr>
 +
<td>'''GL_STREAM_DRAW''' (GL_STREAM_DRAW_ARB)</td>
 +
<td>0x88E0</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_STREAM_READ''' (GL_STREAM_READ_ARB)</td>
 +
<td>0x88E1</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_STREAM_COPY''' (GL_STREAM_COPY_ARB)</td>
 +
<td>0x88E2</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_STATIC_DRAW''' (GL_STATIC_DRAW_ARB)</td>
 +
<td>0x88E4</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_STATIC_READ''' (GL_STATIC_READ_ARB)</td>
 +
<td>0x88E5</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_STATIC_COPY''' (GL_STATIC_COPY_ARB)</td>
 +
<td>0x88E6</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_DYNAMIC_DRAW''' (GL_DYNAMIC_DRAW_ARB)</td>
 +
<td>0x88E8</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_DYNAMIC_READ''' (GL_DYNAMIC_READ_ARB)</td>
 +
<td>0x88E9</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_DYNAMIC_COPY''' (GL_DYNAMIC_COPY_ARB)</td>
 +
<td>0x88EA</td>
 +
</tr>
 +
</table>
 +
 
 +
*'''Für den <nowiki><access></nowiki> Parameter der Funktion [[glMapBuffer | MapBuffer]] '''<br>
 +
 
 
<table border=1 rules=all>
 
<table border=1 rules=all>
 
<tr>
 
<tr>
  <td>'''GL_TOKEN_NAME'''</td>
+
  <td>'''GL_READ_ONLY''' (GL_READ_ONLY_ARB)</td>
  <td>HexCode des Tokens</td>
+
  <td>0x88B8</td>
  <td>Beschreibung</td>
+
</tr>
 +
<tr>
 +
<td>'''GL_WRITE_ONLY''' (GL_WRITE_ONLY_ARB)</td>
 +
<td>0x88B9</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_READ_WRITE''' (GL_READ_WRITE_ARB)</td>
 +
  <td>0x88BA</td>
 
</tr>
 
</tr>
 
</table>
 
</table>
  
<br>
 
  
'''Für <nowiki>[[glEinOGLBefehl]]</nowiki>'''<br>
+
*'''Für den <nowiki><pname></nowiki> Parameter der Funktion [[glGetBufferParameteriv | GetBufferParameteriv]] '''<br>
wenn ''pname'' ...
+
 
 +
<table border=1 rules=all>
 +
<tr>
 +
<td>'''GL_BUFFER_SIZE''' (GL_BUFFER_SIZE_ARB)</td>
 +
<td>0x8764</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_BUFFER_USAGE''' (GL_BUFFER_USAGE_ARB)</td>
 +
<td>0x8765</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_BUFFER_ACCESS''' (GL_BUFFER_ACCESS_ARB)</td>
 +
<td>0x88BB</td>
 +
</tr>
 +
<tr>
 +
<td>'''GL_BUFFER_MAPPED''' (GL_BUFFER_MAPPED_ARB)</td>
 +
<td>0x88BC</td>
 +
</tr>
 +
</table>
  
<br>
+
 
 +
*'''Für den <nowiki><pname></nowiki> Parameter der Funktion [[glGetBufferPointerv | GetBufferPointerv]] '''<br>
 +
 
 +
<table border=1 rules=all>
 +
<tr>
 +
<td>'''GL_BUFFER_MAP_POINTER''' (GL_BUFFER_MAP_POINTER_ARB)</td>
 +
<td>0x88BD</td>
 +
</tr>
 +
</table>
  
  
 
=== '''Neue States''' ===
 
=== '''Neue States''' ===
{| border=1 rules=all
+
Es wurden keine neuen States eingeführt.
!Name
 
!Abfrage mit
 
!Initialwert
 
|-
 
|OPENGL_STATE_1
 
|GetFunction
 
|Wert
 
|}
 
  
 
== Abhängigkeiten ==
 
== Abhängigkeiten ==
Interne Links auf Extensions von denen die hier beschriebene abhängt
+
Die Extension ARB_vertex_buffer_object wurde auf Basis der OpenGL 1.4 Spezifikation geschrieben und ihre Definition wurde von folgenden Extensionen beeinflusst:
 
+
*[[GL_ARB_vertex_blend]]
<br>
+
*[[GL_ARB_vertex_program]]
 +
*[[GL_EXT_vertex_shader]]
  
 
== Ressourcen ==
 
== Ressourcen ==
Hier muss mindestens ein Link auf die Orginalspezifikation (bei oss.sgi.com/...) stehen.
+
*[http://opengl.org/registry/specs/ARB/vertex_buffer_object.txt Orginalspezifikation]
 +
*[[Tutorial_Vertexbufferobject| Vertexbufferobject Tutorial]]

Aktuelle Version vom 4. Oktober 2008, 23:54 Uhr

ARB_vertex_buffer_object

Die Extension wurde in die OpenGL 1.5 Spezifikation aufgenommen. Dieser Artikel berücksichtigt dies, indem die mit OpenGL 1.5 eingeführten Bezeichner verwendet werden. Diese entsprechen den zugehörigen Bezeichnern der Extension, unter Weglassung des Suffix "ARB". Im den Abschnitten #Neue Funktionen und #Neue Tokens werden zur besseren Auffindbarkeit des Artikels die alten Bezeichner mit angegeben.

Abfragestring

GL_ARB_vertex_buffer_object

Beschreibung

Diese Erweiterung definiert eine Schnittstelle, mit der verschiedene Arten von Daten im den Speicher des Servers abgelegt werden können. In der Praxis ist der Server oftmals eine Grafikkarte mit eigenem Video Speicher (VRAM). Auf den eigenem VRAM kann die Grafik-Hardware deutlich schneller zugreifen, als auf den clientseitig vorhandenen Hauptspeicher der CPU. Weil es sich bei den abzulegenden Daten hauptsächlich um Vertex-Array-Daten handelt, wurde mit dieser Extension der Begriff "vertex buffer object" abgekürzt VBO eingeführt, was der Extension auch ihren Namen gab.

VBOs sind in ein Speicherblock zusammengefasste Daten, auf die man von der Anwendung aus über die GL zugreifen kann (z.B. glBufferData, glBufferSubData, glGetBufferSubData) oder direkt über ein Zeiger auf das Objekt selbst, als wären die Daten in einen normalen Hauptspeicherbereich abgelegt. Dies wird über eine Technik realisiert, die im Englischen mit "Memory Mapping" und im Deutschen mit "Speichereinblendung" bezeichnet wird. Die API der Extension verdeckt die Details dieser Technik soweit, dass auch für weniger leistungsfähiger Hardware - die das Einblenden von VRAM in den Hauptspeicher nicht unterstützt - ein möglichst optimaler Zugriff gewährleistet werden kann.

Verwendung

VOB initialisieren

Zuerst holt man sich sich mit glGenBuffers für jede VBO einen eindeutigen Namen (Anmerkung: In GL wird ein Handle auf ein Pufferobjekt als Name bezeichnet):

(...)
var
  VBO: array[0..2] of TGLuint;
  (...)

procedure TGLForm.FormCreate(Sender: TObject);
begin
  // hier GL initialisieren
  (...)
  glGenBuffers(3, @VBO);
  (...)

Im Beispiel werden für drei VBOs die Namen angefordert. Nun kann man sie mit glBindBuffer an ein Ziel binden:

(...)
  // Der Client soll Vertex Arrays bearbeiten können
  glEnableClientState(GL_VERTEX_ARRAY);  
  // Das 1., noch leere, VBO an das Ziel "Vertex-Array" binden
  glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
  (...)

Über das Ziel, im Beispiel das Vertex-Array, kann man das VBO mit Daten füllen. Entweder man kopiert in Hauptspeicher bereits im richtigen Format vorhandene Daten hinein...

(...)
  // Die in MyData vorhandenen Daten in das VBO ablegen
  glBufferData(GL_ARRAY_BUFFER, SizeOf(MyData), MyData, GL_STATIC_DRAW);
  (...)

... dann kümmert glBufferData sich um das Ein- und Ausblenden des Speichers oder man benutzt die Funktion nur zum Reservieren eines Speicherblocks mit der im 2. Parameter übergebenen Größe. In 3. Parameter wird dann nil übergeben (keine Daten zum Kopieren vorhanden). Um das VBO in den Arbeitsspeicher einzublenden, benutzt man die Funktion glMapBuffer. Damit wird ein Zeiger zum Beschreiben des Speicherbereiches angefordert und damit das VBO in den Arbeitsspeicher eingeblendet:

(...)
const
  PointCount =1000;
type
  PVertex2f = ^TVertex2f;
  TVertex2f = packed record
    X,Y: TGLFloat;
  end;
  PVertex2fArray = ^TVertex2fArray;
  TVertex2fArray = packed array[0..0] of TVertex2f;

var
  VBOPointer: PVertex2fArray;
  i: integer;
  Value: double;
begin
  (...)
  // mit glBufferData ein Speicherblock allokieren
  glBufferData(GL_ARRAY_BUFFER, PointCount*SizeOf(TVertex2f), nil, GL_STATIC_DRAW);

  // Zeiger mit Schreibrechten auf das VBO holen
  VBOPointer := glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
  try
    // Vertex-Daten in den VRAM kopieren
    Value := 240;
    for i := 0 to PointCount-1 do begin
      VBOPointer^[i].X := i*5.14;
      VBOPointer^[i].Y := Value;
      Value := Value+Random*50-25;
    end;
  finally
    // Buffer für andere Zugriffe wieder freigeben (VBOPointer ist danach ungültig)
    glUnMapBuffer(GL_ARRAY_BUFFER);
    VBOPointer := nil;
  end;
  (...)

Wichtig ist, dass mit glUnMapBuffer das Einblenden der VBO wieder beendet wird, weil im eingeblendeten Zustand die Anwendung über den Zeiger exklusive Zugriffsrechte auf das VBO bekommt und damit eine gleichzeitige Verwendung durch den Server nicht, oder nur eingeschränkt, möglich ist.

VOB beim Rendern benutzen

VBOs werden beim Rendern genutzt, indem man die Ziele benutzt, an denen sie gebunden sind. Im obigen Beispiel wurde ein VBO an ein Vektor-Array gebunden. Das Vektor-Array kann man Beispielsweise über die Funktion glDrawArrays benutzen:

procedure TGLForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
begin
(...)
  // Vertex 0 bis PointCount-1 als Linie zeichnen
  glDrawArrays(GL_LINE_STRIP, 0, PointCount);
  // Vertex 0 bis PointCount-1 als 5x5 Pixel-Punkte zeichnen
  glPointSize(5.0);
  glDrawArrays(GL_POINTS, 0, PointCount);
  (...)


VOB freigeben

Mit der Funktion glDeleteBuffers werden VBOs freigegeben:

(...)
var
  VBO: array[0..2] of TGLuint;
  (...)

procedure TGLForm.FormDestroy(Sender: TObject);
begin
  (...)
  // freigeben der drei VBOs
  glDeleteBuffers(3, VBO);
  (...)

Eine Bindung an ein Ziel im selben Thread-Kontext muss nicht vorher gelöst werden. War eine VBO vor Aufruf der Funktion glDeleteBuffers gebunden, wird die Bindung im Ziel durch den Null-Namen ersetzt. Dies gilt allerdings nur für den Thread-Kontext, in dem die Freigabe erfolgt. Existieren anderen Thread-Kontexten die das VBO nutzen, müssen die Bindungen dort vorher gelöst werden, damit es nicht zu Zugriffen auf die nicht mehr existierende VBO kommt kann.

Neue Funktionen

Die in der OpenGL Spezifikation >=1.5 verwendeten Bezeichner sind verlinkt. In Klammern dahinter die Bezeichner wie sie in der Extension benutzt werden.


Neue Tokens

Die in der OpenGL Spezifikation >=1.5 verwendeten Bezeichner sind hier FETT hervorgehoben. In Klammern dahinter die Bezeichner wie sie in der Extension benutzt werden. Für nähere Informationen zu den Token-Werten sollte bei der zugehörigen Funktion nachgeschlagen werden.

Neue Parameterwerte

GL_ARRAY_BUFFER (GL_ARRAY_BUFFER_ARB) 0x8892 Das Ziel ist ein Vertex Array
GL_ELEMENT_ARRAY_BUFFER (GL_ELEMENT_ARRAY_BUFFER_ARB) 0x8893 Das Ziel ist ein Index Array


GL_ARRAY_BUFFER_BINDING (GL_ARRAY_BUFFER_BINDING_ARB) 0x8894
GL_ELEMENT_ARRAY_BUFFER_BINDING (GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB) 0x8895
GL_VERTEX_ARRAY_BUFFER_BINDING (GL_VERTEX_ARRAY_BUFFER_BINDING_ARB) 0x8896
GL_NORMAL_ARRAY_BUFFER_BINDING (GL_NORMAL_ARRAY_BUFFER_BINDING_ARB) 0x8897
GL_COLOR_ARRAY_BUFFER_BINDING (GL_COLOR_ARRAY_BUFFER_BINDING_ARB) 0x8898
GL_INDEX_ARRAY_BUFFER_BINDING (GL_INDEX_ARRAY_BUFFER_BINDING_ARB) 0x8899
GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING (GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB) 0x889A
GL_EDGE_FLAG_ARRAY_BUFFER_BINDING (GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB) 0x889B
GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING (GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB) 0x889C
GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING (GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB) 0x889D
GL_WEIGHT_ARRAY_BUFFER_BINDING (GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB) 0x889E


GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB) 0x889F


GL_STREAM_DRAW (GL_STREAM_DRAW_ARB) 0x88E0
GL_STREAM_READ (GL_STREAM_READ_ARB) 0x88E1
GL_STREAM_COPY (GL_STREAM_COPY_ARB) 0x88E2
GL_STATIC_DRAW (GL_STATIC_DRAW_ARB) 0x88E4
GL_STATIC_READ (GL_STATIC_READ_ARB) 0x88E5
GL_STATIC_COPY (GL_STATIC_COPY_ARB) 0x88E6
GL_DYNAMIC_DRAW (GL_DYNAMIC_DRAW_ARB) 0x88E8
GL_DYNAMIC_READ (GL_DYNAMIC_READ_ARB) 0x88E9
GL_DYNAMIC_COPY (GL_DYNAMIC_COPY_ARB) 0x88EA
  • Für den <access> Parameter der Funktion MapBuffer
GL_READ_ONLY (GL_READ_ONLY_ARB) 0x88B8
GL_WRITE_ONLY (GL_WRITE_ONLY_ARB) 0x88B9
GL_READ_WRITE (GL_READ_WRITE_ARB) 0x88BA


GL_BUFFER_SIZE (GL_BUFFER_SIZE_ARB) 0x8764
GL_BUFFER_USAGE (GL_BUFFER_USAGE_ARB) 0x8765
GL_BUFFER_ACCESS (GL_BUFFER_ACCESS_ARB) 0x88BB
GL_BUFFER_MAPPED (GL_BUFFER_MAPPED_ARB) 0x88BC


GL_BUFFER_MAP_POINTER (GL_BUFFER_MAP_POINTER_ARB) 0x88BD


Neue States

Es wurden keine neuen States eingeführt.

Abhängigkeiten

Die Extension ARB_vertex_buffer_object wurde auf Basis der OpenGL 1.4 Spezifikation geschrieben und ihre Definition wurde von folgenden Extensionen beeinflusst:

Ressourcen