本章主要是对纹理的进一步讲解,我们很多时候需要将现实中已有 的图片在网页中展示出来而不是去创造图片,通过纹理 我们可以将光栅化的图形和图片纹理形成映射并且将图片在图形 中显示出来。基本过程与前几章一致,在着色器中主要是添加了一个取样器的变量作用是从纹理单元中取出图形在不同坐标的片元上显示出来,这里先要设置纹理坐标将纹理坐标和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. ios学习路线—Objective-C(属性修饰符)

    readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...

  2. CentOS7.3安装mysql数据库

    Mysql数据库安装 1.环境 操作系统:CentOS 7.3 软件:MySQL 5.7 下载链接:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5 ...

  3. (一)U盘安装ubuntu18.04.1

    我选择安装的ubuntu18.04.1因为我的显卡是Amd RX470 ,Amd官方所兼容的版本是18.04.1, 跳过的坑:用18.04.2 18.04.3 安装amdgpu驱动各种报错 0X:下载 ...

  4. json keyname map

    var obj = { fname:'zhao', lname:'yao', parents:{ father:'zhao' }, children:[ { dname:'zhaoyiyi' } ] ...

  5. 【python3】将视频转换为代码视频

    一.环境准备 1.需要安装opencv,直接安装 pip install opencv-python 2.需要安装ffmpeg ,直接解压免安装,下载传送门: 将 ffmpeg.exe 的路径复制,替 ...

  6. pythonDjango开发-创建django程序

    1.创建jgango程序 a.命令 cmd命令行下 进入到需要创建项目的路径下 django-admin startproject mysite  创建项目 cd mysite 进入项目文件夹 pyt ...

  7. jsp编译原理

    jsp运行时都要先转换成servlet,使用tomcat时会在tomcat安装目录下的work生成一系列的运行的项目文件夹,文件下面含有.java文件和编译后的.class文件.jsp最终转化为ser ...

  8. jmeter no-gui模式动态传递场景参数

    jmeter进行性能压测时,有时候需要在linux上no-gui模式下运行,为了在no-gui模式下更方便的设置脚本的运行的场景, 将脚本的线程数,运行时间设置为动态参数,可以在脚本运行时动态设置“线 ...

  9. Bootstrap学习笔记(3)--表格\表单\图片

    Bootstrap表格   表格类:    .table只会在表行之间增加横线;    .table-striped会在表格行之间增减斑马线;    .table-hover会给表设置鼠标悬停状态; ...

  10. 阿超的烦恼 javaScript篇

    幼儿园级1-100随机数运算 实现目标 1.点击随机生成两个数并进项随机的四则运算. 2.答案暂时隐藏,等孩子做完题后点击答案处显示答案. 3.背景设置的卡通些,激发孩子阅读兴趣........... ...