为什么我在 WebGL 中添加了 color 属性后,我的代码就断了?

问题描述 投票:1回答:1

出于某种原因,尽管我想让它绘制9999个(出于测试原因)矩形,但我的代码中什么都没有显示。

const canvas = document.getElementById("canvas");
const vertexCode = `
precision mediump float;

attribute vec4 position;
uniform mat4 matrix;
attribute vec4 color;
varying vec4 col;

void main() {
  col = color;
  gl_Position = matrix * position;
}
`;
const fragmentCode = `
precision mediump float;

varying vec4 col;

void main() {
  gl_FragColor = vec4(1, 0, 0, 1);
}
`;
const width = canvas.width;
const height = canvas.height;
const gl = canvas.getContext("webgl");
if(!gl) {
  console.log("WebGL not supported");
}
const projectionMatrix = [
  2/width, 0, 0, 0,
  0, -2/height, 0, 0,
  0, 0, 1, 0,
  -1, 1, 0, 1
];


const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexCode);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentCode);
gl.compileShader(fragmentShader);

const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

gl.linkProgram(program);

gl.useProgram(program);

const positionBuffer = gl.createBuffer();
const colorBuffer = gl.createBuffer();
const positionLocation = gl.getAttribLocation(program, "position");
const colorLocation = gl.getAttribLocation(program, `color`);
const projectionLocation = gl.getUniformLocation(program, `matrix`);
gl.enableVertexAttribArray(positionLocation);
const vertex = [
    0, 0, 0, 1,
    0, 0, 0, 1,
    0, 0, 0, 1,
    0, 0, 0, 1
  ]
const floatArray = new Float32Array(vertex);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLocation, 4, gl.FLOAT, false, 0, 0);

gl.enableVertexAttribArray(colorLocation);
const color = [
  1, 0, 0, 1,
  1, 0, 0, 1,
  1, 0, 0, 1,
  1, 0, 0, 1
]
const colorArray = new Float32Array(color);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);

gl.uniformMatrix4fv(projectionLocation, false, projectionMatrix);
function rect(x, y, w, h) {
  floatArray[0] = x;
  floatArray[1] = y;
  floatArray[4] = x + w;
  floatArray[5] = y;
  floatArray[8] = x;
  floatArray[9] = y + h;
  floatArray[12] = x + w;
  floatArray[13] = y + h;

  gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.DYNAMIC_DRAW);
  gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.DYNAMIC_DRAW);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

}
function fill(r, g, b, a) {
  colorArray[0] = r;
  colorArray[1] = g;
  colorArray[2] = b;
  colorArray[3] = a;
  // gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.DYNAMIC_DRAW);
}
let lastTime = 0;
let fpsText = document.getElementById("fps");
function animate(currentTime) {
  fpsText.textContent = (1000 / (currentTime - lastTime)).toFixed(1);
  lastTime = currentTime;
  for(let i=0;i<9999;i++) {
    fill(random(0, 1), random(0, 1), random(0, 1), 1);
    rect(random(0, 800), random(0, 600), 10, 10);
  }
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
function random(low, high) {
  return low + Math.random() * (high-low)
}

因此,当我没有添加颜色属性时,一切都很正常。然而,当我输入以下代码时,一切都开始中断了 gl.enableVertexAttribArray(colorLocation); 而画布上什么也没有显示。你们能帮我找到我的错误吗?非常感谢。

javascript webgl
1个回答
-1
投票

当我运行你的代码时,在JavaScript控制台中得到一个明显的错误信息

[.WebGL-0x7fae86814200]GL ERROR :GL_INVALID_OPERATION : glDrawArrays: 试图访问属性0中超出范围的顶点。

从你的代码来看,你需要在调用 gl.bufferData 上传数据

你有这个

  gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.DYNAMIC_DRAW);
  gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.DYNAMIC_DRAW);

但它需要这样

  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.DYNAMIC_DRAW);
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.DYNAMIC_DRAW);

const canvas = document.getElementById("canvas");
const vertexCode = `
precision mediump float;

attribute vec4 position;
uniform mat4 matrix;
attribute vec4 color;
varying vec4 col;

void main() {
  col = color;
  gl_Position = matrix * position;
}
`;
const fragmentCode = `
precision mediump float;

varying vec4 col;

void main() {
  gl_FragColor = vec4(1, 0, 0, 1);
}
`;
const width = canvas.width;
const height = canvas.height;
const gl = canvas.getContext("webgl");
if(!gl) {
  console.log("WebGL not supported");
}
const projectionMatrix = [
  2/width, 0, 0, 0,
  0, -2/height, 0, 0,
  0, 0, 1, 0,
  -1, 1, 0, 1
];


const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexCode);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentCode);
gl.compileShader(fragmentShader);

const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

gl.linkProgram(program);

gl.useProgram(program);

const positionBuffer = gl.createBuffer();
const colorBuffer = gl.createBuffer();
const positionLocation = gl.getAttribLocation(program, "position");
const colorLocation = gl.getAttribLocation(program, `color`);
const projectionLocation = gl.getUniformLocation(program, `matrix`);
gl.enableVertexAttribArray(positionLocation);
const vertex = [
    0, 0, 0, 1,
    0, 0, 0, 1,
    0, 0, 0, 1,
    0, 0, 0, 1
  ]
const floatArray = new Float32Array(vertex);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLocation, 4, gl.FLOAT, false, 0, 0);

gl.enableVertexAttribArray(colorLocation);
const color = [
  1, 0, 0, 1,
  1, 0, 0, 1,
  1, 0, 0, 1,
  1, 0, 0, 1
]
const colorArray = new Float32Array(color);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);

gl.uniformMatrix4fv(projectionLocation, false, projectionMatrix);
function rect(x, y, w, h) {
  floatArray[0] = x;
  floatArray[1] = y;
  floatArray[4] = x + w;
  floatArray[5] = y;
  floatArray[8] = x;
  floatArray[9] = y + h;
  floatArray[12] = x + w;
  floatArray[13] = y + h;

  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.DYNAMIC_DRAW);
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.DYNAMIC_DRAW);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

}
function fill(r, g, b, a) {
  colorArray[0] = r;
  colorArray[1] = g;
  colorArray[2] = b;
  colorArray[3] = a;
  //gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.DYNAMIC_DRAW);
}
let lastTime = 0;
let fpsText = document.getElementById("fps");
function animate(currentTime) {
  fpsText.textContent = (1000 / (currentTime - lastTime)).toFixed(1);
  lastTime = currentTime;
  for(let i=0;i<9999;i++) {
    fill(random(0, 1), random(0, 1), random(0, 1), 1);
    rect(random(0, 800), random(0, 600), 10, 10);
  }
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
function random(low, high) {
  return low + Math.random() * (high-low)
}
<canvas id="canvas" width="800" height="600"></canvas>
<div id="fps"></div>
© www.soinside.com 2019 - 2024. All rights reserved.