2012-02-13 2 views
1

webglで複数のシェーダープログラムを使用しようとしていますが、引き続き問題が発生します。WebGLの複数のプログラムが動作しません

私はプログラムで頂点シェーダの属性の数が異なると、何もエラーなしで表示されないようです。プログラムが同じ数の属性を持たなければならないという制約がありますか?プログラムを変更するときに属性の位置を無効/有効にする必要がありますか?

複数のプログラムを作成するだけで、問題が発生しているようです(2番目のシェーダを使用しなくても、問題が発生します)。 (すべてのプログラム内の属性の数が同じであれば正常に動作します)

は、私は次のコードを使用していた属性を作成するには、次のコードのような大規模な塊を投稿するための

for (var i=0 ; i<vertexAttributes.length ; i++) 
{ 
    shaderProgram[vertexAttributes[i].name] = gl.getAttribLocation(shaderProgram,vertexAttributes[i].name); 
    gl.enableVertexAttribArray(shaderProgram[vertexAttributes[i].name]); 
} 

申し訳ありませんが、これは問題を最もよく示しています。これはlearningwebgl.comチュートリアルのコードの1つで、2番目のシェーダ(「shader2-fs」と「shader2-vs」)とinitShaders2という新しい関数を追加するだけです。 initShaders2がwebGLStart()で呼び出された場合(コード内にあるように)、何も描画されません???私はうんざり!

<script type="text/javascript" src="two_files/glMatrix-0.js"></script> 
<script type="text/javascript" src="two_files/webgl-utils.js"></script> 

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

    varying vec4 vColor; 

    void main(void) { 
     gl_FragColor = vColor; 
    } 
</script> 

<script id="shader-vs" type="x-shader/x-vertex"> 
    attribute vec3 aVertexPosition; 
    attribute vec4 aVertexColor; 

    uniform mat4 uMVMatrix; 
    uniform mat4 uPMatrix; 

    varying vec4 vColor; 

    void main(void) { 
     gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); 
     vColor = aVertexColor; 
    } 
</script> 

<script id="shader2-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="shader2-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> 


<script type="text/javascript"> 

    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.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); 
     gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute); 

     shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); 
     shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); 
    } 


    var shaderProgram2; 

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

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

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

     gl.useProgram(shaderProgram2); 

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

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

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

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

    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 "Invalid popMatrix!"; 
     } 
     mvMatrix = mvMatrixStack.pop(); 
    } 


    function setMatrixUniforms() { 
     gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); 
     gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); 
    } 


    function degToRad(degrees) { 
     return degrees * Math.PI/180; 
    } 


    var pyramidVertexPositionBuffer; 
    var pyramidVertexColorBuffer; 
    var cubeVertexPositionBuffer; 
    var cubeVertexColorBuffer; 
    var cubeVertexIndexBuffer; 

    function initBuffers() { 
     pyramidVertexPositionBuffer = gl.createBuffer(); 
     gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); 
     var vertices = [ 
      // Front face 
      0.0, 1.0, 0.0, 
      -1.0, -1.0, 1.0, 
      1.0, -1.0, 1.0, 

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

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

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

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

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

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

      // Left face 
      1.0, 0.0, 0.0, 1.0, 
      0.0, 0.0, 1.0, 1.0, 
      0.0, 1.0, 0.0, 1.0 
     ]; 
     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); 
     pyramidVertexColorBuffer.itemSize = 4; 
     pyramidVertexColorBuffer.numItems = 12; 


     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; 

     cubeVertexColorBuffer = gl.createBuffer(); 
     gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); 
     colors = [ 
      [1.0, 0.0, 0.0, 1.0], // Front face 
      [1.0, 1.0, 0.0, 1.0], // Back face 
      [0.0, 1.0, 0.0, 1.0], // Top face 
      [1.0, 0.5, 0.5, 1.0], // Bottom face 
      [1.0, 0.0, 1.0, 1.0], // Right face 
      [0.0, 0.0, 1.0, 1.0] // Left face 
     ]; 
     var unpackedColors = []; 
     for (var i in colors) { 
      var color = colors[i]; 
      for (var j=0; j < 4; j++) { 
       unpackedColors = unpackedColors.concat(color); 
      } 
     } 
     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(unpackedColors), gl.STATIC_DRAW); 
     cubeVertexColorBuffer.itemSize = 4; 
     cubeVertexColorBuffer.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 rPyramid = 0; 
    var rCube = 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, [-1.5, 0.0, -8.0]); 

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

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

     gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); 
     gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, pyramidVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0); 

     setMatrixUniforms(); 
     gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer.numItems); 

     mvPopMatrix(); 


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

     mvPushMatrix(); 
     mat4.rotate(mvMatrix, degToRad(rCube), [1, 1, 1]); 

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

     gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); 
     gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, cubeVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0); 

     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; 

      rPyramid += (90 * elapsed)/1000.0; 
      rCube -= (75 * elapsed)/1000.0; 
     } 
     lastTime = timeNow; 
    } 


    function tick() { 
     requestAnimFrame(tick); 
     drawScene(); 
     animate(); 
    } 


    function webGLStart() { 
     var canvas = document.getElementById("lesson04-canvas"); 
     initGL(canvas); 
     initShaders2(); // !!!!!!!!!!!!!!!!!!!!!!!!! 
     initShaders(); 
     initBuffers(); 

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

     tick(); 
    } 

</script> 


</head> 


<body onload="webGLStart();"> 
    <a href="http://learningwebgl.com/blog/?p=370">&lt;&lt; Back to Lesson 4</a><br> 

    <canvas id="lesson04-canvas" style="border: none;" width="500" height="500"></canvas> 

    <br> 
    <a href="http://learningwebgl.com/blog/?p=370">&lt;&lt; Back to Lesson 4</a><br> 

</body></html> 

答えて

10

あなたは、おそらく私たちに少しより多くの情報を与える必要がありますが、あなたはここに始めるためには、迅速なチェックリストです。あなたがプログラムを変更するときはいつでも、あなたがしたいと思う:適切な頂点を有効

  • は配列
  • バインド頂点は、彼らがすでに右バッファ
  • バインドに必要な任意の制服に結合させた場合でも、ポインタ属性属性テクスチャサンプラーのように。

基本的に、描画呼び出しを初めて設定したときと同じように、プログラムを変更するたびに処理します。

+0

洞察に感謝します!私はそれを解決するのに十分な情報を与えていませんでしたが、あなたが与えた情報は私の心を正しい方法で考えさせました。乾杯! –

関連する問題