webgl學習筆記五-紋理

寫在前面html

建議先閱讀下前面個人三篇文章。web

webgl學習筆記一-繪圖單點canvas

webgl學習筆記二-繪圖多點瀏覽器

webgl學習筆記三-平移旋轉縮放學習

術語 :webgl

  • 紋理 :圖像
  • 圖形裝配區域 :頂點着色器頂點座標信息
  • 裝配圖形 : 片元着色器裝配
  • 光柵化 :顯示在屏幕上的三角形是由片元(像素)組成的,因此還須要將圖形轉化爲片元,這個過程被稱爲光柵化。
  • 紋理圖像:映射的這個圖像稱爲紋理圖像
  • 紋素 : 組成紋理圖像的像素稱爲紋素
  • 紋理座標 : 是紋理圖像上的座標,經過紋理座標能夠在紋理圖像上獲取紋素顏色;

紋理繪圖流程code

  重點介紹紋理的流程。orm

  • 建立紋理對象
  • 加載紋理圖像
  • 配置屬性

demohtm

  • html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<canvas id="canvas" width="200px" height="200px"></canvas>



</body>
</html>
  • JavaScript
<script>

    window.onload = function () {

        //頂點着色器程序
        var VSHADER_SOURCE =
            "attribute vec4 a_Position;" +
            "attribute vec2 a_TextCoord;" + // 接受紋理座標
            "varying vec2 v_TexCoord;" +    // 傳遞紋理座標
            "void main() {" +
            //設置座標
            "gl_Position = a_Position; " +  // 設置座標
            //設置紋素
            "v_TexCoord = a_TextCoord; " +  // 設置紋理座標
            "} ";

        //片元着色器
        var FSHADER_SOURCE =
            "precision mediump float;" +  //須要聲明浮點數精度,不然報錯No precision specified for (float)
            "uniform sampler2D u_Sampler;" + // 取樣器
            "varying vec2 v_TexCoord;" +  // 接受紋理座標
            "void main() {" +
            //設置顏色
            "gl_FragColor = texture2D(u_Sampler, v_TexCoord);" +  // 設置顏色
            "}";

        //獲取canvas元素
        var canvas = document.getElementById('canvas');
        //獲取繪製webgl繪圖上下文
        var gl = canvas.getContext('webgl');
        if (!gl) {
            console.log("Failed");
            return;
        }
        //編譯着色器
//        (1)建立Shader(着色器)對象
//        (2)將着色器程序附加到Shader上
//        (3)編譯程序
        var vertShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertShader, VSHADER_SOURCE);
        gl.compileShader(vertShader);

        var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragShader, FSHADER_SOURCE);
        gl.compileShader(fragShader);
        //合併程序
//        (1)建立一個程序對象
//        (2)附加着色器
//        (3)連接着色器
//        (4)使用程序
        var shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertShader);
        gl.attachShader(shaderProgram, fragShader);
        gl.linkProgram(shaderProgram);
        gl.useProgram(shaderProgram);


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

        var n = initBuffers(gl, shaderProgram);
        initTexture(gl, shaderProgram, n);

        gl.clear(gl.COLOR_BUFFER_BIT);

        //繪製一個點
        gl.drawArrays(gl.POINTS, 0, 1);
    }


    // 使用緩衝區對象向頂點傳入多個頂點數據
    function initBuffers(gl, shaderProgram) {
        //頂點座標和顏色
        var vertices = new Float32Array([
            -0.5, 0.5, 0.0, 1.0,
            -0.5, -0.5, 0.0, 0.0,
            0.5, 0.5, 1.0, 1.0,
            0.5, -0.5, 1.0, 0.0
        ]);
        var n = 4;//點的個數
        //建立緩衝區對象
        var vertexBuffer = gl.createBuffer();

        //將緩衝區對象綁定到目標
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        //向緩衝區寫入數據
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        var FSIZE = vertices.BYTES_PER_ELEMENT;

        //獲取座標點
        var a_Position = gl.getAttribLocation(shaderProgram, "a_Position");
        //將緩衝區對象分配給a_Position變量
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
        //鏈接a_Position變量與分配給它的緩衝區對象
        gl.enableVertexAttribArray(a_Position);

        //獲取Color座標點
        var a_TextCoord = gl.getAttribLocation(shaderProgram, "a_TextCoord");
        //將緩衝區對象分配給a_Position變量
        gl.vertexAttribPointer(a_TextCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
        //鏈接a_Position變量與分配給它的緩衝區對象
        gl.enableVertexAttribArray(a_TextCoord);
        return n;
    }

    // 初始建立紋理,建立image對象
    function initTexture(gl, shaderProgram, n) {
        //建立紋理對象
        var texture = gl.createTexture();
        //獲取u_Sampler的存儲位置
        var u_Sampler = gl.getUniformLocation(shaderProgram, 'u_Sampler');

        //建立image對象
        var image = new Image();

        //加載紋理
        image.onload = function () {
            loadTexture(gl, n, texture, u_Sampler, image);
        };
        // 瀏覽器開始加載圖片 注意:必定是2^mx2^n尺寸的圖片
        image.src = "../../resources/st2_256*128.png";
        return true;

    }

    // 加載紋理圖像,配置屬性
    function loadTexture(gl, n, texture, u_Sampler, image) {

        //1.對紋理圖像進行Y軸反轉
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
        //2.開啓0號紋理單元
        gl.activeTexture(gl.TEXTURE0);
        //3.向target綁定紋理對象
        gl.bindTexture(gl.TEXTURE_2D, texture);

        //4.配置紋理參數
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        //5.配置紋理圖像
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

        //6.將0號紋理圖像傳遞給着色器
        gl.uniform1i(u_Sampler, 0);
        // 清空 <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        //繪製矩形
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);

    }

</script>
相關文章
相關標籤/搜索