webGL新手碰壁,想請教各大老們
執行結果(連結將在得到解答後失效):
主要程式(main.js
):
function main(){
const cvs = document.querySelector('#mainCvs');
[cvs.width, cvs.height] = [500, 500];
const gl = cvs.getContext('webgl');
window.gl = gl;
if(gl === null){
return;
}
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
let matrix = glMatrix.mat4.create();
glMatrix.mat4.translate(matrix, matrix, [0.2, 0.5, 0]);
let vertexData = [
1, 1, 0,
1, -1, 0,
-1, -1, 0,
1, 1, 0,
-1, 1, 0,
-1, -1, 0,
];
vertexData = vertexData.map(n => n*0.95);
let colorData = [
1, 0, 0,
1, 1, 0,
0, 1, 0,
1, 0, 0,
0, 1, 1,
0, 1, 0,
];
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colorData), gl.STATIC_DRAW);
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, `
precision mediump float;
attribute vec3 position;
attribute vec3 color;
varying vec3 vColor;
uniform mat4 matrix;
void main(){
vColor = color;
gl_Position = matrix * vec4(position, 1);
// gl_Position = vec4(position, 1);
}
`);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, `
precision mediump float;
varying vec3 vColor;
void main(){
gl_FragColor = vec4(vColor, 1);
}
`);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const attribLocation_position = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(attribLocation_position);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(attribLocation_position, 3, gl.FLOAT, false, 0, 0);
const attribLocation_color = gl.getAttribLocation(program, 'color');
gl.enableVertexAttribArray(attribLocation_color);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(attribLocation_color, 3, gl.FLOAT, false, 0, 0);
const uniformLocation_matrix = gl.getUniformLocation(program, 'matrix');
console.log(matrix);
gl.uniformMatrix4fv(uniformLocation_matrix, false, matrix);
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, vertexData.length);
}
main();
錯誤訊息:
main.js:80 WebGL: INVALID_OPERATION: uniformMatrix4fv: location is not from current program
main @ main.js:80
(anonymous) @ main.js:85
額外描述:
如果把第49行
的matrix *
拿掉,改成第50行
的樣子就不會出錯,所以懷疑是matrix * vec4(position, 1)
出問題
自己找到問題了XD
問題在於uniformMatrix4fv
必須在useProgram
之後才能使用,也就是說main.js
應該改成:
function main(){
const cvs = document.querySelector('#mainCvs');
[cvs.width, cvs.height] = [500, 500];
const gl = cvs.getContext('webgl');
window.gl = gl;
if(gl === null){
return;
}
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
let matrix = glMatrix.mat4.create();
glMatrix.mat4.translate(matrix, matrix, [0.2, 0.5, 0]);
let vertexData = [
1, 1, 0,
1, -1, 0,
-1, -1, 0,
1, 1, 0,
-1, 1, 0,
-1, -1, 0,
];
vertexData = vertexData.map(n => n*0.95);
let colorData = [
1, 0, 0,
1, 1, 0,
0, 1, 0,
1, 0, 0,
0, 1, 1,
0, 1, 0,
];
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colorData), gl.STATIC_DRAW);
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, `
precision mediump float;
attribute vec3 position;
attribute vec3 color;
varying vec3 vColor;
uniform mat4 matrix;
void main(){
vColor = color;
gl_Position = matrix * vec4(position, 1);
// gl_Position = vec4(position, 1);
}
`);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, `
precision mediump float;
varying vec3 vColor;
void main(){
gl_FragColor = vec4(vColor, 1);
}
`);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const attribLocation_position = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(attribLocation_position);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(attribLocation_position, 3, gl.FLOAT, false, 0, 0);
const attribLocation_color = gl.getAttribLocation(program, 'color');
gl.enableVertexAttribArray(attribLocation_color);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(attribLocation_color, 3, gl.FLOAT, false, 0, 0);
gl.useProgram(program);
const uniformLocation_matrix = gl.getUniformLocation(program, 'matrix');
console.log(matrix);
gl.uniformMatrix4fv(uniformLocation_matrix, false, matrix);
gl.drawArrays(gl.TRIANGLES, 0, vertexData.length);
}
main();