2012-02-13 5 views
1

webgl에서 여러 개의 셰이더 프로그램을 사용하려고하지만 계속 문제가 발생합니다.WebGL에서 여러 프로그램이 작동하지 않습니다.

내가 프로그램에서 버텍스 쉐이더 속성의 다른 수를 가진다면 아무런 오류없이 아무것도 렌더링되지 않는 것처럼 보입니다. 프로그램이 같은 수의 속성을 가져야한다는 것을 의미하는 제약이 있습니까? 프로그램을 변경할 때 속성 위치를 비활성화/활성화해야합니까?

여러 프로그램을 만드는 것만으로도 문제가 발생합니다. 두 번째 셰이더를 사용해야 할 필요가 있습니다. (모든 프로그램의 속성 개수가 동일한 경우 잘 작동)

내가 다음 코드를 사용하고 속성을 만들려면 다음 코드와 같은 큰 덩어리를 게시

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 튜토리얼의 코드 중 하나입니다. 두 번째 쉐이더 쉐이더 ("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

통찰력에 감사드립니다! 나는 당신이 그것을 해결할 수있는 충분한 정보를주지 못했지만, 당신이 준 정보는 올바른 생각으로 내 마음을 세웠습니다. 건배! –

관련 문제