Co to jest bufor indeksu i jak jest on powiązany z buforami wierzchołków?

11

Mam bufor wierzchołków taki jak ten:

0.0, 0.0,
1.0, 0.0,
0.0, 0.6,
1.0, 0.6,
0.5, 1.0

Mam następujący bufor indeksu:

0, 2,
2, 4,
4, 3,
3, 2,
2, 1,
1, 0,
0, 3,
3, 1

Wiem, że chcę rysować gl.LINESza pomocą WebGL, co oznacza wiele oddzielnych segmentów linii.

gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, indexBuffer);

Wydaje się, że umożliwia rysowanie wielu segmentów linii w jednym wywołaniu rysowania w WebGL.

Czy ktoś może dla mnie ELI5, czym jest bufor indeksu i jak jest on powiązany z buforami wierzchołków? Jak wygenerować bufory indeksu z moich prymitywów?

Afr
źródło

Odpowiedzi:

12

Czy ktoś mógłby mi ELI5, co to jest bufor indeksu i jak to jest powiązane z buforami wierzchołków

Bufor wierzchołków zawiera współrzędne X i Y 5 wierzchołków. Oni są:

index |  X  |  Y
  0   | 0.0 | 0.0 
  1   | 1.0 | 0.0
  2   | 0.0 | 0.6
  3   | 1.0 | 0.6
  4   | 0.5 | 1.0

Bufor indeksu zawiera informacje o tym, które linie narysować między tymi wierzchołkami. Używa indeksu każdego wierzchołka w buforze wierzchołków jako wartości.

Ponieważ rysujesz linie, każda para kolejnych wartości w buforze indeksu wskazuje segment linii. Na przykład, jeśli bufor indeksu zaczyna się od 0, 2, oznacza to, że narysuje linię między 0 a 2 wierzchołkami w tablicy wierzchołków, co w tym przypadku narysuje linię przechodzącą od [0.0, 0.0]do [0.0, 0.6].

Na poniższej grafice każda para wskaźników jest skoordynowana kolorystycznie z linią, którą wskazuje:

wprowadź opis zdjęcia tutaj

Podobnie, jeśli rysujesz trójkąty zamiast linii, musisz podać bufor indeksu, w którym każda z 3 kolejnych wartości wskazuje wskaźniki trzech wierzchołków w buforze wierzchołków, np.

0, 1, 2,
2, 1, 3,
2, 3, 4,
Rotem
źródło
5

Jeśli masz taki bufor wierzchołków:

var vertices = [
  0.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.5, 1.0, 0.0
]

I po prostu narysuj go takim, jakim jest:

// Create an empty buffer object
var vertex_buffer = gl.createBuffer();

// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 5);

Wymagałoby to dwóch dedykowanych współrzędnych dla każdego segmentu linii. Przy verticeszdefiniowanym powyżej, możliwe byłyby tylko dwa narysowanie dwóch linii :

dwie linie

Jeśli zdefiniowano następujące wskaźniki:

var indices = [
  0, 2,
  2, 4,
  4, 3,
  3, 2,
  2, 1,
  1, 0,
  0, 3,
  3, 1
]

Możliwe jest rysowanie linii, które przecinają te same wierzchołki raz za razem. Zmniejsza to nadmiarowość. Jeśli powiążesz bufor indeksu i powiesz GPU, aby narysował segmenty linii łączące wierzchołki w kolejności określonej w tablicy indecies:

var index_buffer = gl.createBuffer();

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

// draw geometry lines by indices
gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, index_buffer);

Można rysować bardziej złożone figury bez ponownego definiowania tych samych wierzchołków. Oto wynik:

Dom

Aby osiągnąć ten sam wynik bez indeksów, bufor wierzchołków powinien wyglądać następująco:

var vertices = [
  0.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.5, 1.0, 0.0,
  0.5, 1.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.0, 0.0
]

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 16);

Co daje ten sam obraz:

jeszcze inny dom

Zwróć uwagę na ogromną redundancję w przechowywanych wierzchołkach.

Afr
źródło
2
Jeśli planujesz od razu odpowiedzieć na swoje pytanie, proszę przynajmniej wspomnieć o nim w pytaniu, aby inni nie marnowali czasu.
Rotem,
2
Każde dobre pytanie powinno mieć 2 lub 3 dobre odpowiedzi. Nie marnowałeś czasu i naprawdę doceniałem twoje wysiłki. Potrzebuję tego wątku, aby wyjaśnić logikę partnerowi projektu, a twój post pomoże mu bardzo dużo.
Afr
1
@ 5chdn Zachęcamy do samodzielnego udzielania odpowiedzi . Dziękujemy za dodanie tej odpowiedzi. Jeśli masz na myśli odpowiedź w momencie publikowania pytania, pod pytaniem znajduje się pole wyboru, które pozwoli Ci napisać odpowiedź przed opublikowaniem pytania, więc oba pojawią się w tym samym czasie. Ma to na celu poinformowanie, że jest to przydatne - na pewno nie musisz tego robić, a odpowiedzi na pytania są nadal mile widziane w dowolnym czasie po opublikowaniu pytania.
trichoplax