Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Mai 14, 2024 00:21

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Allgemeines zu VBOs, VAOs und Shader
BeitragVerfasst: Di Dez 16, 2014 11:10 
Offline
DGL Member

Registriert: Di Dez 16, 2014 10:18
Beiträge: 32
Programmiersprache: C++
Hallo zusammen,

Ich würde gerne wissen, ob ich die Systematik dahinter richtig verstanden habe:
  • In einerm VBO/EBO kann ich sämtliche Daten wie Vertex, Farbe und Indizes abspeichern. Diese Daten sind dann an das jeweilige VBO gebunden und ich kann diese Daten wenn ich sie benötige mithilfe von glBindBuffer(...) aufrufen.
  • Hingegen werden in dem VAO keine Daten gespeichert, sondern das VAO dient dem Shader als Informationquelle, wie die Struktur der Daten aussieht.
Wenn ich also eine Szene rendern möchte, gehe ich wie folgt vor:

  1. Aufrufen der Daten mit glBindBuffer() (Daten wurde in einer anderne Funktion mit glBufferData eingelesen)
  2. Festlegen welchen Shader er benutzen soll mit glUseProgram() (ShaderPrgramm wurde in andere Funktion erstellt)
  3. Aufrufen des VAOs mit glBindVertexArray() (Informationen wurden in anderer Funktion definiert)
  4. Zeichnen des Szene mit glDrawElements()
  5. Löschen aller Bindungen

Vielen Dank.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 16, 2014 13:00 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

prinzipiell hast du das richtig verstanden. Ein VBO enthält Vertex-Daten und ein VAO die Meta-Informationen zum VBO. glBindBuffer macht mit den Daten noch nichts, es sagt OpenGL nur, das du etwas mit dem VBO (bzw. den Daten darin machen willst). Das glBindBuffer musst du beim rendern nicht vor glBindVertexArray aufrufen. Das VAO merkt sich welches VBO zur Initialisierung des VAOs gebunden war und ruft dieses dann automatisch auf (siehe Wiki). Das Ganze hat auch nichts mit Shadern zu tun. Das ist zwar am Ende eine der Anwendungsmöglichkeiten die am meißten zum Einsatz kommt, man kann die Daten aus dem VBO aber auch für andere Techniken nutzen (ohne Shader).

MfG Bergmann

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 16, 2014 14:01 
Offline
Compliance Officer
Benutzeravatar

Registriert: So Aug 08, 2010 08:37
Beiträge: 460
Programmiersprache: C / C++ / Lua
In Buffer Objects kannst du prinzipiell erstmal reinkippen was du willst - sie speichern einfach das, was du reinkippst, im Grafikkartenspeicher.

Ein Buffer Object wird erstellt mit glGenBuffers und gebunden(aufrufen ist das falsche Wort) mittels glBindBuffer. Das Buffer Objekt wird wieder freigegeben mittels glDeleteBuffers.

(Diese Mechanik ist bei fast(?) allen OpenGL Objekten gleich, genauso funktioniert es auch bei VAOs, nur halt mittels glGenVertexArrays, glDeleteVertexArrays und glBindVertexArray, weshalb ich bei den folgenden Objekten nicht mehr darauf eingehen werde.)

Der gebundene Buffer wird von den folgenden Befehlen, die sich auf ihn beziehen, genutzt. Selbst verändert oder "aufgerufen" wird da noch nichts.

Mittels glBufferData kannst du dann Daten in das gebundene Buffer Object reinfüllen.
Dabei gibts du einfach einen Pointer auf z.B. ein Array mit deinen Daten und der OpenGL Befehl kopiert dann die Daten aus deinem RAM in den GRAM.

Der erste Parameter von glBindBuffer oder glBufferData, GL_ARRAY_BUFFER oder GL_ELEMENT_ARRAY_BUFFER, gibt an, welche Art von BO du nutzen willst, VBO oder EBO/IBO.

Ich fange mit dem EBO oder IBO an, weil es einfacher ist.
In einem Element Buffer Object, oder wie ich es lieber nenne, Index Buffer Object (IBO), werden die Indices gespeichert, die dann z.B. glDrawElements zum Rendern nutzt.
Der type Parameter von glDrawElements gibt dabei den Typ der im IBO gespeicherten Indices zurück.
Wenn du also in dein IBO die Indices als GLuint's reinkippst, musst du glDrawElements auch, mittels GL_UNSIGNED_INT, sagen, dass es unsigned integers sind, ansonsten kommt Bullshit / Access Violation raus ;).

Nun zu Vertex Buffer Objects (also VBO's), jene sollen normalerweise speichern:
  • Vertices
  • Normalen
  • Farben
  • UV/W-Koordinaten (= Texturekoordinaten)

WAS und vorallem WO die einzelnen Sachen drin stehen "erklärst" du mittels von Vertex Array Objects (VAO).

Diese bestimmen, welche Daten aus dem VBO, wohin beim Rendern (z.B. beim Aufruf von glDrawElements() ) gehen.

Einerseits speichern VAOs deine verwendeten Buffer Objekte. Dabei gehts du so vor:

  • Generieren & Binden des VAOs
  • Erneutes Binden beider Bufferobjekte (WICHTIG! Du musst sie NOCHMAL Binden, unabhängig davon, ob sie schon gebunden sind! Frag mich nicht warum, ist so.)
  • Füllen des VAOs mittels glEnableVertexAttrib und glVertexAttribPointer, s.u.


Der erste Parameter von glVertexAttribPointer bestimmt dabei das Vertex Attribut, das muss vorher mittels glEnableVertexAttrib "angeschaltet" werden.
Pre-OpenGL 3 waren die Vertex Attribute hardgecodet:
  • 0 - Vertices - im Shader gl_Vertex
  • 1 - Normalen - im Shader gl_Normal
  • 2 - Texturkoordinaten - im Shader gl_TexCoord (oder so)
  • ...und noch ein paar mehr, die ich aber gerade nicht finde.

Daher funktionieren sie auch heute noch ohne Shader, beziehungsweise in alten Shadern, die noch gl_Vertex, etc. nutzen - auch wenn du dabei dann zwingend deprecated Features nutzen musst, da man z.B. ab GL3.X Shader nutzen muss.

Ab OpenGL 3.3 (oder so, auf jeden Fall in OpenGL 4) kannst du die Vertex Attribute jedoch selbst im Shader festlegen:

Code:
  1.  
  2. layout(location = 2) in vec4 a_vec;
  3.  

Heißt: Die Daten aus dem VBO, die das VAO für Position 2 beschreibt, werden im Shader in "a_vec" verfügbar sein (im Vertex Shader, für jeden einzelnen Vertex).

Du kannst also selbst bestimmen, wo du welche Daten haben willst - die werden dann im Vertex Shader aus dem jeweiligen VBO mittels der Beschreibung im VAO geholt.

Das müssen daher also nicht mehr nur Vertices, Normalen oder Farben sein, du kannst da reinpacken was auch immer du brauchst, da du es ja dann im Vertex Shader nutzen kannst.

Dein Rendervorgang sieht also normalerweise so aus:

  • …sonstiger Foo…
  • VAO binden - das bindet automatisch dein VBO und IBO
  • Shader binden (vllt. noch Uniforms übergeben, nicht notwendig, wenn alles notwendige im VBO ist)
  • glDrawElements, o.Ä.
  • …sonstige Foo, z.B. SwapBuffers…

Ich hoffe meine ausführlichen Erläuterungen sind brauchbar, ansonsten kannst du auch einfach mal im IRC vorbeischauen, da helfen dir dann auch $leute :)

_________________
offizieller DGL Compliance Beauftragter
Never run a changing system! (oder so)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.029s | 17 Queries | GZIP : On ]