zoukankan      html  css  js  c++  java
  • webgl学习笔记五-纹理

    写在前面

    建议先阅读下前面我的三篇文章。

    webgl学习笔记一-绘图单点

    webgl学习笔记二-绘图多点

    webgl学习笔记三-平移旋转缩放

    术语 :

    • 纹理 :图像
    • 图形装配区域 :顶点着色器顶点坐标信息
    • 装配图形 : 片元着色器装配
    • 光栅化 :显示在屏幕上的三角形是由片元(像素)组成的,所以还需要将图形转化为片元,这个过程被称为光栅化。
    • 纹理图像:映射的这个图像称为纹理图像
    • 纹素 : 组成纹理图像的像素称为纹素
    • 纹理坐标 : 是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹素颜色;

    纹理绘图流程

      重点介绍纹理的流程。

    • 创建纹理对象
    • 加载纹理图像
    • 配置属性

    demo

    • 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>
    
  • 相关阅读:
    django.db.utils.OperationalError: no such table: auth_user
    Python 爬虫 去掉网页注释,去掉网页注释
    Python 爬虫实例(6)—— 爬取蚂蚁免费代理
    HTTPSConnectionPool(host='xxxxx', port=443): Max retries exceeded with url:xxxxxxxx (Caused by NewConnectionError('<urllib3.connect,Max retries exceeded with ,(Caused by NewConnectionError
    requests.exceptions.MissingSchema: Invalid URL 'xxxxxxxxxxxxx': No schema supplied. Perhaps you meant xxxxxxxxxxxxx
    redis安装和配置(一)
    Python 统计代码的行数,Python脚本 统计代码
    Python 实现根据不同的程序运行环境存放日志目录,Python实现Linux和windows系统日志的存放
    Changing SID Server 2012
    [转]VMware Workstation网络连接的三种模式
  • 原文地址:https://www.cnblogs.com/chenmo-xpw/p/7470376.html
Copyright © 2011-2022 走看看