WebGL - Geometri

WebGL bağlamını elde ettikten sonra, ilkel (çizmek istediğiniz nesne) için geometriyi tanımlamanız ve saklamanız gerekir. WebGL'de, JavaScript dizilerini kullanarak bir geometrinin ayrıntılarını (örneğin, köşeler, indeksler, ilkel renk) tanımlarız. Bu ayrıntıları gölgelendirici programlarına geçirmek için, arabellek nesnelerini oluşturmalı ve verileri içeren JavaScript dizilerini ilgili arabelleklerde depolamalı (eklemeliyiz).

Note: Daha sonra bu arabellek nesneleri, gölgelendirici programının (köşe gölgelendiricisi) öznitelikleriyle ilişkilendirilecektir.

Gerekli Geometriyi Tanımlama

Köşeler kullanılarak çizilen bir 2B veya 3B model, mesh. Bir ağdaki her fasete birpolygon ve bir çokgen 3 veya daha fazla noktadan oluşur.

WebGL oluşturma bağlamında modeller çizmek için, JavaScript dizilerini kullanarak köşeleri ve dizinleri tanımlamanız gerekir. Örneğin, diyagramda gösterildiği gibi {(5,5), (-5,5), (-5, -5)} koordinatlarında yer alan bir üçgen oluşturmak istiyorsak, o zaman için bir dizi oluşturabilirsiniz köşeler -

var vertices = [
   0.5,0.5,    //Vertex 1
   0.5,-0.5,   //Vertex 2
   -0.5,-0.5,  //Vertex 3
];

Benzer şekilde, indisler için bir dizi oluşturabilirsiniz. Yukarıdaki üçgen indislerin indisleri [0, 1, 2] olacaktır ve şu şekilde tanımlanabilir -

var indices = [ 0,1,2 ]

Endeksleri daha iyi anlamak için kare gibi daha karmaşık modelleri düşünün. Bir kareyi iki üçgenden oluşan bir set olarak temsil edebiliriz. (0,3,1) ve (3,1,2) bir kare çizmeyi düşündüğümüz iki üçgen ise, indisler şu şekilde tanımlanacaktır:

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

Note -

Temel çizimleri çizmek için WebGL şu iki yöntemi sağlar:

  • drawArrays() - Bu yöntemi kullanırken JavaScript dizilerini kullanarak ilkel olanın köşelerini geçiyoruz.

  • drawElements() - Bu yöntemi kullanırken JavaScript dizisini kullanarak ilkelin hem köşelerini hem de dizinlerini geçiririz.

Tampon Nesneleri

Bir arabellek nesnesi, WebGL tarafından sağlanan ve sistemde ayrılmış bir bellek alanını gösteren bir mekanizmadır. Bu tampon nesnelerinde, çizmek istediğiniz modelin verilerini köşelere, indekslere, renge vb. Karşılık gelen verileri depolayabilirsiniz.

Bu arabellek nesnelerini kullanarak, birden çok veriyi, öznitelik değişkenlerinden biri aracılığıyla gölgelendirici programına (köşe gölgelendiricisi) iletebilirsiniz. Bu arabellek nesneleri GPU belleğinde bulunduğundan, doğrudan işlenebilir ve bu da performansı artırır.

Geometriyi işlemek için iki tür tampon nesne vardır. Onlar -

  • Vertex buffer object (VBO)- Oluşturulacak grafik modelin tepe başına verilerini tutar. Köşe koordinatları, normaller, renkler ve doku koordinatları gibi köşelerle ilgili verileri depolamak ve işlemek için WebGL'de köşe arabelleği nesneleri kullanıyoruz.

  • Index buffer objects (IBO) - Oluşturulacak grafik modelin indekslerini (indeks verilerini) tutar.

Gerekli geometriyi tanımladıktan ve bunları JavaScript dizilerinde depoladıktan sonra, bu dizileri, verilerin gölgelendirici programlarına aktarılacağı tampon nesnelere geçirmeniz gerekir. Verileri tamponlarda saklamak için aşağıdaki adımlar izlenmelidir.

  • Boş bir arabellek oluşturun.

  • Uygun bir dizi nesnesini boş arabelleğe bağlayın.

  • Verileri (köşeler / indeksler) aşağıdakilerden birini kullanarak tampona geçirin. typed arrays.

  • Arabelleği ayırın (İsteğe bağlı).

Bir Tampon Oluşturmak

Boş bir arabellek nesnesi oluşturmak için WebGL, createBuffer(). Oluşturma başarılı olursa, bu yöntem yeni oluşturulmuş bir tampon nesnesi döndürür; aksi takdirde başarısızlık durumunda boş bir değer döndürür.

WebGL bir durum makinesi olarak çalışır. Bir tampon oluşturulduktan sonra, biz onu çözene kadar herhangi bir sonraki tampon işlemi geçerli tampon üzerinde yürütülecektir. Bir arabellek oluşturmak için aşağıdaki kodu kullanın -

var vertex_buffer = gl.createBuffer();

Note - gl geçerli WebGL bağlamına referans değişkendir.

Arabelleği Bağla

Boş bir tampon nesnesi oluşturduktan sonra, ona uygun bir dizi tamponunu (hedef) bağlamanız gerekir. WebGL,bindBuffer() bu amaç için.

Sözdizimi

Sözdizimi bindBuffer() yöntem aşağıdaki gibidir -

void bindBuffer (enum target, Object buffer)

Bu yöntem iki parametreyi kabul eder ve aşağıda tartışılmıştır.

target- İlk değişken, boş arabelleğe bağlamak istediğimiz arabellek türünü temsil eden bir enum değeridir. Bu parametre için seçenekler olarak önceden tanımlanmış iki enum değeriniz vardır. Onlar -

  • ARRAY_BUFFER köşe verilerini temsil eden.

  • ELEMENT_ARRAY_BUFFER indeks verilerini temsil eder.

Object buffer- İkincisi, önceki adımda oluşturulan tampon nesnesinin referans değişkenidir. Referans değişkeni, bir köşe tampon nesnesi veya bir indeks tampon nesnesi olabilir.

Misal

Aşağıdaki kod parçacığı, bindBuffer () yönteminin nasıl kullanılacağını gösterir.

//vertex buffer
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

//Index buffer
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

Verileri Arabelleğe Aktarma

Bir sonraki adım, verileri (köşeler / indeksler) tampona iletmektir. Şimdiye kadar veriler bir dizi biçimindedir ve tampona aktarmadan önce, WebGL türü dizilerden birine sarmamız gerekir. WebGL,bufferData() bu amaç için.

Sözdizimi

BufferData () yönteminin sözdizimi aşağıdaki gibidir -

void bufferData (enum target, Object data, enum usage)

Bu yöntem üç parametreyi kabul eder ve aşağıda tartışılmıştır -

target - İlk parametre, kullandığımız dizi tamponunun türünü temsil eden bir enum değeridir.Bu parametrenin seçenekleri şunlardır -

  • ARRAY_BUFFER temsil eden vertex data.

  • ELEMENT_ARRAY_BUFFER temsil eden index data.

Object data- İkinci parametre, tampon nesneye yazılacak verileri içeren nesne değeridir. Burada verileri kullanarak geçmek zorundayıztyped arrays.

Usage- Bu yöntemin üçüncü parametresi, şekil çizmek için tampon nesne verilerinin (depolanan veriler) nasıl kullanılacağını belirten bir enum değişkenidir. Bu parametre için aşağıda listelendiği gibi üç seçenek vardır.

  • gl.STATIC_DRAW - Veriler bir kez belirtilecek ve birçok kez kullanılacaktır.

  • gl.STREAM_DRAW - Veriler bir kez belirtilecek ve birkaç kez kullanılacaktır.

  • gl.DYNAMIC_DRAW - Veriler tekrar tekrar belirtilecek ve birçok kez kullanılacaktır.

Misal

Aşağıdaki kod parçacığı, nasıl kullanılacağını gösterir. bufferData()yöntem. Köşelerin ve dizinlerin sırasıyla köşe ve dizin verilerini tutan diziler olduğunu varsayalım.

//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

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

Yazılan Diziler

WebGL, adı verilen özel bir dizi türü sağlar typed arraysdizin tepe noktası ve doku gibi veri öğelerini aktarmak için. Bu tip diziler büyük miktarda veriyi depolar ve bunları yerel ikili biçimde işler, bu da daha iyi performans sağlar. WebGL tarafından kullanılan tiplenmiş diziler Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array ve Float64Array'dir.

Note

  • Genel olarak, köşe verilerini depolamak için kullanırız Float32Array; ve indeks verilerini saklamak için kullanıyoruzUint16Array.

  • Tıpkı JavaScript dizileri gibi yazılan diziler oluşturabilirsiniz. new anahtar kelime.

Tamponları Çöz

Arabellekleri kullandıktan sonra çözmeniz önerilir. Aşağıda gösterildiği gibi, tampon nesnesi yerine boş bir değer iletilerek yapılabilir.

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

WebGL, arabellek işlemlerini gerçekleştirmek için aşağıdaki yöntemleri sağlar -

Sr.No. Yöntemler ve Açıklama
1

geçersiz bindBuffer(enum hedefi , Nesne arabelleği )

hedef - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

2

geçersiz bufferData(enum hedefi , uzun boyut , enum kullanımı )

hedef - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

kullanım - STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW

3

geçersiz bufferData(enum hedefi , Nesne verileri , enum kullanımı )

hedef ve kullanım - ile aynıbufferData yukarıda

4

geçersiz bufferSubData(enum hedefi , uzun uzaklık , Nesne verileri )

hedef - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

5 Nesne createBuffer()
6 geçersiz deleteBuffer(Nesne tamponu )
7

hiç getBufferParameter(enum hedefi , enum pname )

hedef - ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname - BUFFER_SIZE, BUFFER_USAGE

8 bool isBuffer(Nesne tamponu )