2012-08-17 18 views
7

Estoy aprendiendo WebGL y estoy en el tutorial this que tiene que ver con la iluminación. Soy nuevo en JavaScript, así que no soy tan bueno para depurarlo todavía. Sigo recibiendo estos errores, ¿alguien sabe por qué los obtengo y cómo solucionarlos?WebGL - Operación no válida useProgram

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. 

index.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> 

first.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(); 
} 

Respuesta

7

La causa en este caso particular es que le falta un cierre} al final de su sombreador de vértices, aunque eso no responde por qué no está viendo un mensaje acerca de por qué su sombreador no puede compilar.

Parece que su código de error en getShader debería funcionar bien, y de hecho se verifican y alertan los registros de errores del embrague mencionados cuando falla la compilación y el enlace.

Cuando copié el código y lo ejecuté al pie de la letra, me dio correctamente un error ("EOF inesperado"), ¿entonces quizás tengas desactivadas las alertas de JavaScript? Puede considerar usar console.log en lugar de alertar y conocer la consola de Javascript en su navegador favorito.

+0

Gracias, en realidad me preguntaba cómo hacer eso. – cgasser

+1

Dudo que este sea el problema, pero solo para su información, siempre y cuando el enlace falle para los programas no válidos GL no es necesario para devolver la falla en la compilación. :-( – gman

4

WebGL le está dando una gran pista con los mensajes de registro de la consola:

WebGL: INVALID_OPERATION: useProgram: programa no válida WebGL: INVALID_OPERATION: getAttribLocation: programa no vinculado

El programa no está vinculado y por lo tanto no se puede utilizar o que es consultada estado.

Su programa parece estar comprobando que los sombreadores se compilaron correctamente y que el programa está vinculado, pero no es el caso. Es probable que haya algún problema con el código de comprobación de errores, ocultando el problema real. Siempre llamo a estas dos funciones en shaders recién compilados y programas vinculados recientemente:

getShaderInfoLog

getProgramInfoLog

Ambos devuelven cadenas y le ayudará a llegar a la raíz del problema.

+0

Gracias, lo intentaré y veré si puedo solucionarlo. – cgasser

3

También conseguía estos errores extraños, pero sólo en Chrome y no en 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 

También he notado que la mayoría de los ejemplos de los errores http://threejs.org/ tiro a (sólo en cromo). Cualquiera al volver a descargar la fuente, pude deshacerme de los errores.

Cuestiones relacionadas