webGL: vertexAttribPointer 函式理解

undefined 發表於 2022-03-07
WebGL

MDN官方定義

告訴顯示卡從當前繫結的緩衝區(bindBuffer()指定的緩衝區)中讀取頂點資料。

語法

void gl.vertexAttribPointer(index, size, type, normalized, stride, offset);

引數

  • index
    指定要修改的頂點屬性的索引
  • size
    指定每個頂點屬性的組成數量,必須是1,2,3或4。
  • type
    指定陣列中每個元素的資料型別
  • normalized
    當轉換為浮點數時是否應該將整數數值歸一化到特定的範圍
  • stride
    一個GLsizei,以位元組為單位指定連續頂點屬性開始之間的偏移量(即陣列中一行長度)。不能大於255。如果stride為0,則假定該屬性是緊密打包的,即不交錯屬性,每個屬性在一個單獨的塊中,下一個頂點的屬性緊跟當前頂點之後。
  • offset
    GLintptr (en-US)指定頂點屬性陣列中第一部分的位元組偏移量。必須是型別的位元組長度的倍數

理解

為什麼使用vertexAttribPointer

如果需要修改頂點位置和顏色, 那麼需要建立兩個緩衝區。而使用vertexAttribPointer 可以存多種資料,不同資料間通過偏移來區分,這樣就可以只需要一個緩衝區資料了。

引數理解

  • index
    通過gl.getAttribLocation(gl.program, "a_Position")方法可以返回a_Position屬性的索引,這就是index需要的資料
  • size
    你需要取幾個資料。
    例如:

     const verties = new Float32Array([
        0.0, 0.5, -0.4, 0.19607843137254902, 0.8431372549019608, 0.8745098039215686, -0.5, -0.5, -0.4, 0.4, 1.0, 0.4, 0.5,
        -0.5, -0.4, 1.0, 0.4, 0.4, 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, -0.5, 0.4,
        -0.2, 1.0, 1.0, 0.4, 0.0, -0.6, -0.2, 1.0, 1.0, 0.4, 0.0, 0.5, 0.0, 0.4,
        0.4, 1.0, -0.5, -0.5, 0.0, 0.4, 0.4, 1.0, 0.5, -0.5, 0.0, 1.0, 0.4, 0.4,
      ]);

    如果引數設定為3, 那就是說需要3個資料。

  • type
    指定資料型別,gl.FLOAT, gl.BYTE等等資料型別,一般為gl.FLOAT
  • normalized
    對於引數gl.FLOAT無效
  • stride
    設定偏移量, 首先拿到const FSIZE = verties.BYTES_PER_ELEMENT, 也就是陣列的位元組長度,偏移量必須是位元組長的的倍數。

關鍵步驟, 設定每次拿資料時的間隔,還是拿上面的資料為例,設定為1*FSIZE,則取的資料為:

`0.0, 0.5, -0.4`, 
`0.5, -0.4, 0.19607843137254902`, 
`-0.4, 0.19607843137254902, 0.8431372549019608,`

如果設定為3*FSIZE, 則取的資料為:
0.0, 0.5, -0.4,
0.19607843137254902, 0.8431372549019608, 0.8745098039215686,
-0.5, -0.5, -0.4

  • offset
    需要配合上一個引數理解,
    例如: gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 3*FSIZE);

    首先一次拿去6個資料,其中需要的是偏移3個單位的資料,再加上size等於3,所以可以確認所拿的資料是後3個,

    比如第一次拿6個單位資料:
    0.0, 0.5, -0.4, 0.19607843137254902, 0.8431372549019608, 0.8745098039215686

    這次正真拿到的則是0.19607843137254902, 0.8431372549019608, 0.8745098039215686