Vraag Wat zijn Vertex-arrayobjecten?


Ik begin vandaag nog met het leren OpenGL uit deze tutorial: http://openglbook.com/the-book/
Ik kwam bij hoofdstuk 2, waar ik een driehoek teken, en ik begrijp alles behalve VAO's (is dit acroniem OK?). De tutorial heeft deze code:

glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);

Hoewel ik begrijp dat de code noodzakelijk is, heb ik geen idee wat het doet. Hoewel ik VaoId nooit voorbij dit punt gebruik (behalve om het te vernietigen), functioneert de code niet zonder deze. Ik ga ervan uit dat dit komt omdat het verplicht is om gebonden te zijn, maar ik weet niet waarom. Moet deze exacte code deel uitmaken van elk OpenGL-programma? In de zelfstudie worden VAO's als volgt uitgelegd:

Een Vertex Array-object (of VAO) is een object dat beschrijft hoe de hoekpuntattributen worden opgeslagen in een Vertex-bufferobject (of VBO). Dit betekent dat de VAO niet het werkelijke object is dat de hoekpuntgegevens opslaat, maar de descriptor van de hoekpuntgegevens. Vertex-kenmerken kunnen worden beschreven door de functie glVertexAttribPointer en de twee zusterfuncties glVertexAttribIPointer en glVertexAttribLPointer, waarvan we de eerste hieronder zullen bekijken.

Ik begrijp niet hoe de VAO de vertex-kenmerken beschrijft. Ik heb ze op geen enkele manier beschreven. Krijgt het de informatie van de glVertexAttribPointer? Ik denk dat dit het moet zijn. Is de VAO eenvoudigweg een bestemming voor de informatie van glVertexAttribPointer?

Even terzijde, is de tutorial die ik volg acceptabel? Is er iets waar ik op moet letten of een betere handleiding om te volgen?


85
2017-08-06 00:30


oorsprong


antwoorden:


"Vertex Array Object" wordt u aangeboden door de OpenGL ARB Subcommittee for Silly Names.

Zie het als een geometrie-object. (Als een oude tijd SGI Performer-programmeur, noem ik ze geosets.) De instantievariabelen / leden van het object zijn je vertex-aanwijzer, normale aanwijzer, kleuraanwijzer, attrib N pointer, ...

Wanneer een VAO voor het eerst wordt gebonden, wijst u deze leden toe door te bellen

glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer...;
glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer...;

enzovoort. Welke kenmerken zijn ingeschakeld en de pointers die u toevoegt, worden opgeslagen in de VAO.

Nadat u de VAO opnieuw hebt gekoppeld, worden al die kenmerken en aanwijzers ook actueel. Zo een glBindVertexArray gesprek is gelijk aan alle code die eerder nodig was om alle kenmerken in te stellen. Het is handig voor het doorgeven van geometrie tussen functies of methoden zonder dat u uw eigen structuren of objecten hoeft te maken.

(Eenmalig instellen, meervoudig gebruik is de gemakkelijkste manier om VAO's te gebruiken, maar u kunt ook kenmerken wijzigen door het te binden en meer aan / uitroepaanroepen te doen. VAO's zijn geen constanten.)

Meer info als antwoord op de vragen van Patrick:

De standaardwaarde voor een nieuw gemaakte VAO is dat deze leeg is (AFAIK). Helemaal geen geometrie, zelfs geen hoekpunten, dus als je het probeert te tekenen, krijg je een OpenGL-foutmelding. Dit is redelijk, net als bij "Alles initialiseren naar False / NULL / zero".

Je hoeft het alleen maar te doen glEnableClientState als je dingen opzet. De VAO onthoudt de enable / disable-status voor elke aanwijzer.

Ja, de VAO wordt opgeslagen glEnableVertexAttribArray en glVertexAttrib. De oude vertex, normale, kleur, ... arrays zijn hetzelfde als attribuutmatrices, vertex == # 0 enzovoort.


81
2017-08-06 01:24



Vertex Array-objecten lijken op macros in tekstverwerkingsprogramma's en dergelijke. Een goede beschrijving is gevonden hier.

Macro's gewoon onthouden de acties die u deed, zoals het activeren van dit kenmerk, het binden van die buffer, enz. Wanneer u belt glBindVertexArray( yourVAOId ), het eenvoudig replays die attribuut aanwijzerbindingen en bufferbindingen.

Dus je volgende call om te tekenen gebruikt alles wat gebonden was door de VAO.

VAO's worden niet opgeslagen vertex data. Nee. De hoekpuntgegevens worden opgeslagen in een hoekpunt buffer of in een array van clientgeheugen.


7
2017-07-07 22:39



VAO is een object dat de vertex-ophaalfase van de OpenGL-pijplijn weergeeft en wordt gebruikt om invoer aan de hoekpuntshader toe te voegen.

U kunt een vertex array-object zoals dit maken

GLuint vao;
glCreateVertexArrays(1, &vao);
glBindVertexArray(vao);

Laten we eerst een eenvoudig voorbeeld doen. Overweeg zo'n invoerparameter in een arceringscode

layout (location = 0) in vec4 offset; // input vertex attribute

Om dit kenmerk in te vullen kunnen we gebruiken

glVertexAttrib4fv(0, attrib); // updates the value of input attribute 0

Hoewel het vertex-arrayobject deze statische attribuutwaarden opslaat Jij, het kan veel meer doen.

Na het maken van een vertex array-object kunnen we beginnen met het invullen van de status. We zullen OpenGL vragen om het automatisch te vullen met behulp van de gegevens die zijn opgeslagen in een bufferobject dat we leveren. Elk vertex-kenmerk krijgt de mogelijkheid om gegevens op te halen uit een buffer die is gebonden aan een van de verschillende vertex-bufferbindingen. Hiervoor gebruiken we glVertexArrayAttribBinding(GLuint vao, GLuint attribindex, GLuint bindingindex). Ook gebruiken we de glVertexArrayVertexBuffer() functie om een ​​buffer te binden aan een van de vertex-bufferbindingen. Wij gebruiken de glVertexArrayAttribFormat() functie om de lay-out en het formaat van de gegevens te beschrijven, en tot slot maken we het automatisch invullen van het attribuut door te bellen mogelijk glEnableVertexAttribArray().

Wanneer een hoekpuntkenmerk is ingeschakeld, voert OpenGL gegevens naar de hoekpuntshader op basis van het formaat en de locatiegegevens die u hebt opgegeven met glVertexArrayVertexBuffer() en glVertexArrayAttribFormat(). Wanneer het attribuut is uitgeschakeld, de vertex-arcering wordt voorzien van de statische informatie die u oproept met een oproep glVertexAttrib*().

// First, bind a vertex buffer to the VAO
glVertexArrayVertexBuffer(vao, 0, buffer, 0, sizeof(vmath::vec4));

// Now, describe the data to OpenGL, tell it where it is, and turn on automatic
// vertex fetching for the specified attribute
glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0);

glEnableVertexArrayAttrib(vao, 0);

En codeer in een arcering

layout (location = 0) in vec4 position;

U moet tenslotte bellen naar glDeleteVertexArrays(1, &vao).


Jij kunt lezen OpenGL SuperBible om het beter te begrijpen.


5
2017-10-14 08:17