Dizin arabelleği nedir ve köşe arabelleği ile nasıl ilişkilidir?


11

Ben böyle bir tepe tamponu var:

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

Aşağıdaki dizin arabelleği var:

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

gl.LINESWebGL kullanarak çizim yapmak istediğimi biliyorum , birden fazla ayrılmış çizgi parçası anlamına geliyor.

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

WebGL'de tek bir çizim çağrısında birden çok çizgi parçasının çizimini etkinleştiriyor gibi görünüyor.

Birisi bana ELI5 olabilir, bir dizin tamponu nedir ve köşe tamponları ile nasıl ilişkilidir? Temel öğelerimden dizin arabellekleri nasıl oluşturulur?

Yanıtlar:


12

Birisi bana ELI5 olabilir, bir dizin tamponu nedir ve köşe tamponları ile nasıl ilişkilidir

Köşe arabelleğiniz, 5 köşenin X ve Y koordinatlarını içerir. Onlar:

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

Dizin arabelleğiniz, bu köşeler arasında hangi çizgilerin çizileceği hakkında bilgi içerir. Bir değer olarak köşe arabelleğindeki her bir tepe noktasının dizinini kullanır.

Çizgi çizdiğiniz için dizin arabelleğinizdeki birbirini takip eden her bir değer çifti bir çizgi segmentini gösterir. Örneğin, birlikte endeks tampon başlar eğer 0, 2, bu durumda giden bir çizgi çizin olur köşe dizideki 0 ve 2. köşeler, arasında bir çizgi çizmek anlamına [0.0, 0.0]etmek [0.0, 0.6].

Aşağıdaki grafikte her bir indeks çifti, belirttiği çizgiyle renk koordinasyonuna sahiptir:

resim açıklamasını buraya girin

Benzer şekilde, çizgiler yerine üçgenler çiziyorsanız, ardışık her 3 değerin köşe arabelleğindeki üç köşenin indekslerini gösterdiği bir dizin tamponu sağlamanız gerekir;

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

5

Bunun gibi bir tepe tamponu varsa:

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
]

Ve sadece olduğu gibi çizin:

// 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);

Her bir çizgi segmenti için iki tahsis edilmiş koordinat gerektirir. İle verticesyukarıda tanımlandığı gibi, sadece mümkün olacağını iki çizmek iki satır :

iki çizgi

Aşağıdaki dizinleri tanımladıysanız:

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

Aynı köşeleri tekrar tekrar kesişen çizgiler çizmek mümkündür. Bu fazlalığı azaltır. Dizin arabelleğini bağlar ve GPU'ya, köşeleri dizin dizisinde belirtilen sıraya göre bağlayan çizgi parçaları çizmesini söylerseniz:

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);

Aynı köşeleri tekrar tekrar tanımlamadan karmaşık şekiller çizilebilir. Sonuç budur:

bir ev

Endeks olmadan aynı sonucu elde etmek için köşe arabelleği aşağıdaki gibi görünmelidir:

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);

Aynı görüntüde sonuçlanan:

yine başka bir ev

Saklanan köşe noktalarındaki büyük yedekliliğe dikkat edin.


2
Kendi sorunuzu hemen cevaplamayı planlıyorsanız, lütfen en azından soruda belirtin, böylece diğerleri zamanlarını boşa harcamaz.
Rotem

2
Her iyi sorunun 2 veya 3 iyi cevabı olmalıdır. Zamanını boşa harcamadın ve ben senin çabalarını gerçekten takdir ettim. Bir proje ortağına mantığı açıklamak için bu konuya ihtiyacım var ve mesajınız ona çok yardımcı olacaktır.
Afr

1
@ 5chdn Kendi kendine yanıtlama çok teşvik edilir . Bu yanıtı eklediğiniz için teşekkür ederiz. Bir soruyu gönderirken bir cevabınız varsa, sorunun altında soruyu göndermeden önce cevabınızı yazmanıza izin verecek bir onay kutusu vardır, böylece her ikisi de aynı anda görünecektir. Bu sadece yararlı olması durumunda sizi bilgilendirmek içindir - kesinlikle bunu yapmanız gerekmez ve kendi cevapları soruyu gönderdikten sonra herhangi bir zaman diliminde hala çok hoş karşılanır.
trichoplax
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.