前几章对图形图形内部多是 以纯色填充,但是现实中已经有许多好的图片了我们没必要一点点画,这一章第五章就是将图片以纹理的形式加载到片元中,主要过程如下,首先是定义点的坐标的attribute变量用于在javascript中 赋值,接下来定义varying 的vec2的变量用于将纹理坐标从顶点着色器传给片元着色器 在片元着色器中定义取样器左右存储纹理图像和相关参数,接下来就是为各个变量赋值,赋值方法与前面一直,先是创建缓冲区,绑定矩阵,写入数据,获取变量存储地址,再就是写入缓冲区数据,最后激活变量,这样就为顶点坐标和纹理坐标赋值了,最后是对取样器赋值 取样器是uniform的 先创建纹理对象,获取取样器地址,获取图像对象,设置图像Y轴反转,因为无法对纹理对象直接操作所以指定纹理单员,激活单元,将纹理对象和纹理单元绑定,配置纹理参数,配置纹理图像,最后取样器赋值,然后画图形。

上代码:

<!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学习笔记四点一

    上一章是对图形的变换,这一章的第一节主要介绍了光栅化的过程,在创建多个颜色的三角形的过程中顶点着点器的过程如下 ,1.首先通过attribute的变量从javascript中获取数据,根据drawAr ...

  2. WebGL学习笔记(二)

    目录 绘制多个顶点 使用缓冲区对象 类型化数组 使用drawArrays()函数绘制图形 图形的移动 图形的旋转 图形的缩放 绘制多个顶点 使用缓冲区对象 创建缓冲区对象 var vertexBuff ...

  3. WebGL学习笔记(二):WebGL坐标系及基础几何概念

    WebGL使用的是正交右手坐标系,且每个方向都有可使用的值的区间,超出该矩形区间的图像不会绘制: x轴最左边为-1,最右边为1: y轴最下边为-1,最上边为1: z轴朝向你的方向最大值为1,远离你的方 ...

  4. webgl学习笔记二-绘图多点

    写在前面 建议先看下第一篇webgl学习笔记一-绘图单点 第一篇文章,介绍了如何用webgl绘图一个点.接下来本文介绍的是如何绘制多个点.形成一个面. webgl提供了一种很方便的机制,即缓冲区对象, ...

  5. WebGL学习笔记二——绘制基本图元

    webGL的基本图元点.线.三角形 gl.drawArrays(mode, first,count) first,代表从第几个点开始绘制即顶点的起始位置 count,代表绘制的点的数量. mode,代 ...

  6. html5标签video(播放器)学习笔记(二)-基本操作

    html5标签video(播放器)学习笔记(二)-基本操作 subying 发布时间: 2014/12/01 23:59 阅读: 13008 收藏: 21 点赞: 3 评论: 0 摘要 本文介绍了ht ...

  7. webgl学习笔记五-纹理

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

  8. webgl学习笔记四-动画

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放   下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘 ...

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

    写在前面 建议先阅读下前面我的两篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 平移 1.关键点说明 顶点着色器需要加上 uniform vec4 u_Translation ...

随机推荐

  1. 【jq】JQuery对select的操作

    下拉框 <select id="selectID" name="selectName"> <option vlaue="1" ...

  2. 求助:将以下ES5格式代码转换为ES6格式!!!

    function Slider(id){     //属性     //  1. 通过id获取元素对象(大盒子)     this.bigBox = document.getElementById(i ...

  3. C++学习第一天(helloword)

    C++编译过程 #include <iostream> //iostream 提供了一个叫命名空间的东西,标准的命名空间是std 包含了有关输入输出语句的函数 // input&^ ...

  4. 第一次作业:基于Linux 4.5的进程模型与调度器分析

    1.操作系统是怎么组织进程的? 1.1什么是线程,什么是进程: 刚接触时可能经常会将这两个东西搞混.简单一点的说,进程是一个大工程,线程则是这个大工程中每个小地方需要做的东西(在linux下看作&qu ...

  5. OpenID Connect Core 1.0(一)介绍

    IdentityServer4是基于OpenID Connect and OAuth 2.0框架,OpenID Connect Core 1.0是IdentityServer4最重要的文档 By 道法 ...

  6. C语言学习记录_2019.02.06

    break语句的作用:当执行到break,则跳出循环,免去不必要的循环次数,节省时间和资源.-----跳出循环,结束循环: continue:跳过这一次循环剩下的语句,进入到下一轮循环.-----跳到 ...

  7. 泰坦尼克(Titanic)生存因素可视化

    数据来源: kaggle 分析工具:Python 3.6 & jupyter notebook 附上数据:链接: https://pan.baidu.com/s/1D7JNvHmqTIw0Oo ...

  8. 不能存在多个@ManyToMany(fetch=FetchType.EAGER)

    @LazyCollection(LazyCollectionOption.FALSE) 原地址:https://stackoverflow.com/questions/4334970/hibernat ...

  9. Python_sklearn机器学习库学习笔记(六) dimensionality-reduction-with-pca

    # 用PCA降维 #计算协方差矩阵 import numpy as np X=[[2,0,-1.4], [2.2,0.2,-1.5], [2.4,0.1,-1], [1.9,0,-1.2]] np.c ...

  10. 洛咕 P3338 [ZJOI2014]力

    好久没写过博客了.. 大力推式子就行了: \(E_i=\sum_{j<i}\frac{q_j}{(i-j)^2}+\sum_{j>i}\frac{q_j}{(j-i)^2}\) 那么要转化 ...