本章主要是对纹理的进一步讲解,我们很多时候需要将现实中已有 的图片在网页中展示出来而不是去创造图片,通过纹理 我们可以将光栅化的图形和图片纹理形成映射并且将图片在图形 中显示出来。基本过程与前几章一致,在着色器中主要是添加了一个取样器的变量作用是从纹理单元中取出图形在不同坐标的片元上显示出来,这里先要设置纹理坐标将纹理坐标和webGL坐标形成映射,然后是创建图像对象,创建纹理对象,开启某个纹理单元,将纹理对象与纹理单元绑定,配置纹理参数,将图像对象添加进纹理单元,将纹理单元中的纹理传给取样器,取样器根据纹理坐标和webGL坐标的对应关系显示纹理图像。

效果如下:

看代码:

<!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="data: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学习笔记五的更多相关文章

  1. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

  2. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  3. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  4. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  8. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  9. python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍

    python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...

随机推荐

  1. html5复习--canvas

    一.简介 <canvas>是html5新增的标签,可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素.它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至 ...

  2. MySQL原生语句个人补漏

    # insert插入insert into table_name (field1,field2...fieldn) **values** (value1,value2...valuen);所有列需添加 ...

  3. c语言数组放在main函数里面和外面的区别

    最近a算法题的时候碰到一道题:一个数列前三项都为1,之后每项的值等于前三项之和,求第20193024项的最后4位数字.一开始写的代码如下: 结果一直爆 Terminated due to signal ...

  4. 时间序列深度学习:seq2seq 模型预测太阳黑子

    目录 时间序列深度学习:seq2seq 模型预测太阳黑子 学习路线 商业中的时间序列深度学习 商业中应用时间序列深度学习 深度学习时间序列预测:使用 keras 预测太阳黑子 递归神经网络 设置.预处 ...

  5. Modelsim SE自动化仿真——如何将.do文件中自定义的库链接到testbench顶层模块

    我们用Modelsim SE进行仿真时,为了方便,一般会编写.do文件来启动当前仿真.关于.do文件的编写,一般网上都有成型的模板,我们只要稍微改几个参数,就可以符合我们的仿真需求了.但是如果仿真时需 ...

  6. MySQL易忘知识点梳理

    一.零碎知识 1.mysql where子句区分大小写:WHERE BINARY 2.判断是否为null,只能用is null,is not null,不能用=null或!=null 3.函数 4.S ...

  7. Python之时间模块、random模块、json与pickle模块

    一.时间模块 1.常用时间模块 import time # 时间分为三种格式 #1.时间戳---------------------以秒计算 # start= time.time() # time.s ...

  8. How to: Provide Credentials for the Dashboards Module when Using External Data Sources

    XAF中使用dashboard模块时,如果使用了sql数据源,可以使用此方法提供连接信息 https://www.devexpress.com/Support/Center/Question/Deta ...

  9. SQL Server Management Studio 键盘快捷键

    光标移动键盘快捷键 操作 SQL Server 2012 SQL Server 2008 R2 左移光标 向左键 向左键 右移光标 向右键 向右键 上移光标 向上键 向上键 下移光标 向下键 向下键 ...

  10. 利用VS2015开发python版本的caffe应用

    打开VS2015,选择“新建项目”->“其它语言”->“python”,VS会提示你安装PTVS(Python Tools for Visual Studio)插件,安装完毕后即可开始py ...