What is the logic for binding buffers in webgl?

I sometimes struggle between declaring buffers (with createBuffer / bindBuffer / bufferdata) in a different order and re-linking them in other parts of the code, usually in the drawing chain.

If I do not double-check the vertex buffer before drawing arrays, the console complains about trying to access the vertices of the range. My suspect is that the last related object is passed by pointer and then to drawarrays, but when I reorder at the beginning of the code, nothing changes. Effective work is reordering a buffer in a drawing loop. Therefore, I cannot understand the logic of this. When do you need to reinstall? Why do you need to reinstall? What is attribute0 referring to?

+4
source share
1 answer

I do not know if this will help. As some people have said, GL / WebGL has a bunch of internal state . All functions that you call set the state. When all settings you call drawArraysor drawElements, and all this state is used to draw things

This is explained elsewhere on SO, but the buffer binding just sets 1 out of 2 global variables inside WebGL. After that, you refer to the buffer by its anchor point.

You can think of it this way:

gl = function() {
   // internal WebGL state
   let lastError;
   let arrayBuffer = null;
   let vertexArray = {
     elementArrayBuffer: null,
     attributes: [
       { enabled: false, type: gl.FLOAT, size: 3, normalized: false, 
         stride: 0, offset: 0, value: [0, 0, 0, 1], buffer: null },
       { enabled: false, type: gl.FLOAT, size: 3, normalized: false, 
         stride: 0, offset: 0, value: [0, 0, 0, 1], buffer: null },
       { enabled: false, type: gl.FLOAT, size: 3, normalized: false, 
         stride: 0, offset: 0, value: [0, 0, 0, 1], buffer: null },
       { enabled: false, type: gl.FLOAT, size: 3, normalized: false, 
         stride: 0, offset: 0, value: [0, 0, 0, 1], buffer: null },
       { enabled: false, type: gl.FLOAT, size: 3, normalized: false, 
         stride: 0, offset: 0, value: [0, 0, 0, 1], buffer: null },
       ...
     ],
   }
   ...

   // Implementation of gl.bindBuffer. 
   // note this function is doing nothing but setting 2 internal variables.
   this.bindBuffer = function(bindPoint, buffer) {
     switch(bindPoint) {
       case gl.ARRAY_BUFFER;
         arrayBuffer = buffer;
         break;
       case gl.ELEMENT_ARRAY_BUFFER;
         vertexArray.elementArrayBuffer = buffer;
         break;
       default:
         lastError = gl.INVALID_ENUM;
         break;
     }
   };
...
}();

After that, other WebGL functions reference them. For example, it gl.bufferDatacan do something like

   // implementation of gl.bufferData
   // Notice you don't pass in a buffer. You pass in a bindPoint. 
   // The function gets the buffer one of its internal variable you set by
   // previously calling gl.bindBuffer

   this.bufferData = function(bindPoint, data, usage) {

     // lookup the buffer from the bindPoint
     var buffer;
     switch (bindPoint) {
       case gl.ARRAY_BUFFER;
         buffer = arrayBuffer;
         break;
       case gl.ELEMENT_ARRAY_BUFFER;
         buffer = vertexArray.elemenArrayBuffer;
         break;
       default:
         lastError = gl.INVALID_ENUM;
         break;
      }

      // copy data into buffer
      buffer.copyData(data);  // just making this up
      buffer.setUsage(usage); // just making this up
   };

. . , . gl.getAttribLocation(someProgram, "nameOfAttribute") , .

, 4 , , . gl.enableVertexAttribArray, gl.disableVertexAttribArray, gl.vertexAttribPointer gl.vertexAttrib??.

-

this.enableVertexAttribArray = function(location) {
  const attribute = vertexArray.attributes[location];
  attribute.enabled = true;  // true means get data from attribute.buffer 
};

this.disableVertexAttribArray = function(location) {
  const attribute = vertexArray.attributes[location];
  attribute.enabled = false; // false means get data from attribute.value
};

this.vertexAttribPointer = function(location, size, type, normalized, stride, offset) {
  const attribute = vertexArray.attributes[location];
  attribute.size       = size;       // num values to pull from buffer per vertex shader iteration
  attribute.type       = type;       // type of values to pull from buffer
  attribute.normalized = normalized; // whether or not to normalize
  attribute.stride     = stride;     // number of bytes to advance for each iteration of the vertex shader. 0 = compute from type, size
  attribute.offset     = offset;     // where to start in buffer.

  // IMPORTANT!!! Associates whatever buffer is currently *bound* to 
  // "arrayBuffer" to this attribute
  attribute.buffer     = arrayBuffer;
};

this.vertexAttrib4f = function(location, x, y, z, w) {
  const attribute = vertexArray.attributes[location];
  attribute.value[0] = x;
  attribute.value[1] = y;
  attribute.value[2] = z;
  attribute.value[3] = w;
};

, gl.drawArrays gl.drawElements, , , , . . , .

, , , drawElements drawArrays, , . # 1 # 2 , 3 , 6 gl.drawArrays, . , , gl.ELEMENT_ARRAY_BUFFER, , > 2, index out of range. 3 , 0, 1 2.

, , - , , . ? , , , , , , . , . , , , . , , , . , , , .

, , , . , 10 . , , , , , .

, [ OES_vertex_array_object], WebGL 2.0. Vertex Array - , vertexArray, elementArrayBuffer .

gl.createVertexArray . gl.bindVertexArray attributes , .

gl.bindVertexArray

 this.bindVertexArray = function(vao) {
   vertexArray = vao ? vao : defaultVertexArray;
 }    

, init, 1 WebGL .

+14

All Articles