2016-11-11 104 views
1

我正在使用紋理金字塔,但我收到了一些警告。我從「開始WebGL for HTML5」一書中一步一步完成,並且它不起作用。在WebGL中構造一個金字塔

這裏是我的代碼:

<!doctype html> 
<html> 
    <head> 
     <title>Project 2</title> 

     <script type="text/javascript" src="gl-matrix-min.js"></script> 


     <style> 
       body{ background-color: grey; } 
       canvas{ background-color: white; } 
     </style> 
     <script id="shader-vs" type="x-shader/x-vertex"> 
       attribute vec4 aVertexPosition; 
       attribute vec4 aVertexColor; 
       attribute vec2 aVertexTextureCoord; 

       varying highp vec2 vTextureCoord; 
       varying vec4 vColor; 
       /* 

       Couting On GPU 

       // Model matrix 
       uniform mat4 uMVMatrix; 
       // Projection matrix 
       uniform mat4 uPMatrix; 
       // View matrix 
       uniform mat4 uVMatrix; 

       */ 

       uniform mat4 uPVMatrix; 

       void main(void) { 
        vColor = aVertexColor; 
        gl_Position = uPVMatrix * aVertexPosition; 
        vTextureCoord = aVertexTextureCoord; 
       // gl_Position = uPMatrix * uVMatrix * uMVMatrix * aVertexPosition; 
       } 
     </script> 
     <script id="shader-fs" type="x-shader/x-fragment"> 
      precision mediump float; 
      varying vec4 vColor; 
      varying highp vec2 vTextureCoord; 
      uniform sampler2D uSampler; 
       void main(void) { 
        gl_FragColor = texture2D(uSampler, vTextureCoord); 
       } 
     </script> 
     <script> 
       var gl = null, 
        canvas = null, 
        glProgram = null, 
        fragmentShader = null, 
        vertexShader = null; 

       var coordinateArray = [], 
        triangleVerticeColors = [], 
        verticesArray = [], 
        verticesIndexArray = [], 
        triangleTexCoords = []; 

       var vertexPositionAttribute = null, 
        trianglesVerticeBuffer = null, 
        vertexColorAttribute = null, 
        trianglesColorBuffer = null, 
        triangleVerticesIndexBuffer = null, 
        vertexTexCoordAttribute = null, 
        trianglesTexCoordBuffer = null; 



       var P = mat4.create(), 
        V = mat4.create(), 
        M = mat4.create(), 
        VM = mat4.create(), 
        PVM = mat4.create(); 

       var uPVMMatrix; 

       var texture; 
       var textureImage = null; 

       function initWebGL() { 
        canvas = document.getElementById("my-canvas"); 
        try { 
         gl = canvas.getContext("webgl") || 
         canvas.getContext("experimental-webgl"); 
        }catch(e){ } 
        if(gl) { 
         setupWebGL(); 
         initShaders(); 
         setupTexture(); 
         setupBuffers(); 

         //getMatrixUniforms(); 
         //setMatrixUniforms(); 
         //animationLoop(); 
         drawScene(); 
        }else{ 
         alert("Error: Your browser does not appear to" + "support WebGL."); 
        } 
       } 

       function animationLoop() { 
        var R = mat4.create(); 
        var angle = 0; 
        var i =0; 

        var loop = function() { 
         angle = performance.now()/1000/6 * 2 * Math.PI; 
         i++; 
         mat4.rotate(PVM, R, angle, [0, 1, 0]); 

         gl.uniformMatrix4fv(uPVMMatrix, false, PVM); 

         gl.clearColor(0.0, 0.0, 0.0, 0.0); 
         gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT); 
         drawScene(); 
         requestAnimationFrame(loop); 
        }; 
        requestAnimationFrame(loop); 
       } 

       function setupWebGL() { 
        gl.enable(gl.DEPTH_TEST); 
        gl.enable(gl.CULL_FACE); 
        gl.frontFace(gl.CW); 
        gl.cullFace(gl.BACK); 
        gl.clearColor(0.0, 0.0, 0.0, 0.0); 
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 



        console.log(P);   
        console.log(V);    
        console.log(M); 

       // mat4.identity(M); 
        mat4.lookAt(V, [5, 0, -5], [0, 0, 0], [0, 1, 0]); 
        mat4.perspective(P, glMatrix.toRadian(45), canvas.width/canvas.height, 0.1, 1000.0); 

        mat4.multiply(VM,V,M); 
        mat4.multiply(PVM,P,VM); 


       } 

       function initShaders() { 
        var fs_source = document.getElementById('shader-fs').innerHTML, 
         vs_source = document.getElementById('shader-vs').innerHTML; 

        vertexShader = makeShader(vs_source, gl.VERTEX_SHADER); 
        fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER); 

        glProgram = gl.createProgram(); 

        gl.attachShader(glProgram, vertexShader); 
        gl.attachShader(glProgram, fragmentShader); 
        gl.linkProgram(glProgram); 
        if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) { 
         alert("Unable to initialize the shader program."); 
        } 

        gl.useProgram(glProgram); 

        uPVMMatrix = gl.getUniformLocation(glProgram, "uPVMatrix"); 
        gl.uniformMatrix4fv(uPVMMatrix, false, PVM); 

       } 



       function loadTexture() { 
        textureImage = $("#troll").get(0); 
        setupTexture(); 
       } 

       function setupTexture() { 
        texture = gl.createTexture(); 
        gl.bindTexture(gl.TEXTURE_2D, texture); 
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNISGNED_BYTE, textureImage); 
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 

        glProgram.sampleUniform = gl.getUniformLocation(glProgram, "uSampler"); 
        gl.uniform1i(glProgram.sampleUniform, 0); 

        if(!gl.isTexture(texture)) { 
         console.log("Error : Texture is invalid"); 
        } 
       } 

       function makeShader(src, type) { 
        var shader = gl.createShader(type); 

        gl.shaderSource(shader, src); 
        gl.compileShader(shader); 
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 
         alert("Error compiling shader: " + gl.getShaderInfoLog(shader)); 
        } 
        return shader; 
       } 

       function setupBuffers() { 
        // n-sides polygon 
        var n = 6; 
        var radius = 1; 
        var angle = (Math.PI * 2)/n; 
        var xCoordinate = 0; 
        var yCoordinate = 0; 
        for(var i = 0 ; i < n ; i++) { 

         var a = angle * i; 
         var xNewCoordinate = xCoordinate + radius * Math.cos(a); 
         var yNewCoordinate = yCoordinate + radius * Math.sin(a); 
         var zNewCoordinate = 0; 
         coordinateArray.push(xNewCoordinate); 
         coordinateArray.push(yNewCoordinate); 
         coordinateArray.push(zNewCoordinate); 

        } 

        verticesArray = [ 

         //Bottom Face 
         0.0, 0.0, 0.0, 
         0.0, 0.0, -1.0, 
         1.0, 0.0, -1.0, 
         0.0, 0.0, 0.0, 
         1.0, 0.0, -1.0, 
         1.0, 0.0, 0.0, 

         //Front Face 
         0.0, 0.0, 0.0, 
         1.0, 0.0, 0.0, 
         0.5, 1.0, -0.5, 

         //Right Face 
         1.0, 0.0, 0.0, 
         1.0, 0.0, -1.0, 
         0.5, 1.0, -0.5, 

         //Back Face 
         1.0, 0.0, -1.0, 
         0.0, 0.0, -1.0, 
         0.5, 1.0, -0.5, 

         //Left Face 
         0.0, 0.0, -1.0, 
         0.0, 0.0, 0.0, 
         0.5, 1.0, -0.5, 
        ]; 

        trianglesVerticeBuffer = gl.createBuffer(); 
        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer); 
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArray), gl.STATIC_DRAW); 

        verticesIndexArray = [ 
         0, 1, 2, 
         3, 4, 5, 
         6, 7, 8, 
         9, 10, 11, 
         12, 13, 14, 
         15, 16, 17, 
        ]; 

        triangleVerticesIndexBuffer = gl.createBuffer(); 
        triangleVerticesIndexBuffer.number_vertext_points = verticesIndexArray.length; 
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleVerticesIndexBuffer); 
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(verticesIndexArray), gl.STATIC_DRAW); 

        triangleTexCoords = [ 
         0.5000, 0.1910, 
         0.1910, 0.5000, 
         0.5000, 0.8090, 
         0.5000, 0.1910, 
         0.5000, 0.8090, 
         0.8090, 0.5000, 

         0.5000, 0.1910, 
         0.8090, 0.5000, 
         1.0000, 0.0000, 

         0.8090, 0.5000, 
         0.5000, 0.8090, 
         1.0000, 1.0000, 

         0.5000, 0.8090, 
         0.1910, 0.5000, 
         0.0000, 1.0000, 

         0.1910, 0.5000, 
         0.5000, 0.1910, 
         0.0000, 0.0000, 
        ]; 

        trianglesTexCoordBuffer = gl.createBuffer(); 
        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesTexCoordBuffer); 
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleTexCoords), gl.STATIC_DRAW); 

        triangleVerticeColors = [ 
         // Bottom quad 
         0.470, 0.796, 0.886, 
         0.470, 0.796, 0.886, 
         0.470, 0.796, 0.886, 
         0.470, 0.796, 0.886, 
         0.470, 0.796, 0.886, 
         0.470, 0.796, 0.886, 

         // Back triangle 
         0.772, 0.470, 0.886, 
         0.772, 0.470, 0.886, 
         0.772, 0.470, 0.886, 

         // Left triangle 
         0.886, 0.552, 0.470, 
         0.886, 0.552, 0.470, 
         0.886, 0.552, 0.470, 

         // Front triangle 
         0.886, 0.882, 0.470, 
         0.886, 0.882, 0.470, 
         0.886, 0.882, 0.470, 

         // Right triangle 
         0.470, 0.886, 0.505, 
         0.470, 0.886, 0.505, 
         0.470, 0.886, 0.505, 
        ]; 

        trianglesColorBuffer = gl.createBuffer(); 
        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer); 
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticeColors), gl.STATIC_DRAW); 

       } 

       // GPU 

       function getMatrixUniforms() { 

        glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, "uMVMatrix"); 
        glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, "uPMatrix"); 
        glProgram.vMatrixUniform = gl.getUniformLocation(glProgram, "uVMatrix");     

       } 

       // GPU 

       function setMatrixUniforms() { 

        gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, M); 
        gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, P); 
        gl.uniformMatrix4fv(glProgram.vMatrixUniform, false, V); 

       } 

       function drawScene() { 
        vertexPositionAttribute = gl.getAttribLocation(glProgram, "aVertexPosition"); 
        gl.enableVertexAttribArray(vertexPositionAttribute); 
        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer); 
        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); 

        vertexTexCoordAttribute = gl.getAttribLocation(glProgram, "aVertexTexCoord"); 
        gl.enableVertexAttribArray(vertexTexCoordAttribute); 
        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesTexCoordBuffer); 
        gl.vertexAttribPointer(vertexTexCoordAttribute, 2, gl.FLOAT, false, 0, 0); 

        /*vertexColorAttribute = gl.getAttribLocation(glProgram, "aVertexColor");  
        gl.enableVertexAttribArray(vertexColorAttribute); 
        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer); 
        gl.vertexAttribPointer(vertexColorAttribute, 3, gl.FLOAT, false, 0, 0); 
        */ 


        gl.drawElements(gl.TRIANGLE_STRIP, triangleVerticesIndexBuffer.number_vertext_points, gl.UNSIGNED_SHORT, 0);   
       } 
     </script> 
    </head> 
    <body onload="initWebGL()"> 
     <canvas id="my-canvas" width="800" height="600"> 
      Your browser does not support the HTML5 canvas element. 
     </canvas> 
     <img src="./trollface.png" id="troll" /> 
    </body> 
</html> 

紋理座標我用看起來像這樣:

UV map

這裏是質地:

texture

的警告大約超出範圍數組和關於圖像不加載。

回答

1

您的代碼中有多個錯誤。

  1. 您的功能loadTexture()永遠不會被調用,所以紋理實際上從不加載。
    initWebGL()代替setupTexture()loadTexture()

  2. 您似乎也在使用jQuery從DOM中檢索圖像,但是您沒有加載該庫。
    $("#troll").get(0)替換爲document.getElementById("troll")內部loadTexture()

  3. 紋理的尺寸需要是2的冪(128x32,256x256,512x1024,...)
    您應該將圖像大小調整爲256x256。

  4. 您使用texImage2D()的某個參數進行了拼寫錯誤。
    gl.UNISGNED_BYTE替換爲gl.UNSIGNED_BYTE在你的gl.texImage2D()之內調用。

  5. 您的紋理座標屬性的名稱在您的gl.getAttribLocation()調用和頂點着色器代碼之間不匹配。
    用您的gl.getAttribLocation()呼叫替換aVertexTexCoordaVertexTextureCoord

  6. 如果您正在渲染單個三角形,請在gl.drawElements()調用中將gl.TRIANGLE_STRIP替換爲gl.TRIANGLES

如果你解決所有這些代碼將沒有錯誤運行錯誤。

+0

謝謝你的幫忙! – yerpy