W jaki sposób re-glBufferData () 'współdziała z glVertexAttribPointer?
Rozumiem podstawową sekwencję: glGenBuffers () tworzy „nazwę obiektu bufora”, glBindBuffer () tworzy rzeczywisty obiekt bufora (a także wiąże jego nazwę), glBufferData () „tworzy i inicjalizuje magazyn danych obiektu bufora” i glVertexAttribPointer () ustawia format danych bufora, a także zapisuje powiązanie obiektu bufora jako część stanu tablicy atrybutów wierzchołków.
Trudna rzecz, której nie jestem pewien, polega na tym, że funkcja glVertexAttribPointer () pozostaje ważna, jeśli „magazyn danych obiektu bufora” (ale nie sam obiekt bufora) zostanie zdmuchnięty przez nowe wywołanie funkcji glBufferData (). Zdaję sobie sprawę, że zwykle nie jest to dobry pomysł - używaj glBufferSubData (), gdy tylko przepisujesz bufory - ale glBufferData () wydaje się być jedyną opcją, jeśli trzeba zmienić jej rozmiar. Poza tym jestem po prostu ciekawy.
Strony referencyjne sprawiają, że brzmi to tak, jakby mogło to pójść w obie strony - w szczególności (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):
Jeśli wskaźnik nie ma wartości NULL, niezerowy nazwany obiekt bufora musi być powiązany z celem GL_ARRAY_BUFFER (patrz glBindBuffer ), w przeciwnym razie zostanie wygenerowany błąd. wskaźnik jest traktowany jako przesunięcie bajtów do magazynu danych obiektu bufora. Powiązanie obiektu buforu (GL_ARRAY_BUFFER_BINDING) jest zapisywane jako ogólny stan tablicy atrybutów wierzchołków (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) dla indeksu .
Gdy zostanie określona ogólna tablica atrybutów wierzchołków, rozmiar , typ , znormalizowany , krok i wskaźnik są zapisywane jako stan tablicy wierzchołków, oprócz bieżącego powiązania obiektu buforu tablicy wierzchołków.
Wygląda na to, że zarówno przesunięcie bajtów, jak i powiązanie obiektu bufora mogą pozostać ważne, nawet jeśli magazyn danych został zastąpiony czymś innym. Ale widziałem również, że jest implementowany w taki sposób, że w momencie wywołania powiązanie przechwytuje określony wskaźnik do magazynu danych, który zostaje unieważniony, jeśli magazyn danych zostanie zastąpiony. Sformułowanie nie wydaje się wykluczać żadnej z tych możliwości.
Odpowiedzi
Wygląda na to, że powiązania glVertexAttribPointer () pozostają ważne, nawet po kolejnych wywołaniach funkcji glBufferData (). Ustaliłem to, próbując tego, co nie jest 100% dowodem - może po prostu działać tylko w tej implementacji (w moim przypadku sterowniki NVidia).
Jednak przy włączonym wywołaniu zwrotnym komunikatu o błędzie i trybie debugowania otrzymuję następujący komunikat po drugim wywołaniu funkcji glBufferData (), co zdecydowanie sugeruje, że ta sytuacja jest oczekiwana / zaprojektowana dla:
[LWJGL] Komunikat debugowania OpenGL
Identyfikator: 0x20071
Źródło: API
Typ: INNE
Waga: POWIADOMIENIE
Komunikat: Szczegółowe informacje o buforze: Obiekt bufora 1 (powiązany z GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) i GL_ARRAY_BUFFER_ARB, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) i GL_ARRAY_BUFFER_ARB, wskazówka dotycząca użycia to GL_ST jako pamięć bufora).
Pierwsze dwa powiązania reprezentują moje dwa wywołania funkcji glVertexAttribPointer () i nie są obecne w komunikacie, który jest rejestrowany przy pierwszym wywołaniu funkcji glBufferData ().