iT邦幫忙

0

[已解決] WebGL uniformMatrix4fv 位置不是來自當前程序

  • 分享至 

  • xImage

2023.03.04 發問

webGL新手碰壁,想請教各大老們

執行結果(連結將在得到解答後失效):

https://maohupi.github.io/webGlTest/

主要程式(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)出問題

2023.03.05 更新 - 已解決

自己找到問題了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();
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答