Javascript 如何为不同的属性使用不同的缓冲区

Javascript 如何为不同的属性使用不同的缓冲区,javascript,webgl,Javascript,Webgl,我正在学习WebGL,并且一直在理解如何将数据传递给属性 drawArrays:没有缓冲区绑定到enabled属性 这是我收到的警告,但是如果我禁用一个vertexAttrib ,此警告消失,但屏幕上仍然没有任何内容 我做错了什么 这是我的着色器 const vsSource = ` attribute vec4 a_position; attribute vec4 a_color; varying vec4 v_color; void main() { gl_Position = a_p

我正在学习WebGL,并且一直在理解如何将数据传递给属性

drawArrays:没有缓冲区绑定到enabled属性 这是我收到的警告,但是如果我禁用一个vertexAttrib

,此警告消失,但屏幕上仍然没有任何内容

我做错了什么

这是我的着色器

const vsSource = `
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;

void main() {
  gl_Position = a_position;
  v_color = a_color;
}
`;

const fsSource = `
precision mediump float;
varying vec4 v_color;

void main() {
  gl_FragColor = v_color;
}
`;
我的下一步: 1) 获取gl上下文

const canvas = document.querySelector('#glCanvas'); 
gl = canvas.getContext('webgl');
2) 创建着色器

function createShader(type, source) {
  var shader = gl.createShader(type);   // create shader
  gl.shaderSource(shader, source);      // set to shader his code
  gl.compileShader(shader);             // compile shader
  var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (success) {
    return shader;
  }

  console.log(gl.getShaderInfoLog(shader));
  gl.deleteShader(shader);
}
  const vShader = createShader(gl.VERTEX_SHADER, vsSource)
  const fShader = createShader(gl.FRAGMENT_SHADER, fsSource)
3) 创建程序并附加着色器,链接它们

var program = gl.createProgram();
  checkGlError()
  gl.attachShader(program, vShader); 
  gl.attachShader(program, fShader);
  gl.linkProgram(program); 

  if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) {
    var info = gl.getProgramInfoLog(program);
    throw 'Could not compile WebGL program. \n\n' + info;
  }
4) 获取对属性的引用

var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
  var colorAttributeLocation = gl.getAttribLocation(program, "a_color");
5) 创建缓冲区并绑定数据

  var positionBuffer = gl.createBuffer()
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
  setRectangle(gl)

  var colorBuffer = gl.createBuffer()
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
  setColors(gl)

function setRectangle(gl) {
  let x = randomFloat()
  let y = randomFloat()
  let width = randomFloat()
  let height = randomFloat()

  let x1 = x;
  let x2 = x + width;
  let y1 = y;
  let y2 = y + height;

  let positions = [
    x1, y1,
    x2, y1,
    x1, y2,
    x1, y2,
    x2, y1,
    x2, y2
  ]
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
}
function setColors(gl) {
  var r1 = Math.random();
  var b1 = Math.random();
  var g1 = Math.random();

  var r2 = Math.random();
  var b2 = Math.random();
  var g2 = Math.random();

  gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array(
        [ r1, b1, g1, 1,
          r1, b1, g1, 1,
          r1, b1, g1, 1,
          r2, b2, g2, 1,
          r2, b2, g2, 1,
          r2, b2, g2, 1]),
      gl.STATIC_DRAW);
}
6) 画场景

  gl.viewport(0,0,gl.canvas.width,gl.canvas.height)

  gl.clearColor(78/255.0,159/255.0,255/255.0,1.0)
  gl.clear(gl.COLOR_BUFFER_BIT)

  gl.useProgram(program)

  gl.enableVertexAttribArray(positionAttributeLocation)

  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)

  var size = 2
  var type = gl.FLOAT
  var normalize = false
  var stride = 0
  var offset = 0

  gl.vertexAttribPointer(
    positionBuffer,
    size,
    type,
    normalize,
    stride,
    offset)

    gl.enableVertexAttribArray(colorAttributeLocation)
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)

    var size = 4
    var type = gl.FLOAT
    var normalize = false
    var stride = 0
    var offset = 0

    gl.vertexAttribPointer(
      colorBuffer,
      size,
      type,
      normalize,
      stride,
      offset)


    let verticiesCounter = 6;
    var drawingOffset = 0;

    gl.drawArrays(gl.TRIANGLES, drawingOffset , verticiesCounter)

VertexAttributePointer
的第一个参数必须是通用顶点属性的索引,而不是缓冲区对象。
注意,
VertexAttributePointer
指定通用顶点属性的数据,因此必须在某处指定索引。 如果命名缓冲区对象绑定到目标
ARRAY\u buffer
,则此缓冲区中的数据就是数据源

看到和

这意味着您必须像这样更改代码:

gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
gl.vertexAttribPointer(
    positionAttributeLocation, // instead of positionBuffer
    size,
    type,
    normalize,
    stride,
    offset)

.....

gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.vertexAttribPointer(
    colorAttributeLocation, // instead of colorBuffer
    size,
    type,
    normalize,
    stride,
    offset)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
gl.vertexAttribPointer(
    positionAttributeLocation, // instead of positionBuffer
    size,
    type,
    normalize,
    stride,
    offset)

.....

gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.vertexAttribPointer(
    colorAttributeLocation, // instead of colorBuffer
    size,
    type,
    normalize,
    stride,
    offset)