10

我正在学习 WebGL,并且正在学习与照明有关的教程。我是 JavaScript 新手,所以我还不太擅长调试它。我不断收到这些错误,有人知道我为什么会遇到这些错误以及如何解决吗?

WebGL: INVALID_OPERATION: useProgram: program not valid http://insanergamer.zxq.net/:1
WebGL: INVALID_OPERATION: getAttribLocation: program not linked http://insanergamer.zxq.net/:1
WebGL: INVALID_OPERATION: getUniformLocation: program not linked http://insanergamer.zxq.net/:1
WebGL: too many errors, no more errors will be reported to the console for this context. 

索引.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf 8" />
    <link rel="stylesheet" href="main.css">
    <script type="text/javascript" language="javascript" src="gl-matrix.js"></script>
    <script type="text/javascript" language="javascript" src="webgl-utils.js"></script>
    <script type="text/javascript" language="javascript" src="first.js"></script>

        <script id="shader-fs" type="x-shader/x-fragment">
               precision mediump float;

                varying vec2 vTextureCoord;
                varying vec3 vLightWeighting;

                uniform sampler2D uSampler;

                void main(void) {
                    vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
                    gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
                }

        </script>

        <script id="shader-vs" type="x-shader/x-vertex">
            attribute vec3 aVertexPosition;
            attribute vec3 aVertexNormal;
            attribute vec2 aTextureCoord;

            uniform mat4 uMVMatrix;
            uniform mat4 uPMatrix;
            uniform mat3 uNMatrix;

            uniform vec3 uAmbientColor;

            uniform vec3 uLightingDirection;
            uniform vec3 uDirectionalColor;

            uniform bool uUseLighting;

            varying vec2 vTextureCoord;
            varying vec3 vLightWeighting;

            void main(void) {
                gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
                vTextureCoord = aTextureCoord;

                if (!uUseLighting) {
                    vLightWeighting = vec3(1.0, 1.0, 1.0);
                } else {
                    vec3 transformedNormal = uNMatrix * aVertexNormal;
                    float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
                    vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
                }
        </script>
</head>
<body onLoad="webGLStart()">
    <header>
    </header>
    <nav>
    </nav>
    <section>
        <h3><a href="todo.html">Link to the TODO page.</a></h3>

        <form>
            <input type="checkbox" id="lighting"></input>Lighting On/Off<br />
            Ambient Lighting Color: Red:<input type="text" id="ambientR"></input> Green:<input type="text" id="ambientG"></input> Blue:<input type="text" id="ambientB"></input> <br />
            Light Direction: X:<input type="text" id="lightDirectionX"></input> Y:<input type="text" id="lightDirectionY"></input> Z:<input type="text" id="lightDirectionZ"></input> <br />
            Direction Lighting Color: Red:<input type="text" id="directionalR"></input> Green:<input type="text" id="directionalG"></input> Blue:<input type="text" id="directionalB"></input> <br />
        </form>

        <p>Press 'F' to change Texture quality.</p>
        <p>Use Arrow Keys to rotate cube.</p>
        <p>Page Up and Page down to zoom in and out.</p>
        <canvas canvasProperties="prop" id="canvas1" style="border: none;" width="1280" height="720"></canvas>
        <article>
            <header>
            </header>
            <footer>
            </footer>
        </article>
    </section>
    <aside>
    </aside>
    <footer>
    </footer>
</body>

第一个.js

    var gl;
function initGL(canvas) {
    try {
        gl = canvas.getContext("experimental-webgl");
        gl.viewportWidth = canvas.width;
        gl.viewportHeight = canvas.height;
    } catch (e) {
    }
    if (!gl) {
        alert("Could not initialise WebGL, sorry :-(");
    }
}


function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
        return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
        if (k.nodeType == 3) {
            str += k.textContent;
        }
        k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
        shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
        return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}


var shaderProgram;

function initShaders() {
    var fragmentShader = getShader(gl, "shader-fs");
    var vertexShader = getShader(gl, "shader-vs");

    shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    gl.useProgram(shaderProgram);

    shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
    gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

    shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
    gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

    shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
    gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);

    shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
    shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
    shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
    shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
    shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
    shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
    shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");
}

var cubeTextures = Array();
function initTexture()
{
    var cubeImage = new Image();

    for(var i=0;i < 3; i++)
    {
        var texture = gl.createTexture();
        texture.image = cubeImage;
        cubeTextures.push(texture);
    }

    cubeImage.onload = function()
    {
        handleLoadedTexture(cubeTextures);
    }
    cubeImage.src = "cube.png";
}

function handleLoadedTexture(texture)
{
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

    gl.bindTexture(gl.TEXTURE_2D,texture[0]);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture[0].image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

    gl.bindTexture(gl.TEXTURE_2D, texture[1]);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture[1].image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

    gl.bindTexture(gl.TEXTURE_2D, texture[2]);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture[2].image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    gl.generateMipmap(gl.TEXTURE_2D);

    gl.bindTexture(gl.TEXTURE_2D, null);
}

var mvMatrix = mat4.create();
var mvMatrixStack = []
var pMatrix = mat4.create();

function mvPushMatrix()
{
    var copy = mat4.create();
    mat4.set(mvMatrix, copy);
    mvMatrixStack.push(copy);
}

function mvPopMatrix()
{
    if(mvMatrixStack.length == 0)
    {
        throw "No Matrix to Pop!";
    }
    mvMatrix = mvMatrixStack.pop();
}

function degToRad(degrees)
{
    return degrees * Math.PI / 180;
}
function setMatrixUniforms() {
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);

    var normalMatrix = mat3.create();
    mat4.toInverseMat3(mvMatrix, normalMatrix);
    mat3.transpose(normalMatrix);
    gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);
}

var cubeVertexPositionBuffer;
var cubeVertexTextureCoordBuffer;
var cubeVertexIndexBuffer;

function initBuffers() {

    cubeVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
    vertices = [
       // Front face
      -1.0, -1.0,  1.0,
       1.0, -1.0,  1.0,
       1.0,  1.0,  1.0,
      -1.0,  1.0,  1.0,

      // Back face
      -1.0, -1.0, -1.0,
      -1.0,  1.0, -1.0,
       1.0,  1.0, -1.0,
       1.0, -1.0, -1.0,

      // Top face
      -1.0,  1.0, -1.0,
      -1.0,  1.0,  1.0,
       1.0,  1.0,  1.0,
       1.0,  1.0, -1.0,

      // Bottom face
      -1.0, -1.0, -1.0,
       1.0, -1.0, -1.0,
       1.0, -1.0,  1.0,
      -1.0, -1.0,  1.0,

      // Right face
       1.0, -1.0, -1.0,
       1.0,  1.0, -1.0,
       1.0,  1.0,  1.0,
       1.0, -1.0,  1.0,

      // Left face
      -1.0, -1.0, -1.0,
      -1.0, -1.0,  1.0,
      -1.0,  1.0,  1.0,
      -1.0,  1.0, -1.0,
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    cubeVertexPositionBuffer.itemSize = 3;
    cubeVertexPositionBuffer.numItems = 24;

     cubeVertexNormalBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
    var vertexNormals = [
        // Front face
         0.0,  0.0,  1.0,
         0.0,  0.0,  1.0,
         0.0,  0.0,  1.0,
         0.0,  0.0,  1.0,

        // Back face
         0.0,  0.0, -1.0,
         0.0,  0.0, -1.0,
         0.0,  0.0, -1.0,
         0.0,  0.0, -1.0,

        // Top face
         0.0,  1.0,  0.0,
         0.0,  1.0,  0.0,
         0.0,  1.0,  0.0,
         0.0,  1.0,  0.0,

        // Bottom face
         0.0, -1.0,  0.0,
         0.0, -1.0,  0.0,
         0.0, -1.0,  0.0,
         0.0, -1.0,  0.0,

        // Right face
         1.0,  0.0,  0.0,
         1.0,  0.0,  0.0,
         1.0,  0.0,  0.0,
         1.0,  0.0,  0.0,

        // Left face
        -1.0,  0.0,  0.0,
        -1.0,  0.0,  0.0,
        -1.0,  0.0,  0.0,
        -1.0,  0.0,  0.0
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW);
    cubeVertexNormalBuffer.itemSize = 3;
    cubeVertexNormalBuffer.numItems = 24;

    cubeVertexTextureCoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
    var textureCoords = [
         // Front face
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,

          // Back face
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,

          // Top face
          0.0, 1.0,
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,

          // Bottom face
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,
          1.0, 0.0,

          // Right face
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,

          // Left face
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
    cubeVertexTextureCoordBuffer.itemSize = 2;
    cubeVertexTextureCoordBuffer.numItems = 24;

    cubeVertexIndexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
    var cubeVertexIndices = [
      0, 1, 2,      0, 2, 3,    // Front face
      4, 5, 6,      4, 6, 7,    // Back face
      8, 9, 10,     8, 10, 11,  // Top face
      12, 13, 14,   12, 14, 15, // Bottom face
      16, 17, 18,   16, 18, 19, // Right face
      20, 21, 22,   20, 22, 23  // Left face
    ]

    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
    cubeVertexIndexBuffer.itemSize = 1;
    cubeVertexIndexBuffer.numItems = 36;
}

var rCubeX = 0;
var SpeedX = 0;

var rCubeY = 0;
var SpeedY = 0;

var z = -5.0;

var filter = 0;

function drawScene() {
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

    mat4.identity(mvMatrix);

    mat4.translate(mvMatrix, [0.0, 0.0, z]);

    mvPushMatrix();
    mat4.rotate(mvMatrix, degToRad(rCubeX), [1, 0, 0]);
    mat4.rotate(mvMatrix, degToRad(rCubeY), [0, 1, 0]);

    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
    gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, cubeVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);

    gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
    gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);

    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, cubeTextures[filter]);
    gl.uniform1i(shaderProgram.samplerUniform, 0);
    var lighting = document.getElementById("lighting").checked;
    gl.uniform1i(shaderProgram.useLightingUniform, lighting);
    if(lighting)
    {
        gl.uniform3f(
            shaderProgram.ambientColorUniform,
            parseFloat(document.getElementById("ambientR").value),
            parseFloat(document.getElementById("ambientG").value),
            parseFloat(document.getElementById("ambientB").value)
        );
    }

    var lightingDirection = [
        parseFloat(document.getElementById("lightDirectionX").value),
        parseFloat(document.getElementById("lightDirectionY").value),
        parseFloat(document.getElementById("lightDirectionZ").value)
    ];
    var adjustedLD = vec3.create();
    vec3.normalize(lightingDirection, adjustedLD);
    vec3.scale(adjustedLD, -1);
    gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD);
    gl.uniform3f(
        shaderProgram.directionalColorUniform,
        parseFloat(document.getElementById("directionalR").value),
        parseFloat(document.getElementById("directionalG").value),
        parseFloat(document.getElementById("directionalB").value)   
    );

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
    setMatrixUniforms();
    gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

    mvPopMatrix();
}

var lastTime = 0;
function animate()
{
    var timeNow = new Date().getTime();
    if(lastTime != 0)
    {
        var elapsed = timeNow - lastTime;

        rCubeX += (SpeedX * elapsed) / 1000.0;
        rCubeY += (SpeedY * elapsed) / 1000.0;
    }
    lastTime = timeNow;
}

 var currentlyPressedKeys = {};

 function handleKeyDown(event){
    currentlyPressedKeys[event.keyCode] = true;
    if(String.fromCharCode(event.keyCode) == "F"){
        filter += 1;
        if(filter == 3){
            filter = 0;
        }
    }
 }

 function handleKeyUp(event){
    currentlyPressedKeys[event.keyCode] = false;

 }
function handleKeys()
{
    if(currentlyPressedKeys[33])
    {
     z -= 0.05;
    }

    if(currentlyPressedKeys[34])
    {
        z += 0.05;
    }

    if(currentlyPressedKeys[37])
    {
        SpeedY --;
    } else if (SpeedY < 0){
        SpeedY ++;
    }

    if(currentlyPressedKeys[39])
    {
        SpeedY ++;
    }else if(SpeedY > 0){
        SpeedY --;
    }

     if (currentlyPressedKeys[38]) {
         SpeedX --;
    } else if(SpeedX < 0){
         SpeedX ++;
    }

    if (currentlyPressedKeys[40]) {
         SpeedX ++;
    } else if(SpeedX > 0){
         SpeedX--;
    }
}

function update()
{
    requestAnimFrame(update);
    handleKeys();
    drawScene();
    animate();
}


function webGLStart() {
    var canvas = document.getElementById("canvas1");
    initGL(canvas);
    initShaders();
    initBuffers();
    initTexture();

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    document.onkeydown = handleKeyDown;
    document.onkeyup = handleKeyUp;

    update();
}
4

4 回答 4

8

在这种特殊情况下,原因是您在顶点着色器末尾缺少一个结束 },但这并不能解释为什么您没有看到有关着色器编译失败的消息的原因。

您的错误检查代码getShader实际上看起来应该可以正常工作,并且您实际上会在编译和链接失败时检查并警告 Clutch 提到的错误日志。

当我复制您的代码并逐字运行时,它正确地给了我一个错误(“意外的 EOF”),所以也许您关闭了 javascript 警报?您可能会考虑console.log在您喜欢的浏览器中使用而不是警报并了解 Javascript 控制台。

于 2012-08-17T03:12:53.373 回答
4

WebGL 通过控制台日志消息给你一个很大的提示:

WebGL:INVALID_OPERATION:useProgram:程序无效 WebGL:INVALID_OPERATION:getAttribLocation:程序未链接

该程序未链接,因此无法使用或查询其状态。

您的程序似乎确实在检查着色器是否正确编译以及程序是否已链接,但事实并非如此。您的错误检查代码可能有问题,隐藏了真正的问题。我总是在新编译的着色器和最近链接的程序上调用这两个函数:

获取着色器信息日志

获取程序信息日志

它们都返回字符串并将帮助您找到根本原因。

于 2012-08-17T02:18:19.887 回答
3

我也遇到了这些奇怪的错误,但仅限于 Chrome 而不是 Firefox:

WebGL: INVALID_OPERATION: getAttribLocation: program not linked
WebGL: INVALID_OPERATION: getUniformLocation: program not linked 
WebGL: INVALID_OPERATION: useProgram: program not valid 
WebGL: INVALID_OPERATION: getAttribLocation: program not linked 
WebGL: INVALID_OPERATION: getUniformLocation: program not linked

我还注意到http://threejs.org/上的大多数示例都会抛出错误(仅在 chrome 中)。通过重新下载源代码,我能够摆脱错误。

于 2013-11-20T09:14:43.123 回答
-1

使用更新版本的three.js,例如来自此CDN http://cdnjs.com/libraries/three.js。旧版本在有效代码上抛出上述错误。

于 2014-07-16T00:19:26.760 回答