WebGL學習筆記四點二

來源:互聯網
上載者:User

標籤:

   前幾章對圖形圖形內部多是 以純色填充,但是現實中已經有許多好的圖片了我們沒必要一點點畫,這一章第五章就是將圖片以紋理的形式載入到片元中,主要過程如下,首先是定義點的座標的attribute變數用於在javascript中 賦值,接下來定義varying 的vec2的變數用於將紋理座標從頂點著色器傳給片元著色器 在片元著色器中定義取樣器左右儲存紋理映像和相關參數,接下來就是為各個變數賦值,賦值方法與前面一直,先是建立緩衝區,綁定矩陣,寫入資料,擷取變數儲存地址,再就是寫入緩衝區資料,最後啟用變數,這樣就為頂點座標和紋理座標賦值了,最後是對取樣器賦值 取樣器是uniform的 先建立紋理對象,擷取取樣器地址,擷取映像對象,設定映像Y軸反轉,因為無法對紋理對象直接操作所以指定紋理單員,啟用單元,將紋理對象和紋理單元綁定,配置紋理參數,配置紋理映像,最後取樣器賦值,然後畫圖形。

 

 

上代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>TexturedQuad.html</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
    <script src="js/cuon-matrix.js"></script>
    <script src="js/cuon-utils.js"></script>
    <script src="js/webgl-debug.js"></script>
    <script src="js/webgl-utils.js"></script>
    <script type="text/javascript">
        var VSHADER_SOURCE=//定點著色器
        ‘attribute vec4 a_Position;\n‘+//定義vec4的變數 並且聲明該變數是attribute型的
        ‘attribute float a_PointSize;\n‘+
        ‘attribute vec2 a_TextCoord;\n‘+
        ‘varying vec2 v_TextCoord;\n‘+
        ‘void main(){\n‘+
        ‘gl_Position=a_Position;\n‘+//將attribute的變數賦值給內部
        ‘gl_PointSize=a_PointSize;\n‘+
        ‘v_TextCoord=a_TextCoord;\n‘+//將資料傳給片元著色器
        ‘}\n‘;
        
        var FSHADER_SOURCE=//片元著色器
        ‘precision mediump float;\n‘ +
        ‘uniform sampler2D u_Sampler;\n‘+
        ‘varying vec2 v_TextCoord;\n‘+
        ‘void main(){\n‘+
        ‘gl_FragColor=texture2D(u_Sampler,v_TextCoord);\n‘+//
        ‘}\n‘;
        
        function main(){
            var canvas=document.getElementById("webgl");
            
            var gl=getWebGLContext(canvas);
            if(!gl){
                console.log("gl load fail!");
                return;
            }
            
            if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){//初始化著色器
                console.log("fail init shader()!");
                return ;
            }
            
            
            var n=initVertexBuffers(gl);//將頂點座標和紋理座標賦值
            if(n<0){
                console.log("failed to set the positions of the vertices");
                return;
            }
            gl.clearColor(0.0, 0.0, 1.0, 1.0);
            initTextures(gl,n);
            
             
        }
        function initVertexBuffers(gl){
                var verticesTextCoords=new Float32Array([
                -0.5,0.5,2,-0.3,1.7,
                -0.5,-0.5,2,-0.3,-0.2,
                0.5,0.5,2,1.7,1.7,
                0.5,-0.5,2,1.7,-0.2,
                ]);//類型化數組
                
                
                var n=4;//點的個數
                
                var vertexTexcoordBuffer=gl.createBuffer();//在webGL中建立緩衝區
                if(!vertexTexcoordBuffer){
                    console.log("failed to create the buffer object!");
                    return -1;
                }
                
                gl.bindBuffer(gl.ARRAY_BUFFER,vertexTexcoordBuffer);//將緩衝區與ARRAY_BUFFER綁定就是指定了緩衝區的用途
                gl.bufferData(gl.ARRAY_BUFFER,verticesTextCoords,gl.STATIC_DRAW);//往緩衝區寫資料 STATIC_DRAW對緩衝區最佳化   將頂點座標和紋理座標放進緩衝區
                
                var FSize=verticesTextCoords.BYTES_PER_ELEMENT;//數組中每個元素的位元組大小
                //alert(FSize);
                //設定頂點座標 從緩衝區取出座標
                var a_Position=gl.getAttribLocation(gl.program,‘a_Position‘);
                gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,5*FSize,0);//將緩衝區的資料傳入分配給attribute對象 2是定點的分量個數   3*FSize表示相鄰兩個頂點間相距的位元組數也可以理解為每隔3*FSize位元組取倆值 是這些 0表示它的其實 位移量就是從哪開始的
                gl.enableVertexAttribArray(a_Position);//開啟attribute變數
                
                
                //將紋理座標分配給webgl
                var a_TextCoord=gl.getAttribLocation(gl.program,‘a_TextCoord‘);
                gl.vertexAttribPointer(a_TextCoord,2,gl.FLOAT,false,5*FSize,3*FSize);
                gl.enableVertexAttribArray(a_TextCoord);
                
                //設定點的大小
                var a_PointSize=gl.getAttribLocation(gl.program,‘a_PointSize‘);
                gl.vertexAttribPointer(a_PointSize,1,gl.FLOAT,false,5*FSize,2*FSize);
                gl.enableVertexAttribArray(a_PointSize);
                return n;
            }
            function initTextures(gl,n){
                //alert(n);
                var texture=gl.createTexture();//建立紋理對象 用來管理紋理
                if(!texture){
                    console.log("failed to texture");
                    return false;
                }
                //u_Sampler是用來儲存紋理的
                var u_Sampler=gl.getUniformLocation(gl.program,‘u_Sampler‘);
                if(!u_Sampler){
                    console.log("failed to u_Sampler");
                    return false;
                }
                //載入圖片建立圖片對象非同步載入圖片載入完後調用loadTexture函數 未完成前也繼續執行下面的代碼
                var image=new Image();
                
                image.onload=function(){
                    loadTexture(gl,n,texture,u_Sampler,image);//將紋理單元的映像以及參數傳給取樣器
                };
                image.src="image/sky.jpg";
                return true;
            }
            
            function loadTexture(gl,n,texture,u_Sampler,image){
                //alert(image.height);
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1);//對映像進行Y軸反轉
                gl.activeTexture(gl.TEXTURE0);//開啟0號單元
                //console.log(gl.activeTexture(gl.TEXTURE0));
                gl.bindTexture(gl.TEXTURE_2D,texture);//將紋理對象綁定到紋理單元中 因為沒法直接操作紋理對象但是可以操作紋理單元
                gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);//配置紋理的參數
                gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);//在X軸上不足會自動填滿
                gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.MIRRORED_REPEAT);//在y軸上不足的灰自動tian
                gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,gl.RGB,gl.UNSIGNED_BYTE,image);//配置紋理映像
                gl.uniform1i(u_Sampler,0);//將0單元的紋理傳給紋理取樣器
                
                gl.clear(gl.COLOR_BUFFER_BIT);
                gl.drawArrays(gl.TRIANGLE_STRIP,0,n);
            }
    </script>
  </head>
 
  <body onload="main()">
       <canvas id="webgl" width="600" height="400"></canvas>
  </body>
</html>
 

WebGL學習筆記四點二

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.