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>
webgl学习笔记五-纹理的更多相关文章
- WebGL学习笔记五
		本章主要是对纹理的进一步讲解,我们很多时候需要将现实中已有 的图片在网页中展示出来而不是去创造图片,通过纹理 我们可以将光栅化的图形和图片纹理形成映射并且将图片在图形 中显示出来.基本过程与前几章一致 ... 
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
		好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ... 
- (转)Qt Model/View 学习笔记 (五)——View 类
		Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ... 
- java之jvm学习笔记五(实践写自己的类装载器)
		java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ... 
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
		中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ... 
- Typescript 学习笔记五:类
		中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ... 
- ES6学习笔记<五> Module的操作——import、export、as
		import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ... 
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
		目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ... 
- python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍
		python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ... 
随机推荐
- nodejs实现文件上传
			在使用ant-design的upload上传文件时,前端很好实现,那么我们如何实现node服务端呢? 服务端文件上传实现 var express = require('express'); var f ... 
- # 2017-2018-1 20155336《信息安全技术》实验二——Windows口令破解
			2017-2018-1 20155336<信息安全技术>实验二——Windows口令破解 实验原理 口令破解方法 口令破解主要有两种方法:字典破解和暴力破解. 字典破解是指通过破解者对管理 ... 
- gitlab在push代码的时候报错
			一.问题报错 gitlab在执行git pull origin master,拉取代码的时候报如下错误. $ git pull origin master remote: Counting objec ... 
- SaltStack入门篇(六)之部署Redis主从实现和Job管理
			一.部署Redis主从 需求: 192.168.56.11是主,192.168.56.12是从 redis监听自己的ip地址,而不是0.0.0.0 分析: linux-node1 安装 配置 启动 l ... 
- 你不需要jQuery You Don't Need jQuery
			转载:https://github.com/oneuijs/You-Dont-Need-jQuery/blob/master/README.zh-CN.md You Don't Need jQuery ... 
- python的种类
			Cpython Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚拟机上. Jyhton ... 
- Python数据分析开发环境
			准备工作 下载并安装最新版本的Anaconda 下载并安装最新版本的Visual Studio Code 编辑器 Tips: 可以选择自己喜欢并且熟悉的编辑器或IDE.如:VIM.Emacs.Note ... 
- [.NET] 使用HttpClient操作HFS (HTTP File Server)
			前言 本篇文章介绍如何使用HttpClient操作HFS (HTTP File Server),为自己留个纪录也希望能帮助到有需要的开发人员.关于HTTP File Server的介绍.安装.设定,可 ... 
- JS_正则表达式_验证中文字符
			正则表达式:"^[\u4e00-\u9fa5]{0,}$" . "/^[\u4E00-\u9FA5]{1,5}$/" 的含义: 在JS里,\uXXXX 是转义字 ... 
- C#Framework4.0支持异步async/await语法
			由于用户使用的是XP系统,但是程序里异步都是通过async/await代码来实现的,然而async/await需要Framework4.5版本才可以,而XP系统最高只能支持到Framework4.0, ... 
