2015-03-02 54 views
2

我下面一本書,叫做專業的WebGL的不是讀者財產createShader,我手寫的東西,確保我的理解,我有這樣的代碼:WebGL的 - 可空

<!DOCTYPE HTML> 
<html lang="en"> 
<head> 
    <title>2-1 A first WebGL example</title> 
    <meta charset="utf-8"> 

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

     void main() { 
      gl_Position = vec4(aVertexPosition, 1.0); 
     } 
    </script> 

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

     void main() { 
      gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); 
     } 
    </script> 

    <script type="text/javascript"> 
     var gl; 
     var canvas; 
     var shaderProgram; 
     var vertexBuffer; 

     /*Function to create the webgl context*/ 
     function createGLContext(canvas) { 
      var names = ["webgl", "experimental-webgl"]; 
      var context = null; 
      for(var i = 0; i < names.length; i++) { 
       try { 
        context = canvas.getContext(names[i]); 
       } catch(e) { 
        if(context) { 
         break; 
        } 
       } 
      } 
      if(context) { 
       context.viewportWidth = canvas.width; 
       context.viewportHeight = canvas.height; 
      } else { 
       alert("Failed to create webgl context"); 
      } 

      return context; 
     } 

     function loadShaderFromDOM(id) { 
      var shaderScript = document.getElementById(id); 

      //if we don't find an element with the specified id 
      //we do an early exit 
      if(!shaderScript) { 
       return null; 
      } 

      //loop through the children for the found DOM element and 
      //build up the shader source code as a string. 
      var shaderSource = ""; 
      var currentChild = shaderScript.firstChild; 
      while(currentChild) { 
       if(currentChild.nodeType == 3) { 
        //3 corresponds to TEXT_NODE 
        shaderSource += currentChild.textContent; 
       } 
       currentChild = currentChild.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, shaderSource); 
      gl.compileShader(shader); 

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

     /*Function to setup the shaders*/ 
     function setupShaders() { 
      var vertexShader = loadShaderFromDOM("shader-vs"); 
      var fragmentShader = loadShaderFromDOM("shader-fs"); 

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

      if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { 
       alert("Failed toe setup shaders"); 
      } 

      gl.useProgram(shaderProgram); 

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

     /*Function to setup the buffers*/ 
     function setupBuffers() { 
      vertexBuffer = gl.createBuffer(); 
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
      var triangleVertices = [ 
       0.0, 0.5, 0.0, 
       -0.5, -0.5, 0.0, 
       0.5, -0.5, 0.0 
      ]; 
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW); 
      vertexBuffer.itemSize = 3; 
      vertexBuffer.numberOfItems = 3; 
     } 

     /*Function to draw the triangle*/ 
     function draw() { 
      gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 
      gl.celar(gl.COLOR_BUFFER_BIT); 

      gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); 

      gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); 

      gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems); 
     } 

     /*Function to kick everything off*/ 
     function startup() { 
      canvas = document.getElementById("myGLCanvas"); 
      gl = createGLContext(canvas); 
      setupShaders(); 
      setupBuffers(); 
      gl.clearColor(0.0, 0.0, 0.0, 0.1); 
      draw(); 
     } 

    </script> 
</head> 

<body onload="startup()"> 
<canvas id="myGLCnvas" width="500" height="300"></canvas> 
</body> 
</html> 

出於某種原因,它說,它不能讀取屬性爲null createShader這裏: shader = gl.createShader(gl.VERTEX_SHADER);

不過,這並不抱怨,在所有相同的聲明,但與片段着色器。

回答

2

稍有變化的版本。 gl.celar是錯誤的,並獲得上下文的主要循環。

<!DOCTYPE HTML> 
<html lang="en"> 
<head> 
    <title>2-1 A first WebGL example</title> 
    <meta charset="utf-8"> 

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

     void main() { 
      gl_Position = vec4(aVertexPosition, 1.0); 
     } 
    </script> 

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

     void main() { 
      gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); 
     } 
    </script> 

    <script type="text/javascript"> 
     var gl; 
     var canvas; 
     var shaderProgram; 
     var vertexBuffer; 

     /*Function to create the webgl context*/ 
     function createGLContext(canvas) { 
      var names = ["webgl", "experimental-webgl"]; 
      gl = null; 
      for(var i = 0; i < names.length; i++) { 

       gl = canvas.getContext(names[i]); 
       if(gl) 
        break; 
      } 
      if(gl) { 
       gl.viewportWidth = canvas.width; 
       gl.viewportHeight = canvas.height; 
      } else { 
       console.log("Failed to create webgl context"); 
      } 
     } 

     function loadShaderFromDOM(id) { 
      var shaderScript = document.getElementById(id); 

      //if we don't find an element with the specified id 
      //we do an early exit 
      if(!shaderScript) { 
       return null; 
      } 

      //loop through the children for the found DOM element and 
      //build up the shader source code as a string. 
      var shaderSource = ""; 
      var currentChild = shaderScript.firstChild; 
      while(currentChild) { 
       if(currentChild.nodeType == 3) { 
        //3 corresponds to TEXT_NODE 
        shaderSource += currentChild.textContent; 
       } 
       currentChild = currentChild.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, shaderSource); 
      gl.compileShader(shader); 

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

     /*Function to setup the shaders*/ 
     function setupShaders() { 
      var vertexShader = loadShaderFromDOM("shader-vs"); 
      var fragmentShader = loadShaderFromDOM("shader-fs"); 

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

      if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { 
       alert("Failed toe setup shaders"); 
      } 

      gl.useProgram(shaderProgram); 

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

     /*Function to setup the buffers*/ 
     function setupBuffers() { 
      vertexBuffer = gl.createBuffer(); 
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
      var triangleVertices = [ 
       0.0, 0.5, 0.0, 
       -0.5, -0.5, 0.0, 
       0.5, -0.5, 0.0 
      ]; 
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW); 
      vertexBuffer.itemSize = 3; 
      vertexBuffer.numberOfItems = 3; 
     } 

     /*Function to draw the triangle*/ 
     function draw() { 
      gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 
      gl.clear(gl.COLOR_BUFFER_BIT); 

      gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); 

      gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); 

      gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems); 
     } 

     /*Function to kick everything off*/ 
     function startup() { 
      canvas = document.getElementById("myGLCnvas"); 
      createGLContext(canvas); 
      setupShaders(); 
      setupBuffers(); 
      gl.clearColor(0.0, 0.0, 0.0, 0.1); 
      draw(); 
     } 

    </script> 
</head> 

<body onload="startup()"> 
<canvas id="myGLCnvas" width="500" height="300"></canvas> 
</body> 
</html> 
+0

謝謝,我還注意到:canvas = document.getElementById(「myGLCnvas」);並在div中拼寫不同:myGLCanvas。 – user2405469 2015-03-03 10:12:33

+0

我發現保持獲取上下文相同的主循環仍然工作後更改div拼錯...奇怪? – user2405469 2015-03-03 10:16:31

+0

一點也不奇怪。你傳遞了變量'gl = createGLContext()'。但無論如何,你需要設置'gl' var,因爲這是你使用的那個。請接受我的答案,也許upvote它,謝謝。 – 2015-03-03 17:49:04