前面文章:

WebGL入门教程(一)-初识webgl

WebGL入门教程(二)-webgl绘制三角形

WebGL入门教程(三)-webgl动画

WebGL入门教程(四)-webgl颜色

这里就需要用到纹理映射,他就是将一张真实图片贴到一个几何图像表面。

纹理图像:映射的这个图像称为纹理图像;

纹素:组成纹理图像的像素称为纹素;

纹理坐标:是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹素颜色;

效果图:

操作步骤:

1.创建HTML5 canvas

2.获取画布 canvas 的 ID

3.获取WebGL

4.编译着色器,合并程序

5.使用缓冲区对象向顶点传入多个顶点数据

6.创建纹理,加载纹理图像,配置属性,在webgl中使用它;

7.加载纹理图像,配置属性,在webgl中使用它;

以上1~3参考:http://www.cnblogs.com/bsman/p/6128447.html

4.编译着色器

 //顶点着色器程序
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);" + // 设置颜色
"}";

解释:在顶点着色器中为每个顶点指定纹理坐标,然后在片元着色器中根据每个片元的纹理坐标从纹理图像中抽取纹素颜色

  5.使用缓冲区对象向顶点传入多个顶点数据

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;
}

 6.初始创建纹理,创建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 = "../TexturedQuad/shan.jpg";
return true; }
u_Sampler代表从纹理图像中获取纹理颜色
gl.createTexture();创建纹理对象以存储纹理对象;gl.TEXTURE0~gl.TEXTURE7是管理纹理图像的8个纹理单元
注意:这样图片的尺寸一定是2^mx2^n尺寸的图片,不然会报错 WebGL: drawArrays: texture bound to texture unit 0 is not renderable.
浏览器异步加载图片

 7.加载纹理图像,配置属性,在webgl中使用它;

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); }

7.1对纹理图像进行Y轴反转,因为WebGL纹理坐标系统的t轴(分为t轴和s轴)的方向和图片的坐标系统Y轴方向相反。因此将Y轴进行反转。

gl.pixelStorei 第一个参数:有两个,一个UNPACK_FLIP_Y_WEBGL代表对Y轴反转,默认为false;一个UNPACK_PREMULTIPLY_ALPHA_WEBGL代表将图像   RGB颜色值得每一个分量乘以A,默认值为false;

7.2开启0号纹理单元

WebGL通过纹理单元的机制来同时使用多个纹理,gl.TEXTURE0~gl.TEXTURE7是管理纹理图像的8个纹理单元

7.3绑定纹理对象

gl.bindTexture两个参数

第一个参数:有两个选择TEXTURE_2D代表二维纹理,TEXTURE_CUBE_MAP 立方体纹理;

第二个参数:表示绑定的纹理单元

7.4配置纹理参数

gl.texParameteri三个参数

第一个参数:有两个选择TEXTURE_2D代表二维纹理,TEXTURE_CUBE_MAP 立方体纹理;

第二个参数:有4个纹理参数

1.TEXTURE_MAX_FILTER:放大方法   默认:gl.LINEAR

2.TEXTURE_MIN_FILTER:缩小方法    默认:gl.NEAREST_MIPMAP_LINEAR

3.TEXTURE_WRAP_S: 水平填充方法   默认:gl.REPEAT

4.TEXTURE_WRAP_T:   垂直填充方法   默认:gl.REPEAT

第三个参数:

gl.LINEAR:使用距离新像素中心最近的四个像素的颜色值得加权值平均(图片质量好,但是开销大)

gl.NEAREST_MIPMAP_LINEAR:使用原纹理上的距离映射后像素中心最近的那个像素的颜色值作为新像素的值

gl.REPEAT:平铺式的重复纹理

gl.REPEAT:镜像对称式的重复纹理

gl.REPEAT:使用纹理图像边缘值

7.5配置纹理图像

gl.texImage2D有六个参数

第一个参数:有两个选择TEXTURE_2D代表二维纹理,TEXTURE_CUBE_MAP 立方体纹理;

第二个参数:默认为0,涉及到三维再说

第三个参数:图像的内部格式

有:gl.RGB(红绿蓝)、gl.RGBA(红绿蓝透明度)、gl.ALPHA(0.0,0.0,0.0,透明度)、gl.LUMINANCE(L、L、L、1L:流明)、

       gl.LUMINANCE_ALPHA(L、L、L,透明度)、

       流明:表示我们感知到的物体表面的亮度,等于红绿蓝颜色分量值的加权平均来计算流明

第四个参数:纹理的数据格式,必须与第三个参数相同

第五个参数:纹理数据格式 UNSIGNED_BYTE:表示无符号整形,每一个颜色分量占据1字节

UNSIGNED_SHORT_5_6_5:表示RGB,每一个分量分别占据占据5,6,5比特

UNSIGNED_SHORT_4_4_4_4:表示RGBA,每一个分量分别占据占据4,4,4,4比特

UNSIGNED_SHORT_5_5_5_1:表示RGBA,每一个分量分别占据占据5比特,A分量占据1比特

第六个参数:纹理图像的image对象

7.6将0号纹理图像传递给着色器

uniform1i(u_Sampler, 0);这里和上面的片元着色器"gl_FragColor = texture2D(u_Sampler, v_TexCoord);" + // 设置颜色,有联系

其中:sampler2D绑定到gl.TEXTURE_2D上,samplerCube绑定到gl.TEXTURE_CUBE_MAP上

WebGL入门教程(五)-webgl纹理的更多相关文章

  1. WebGL入门教程(四)-webgl颜色

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 颜色效果图: 操作步骤: 1.创建HTML5 canva ...

  2. WebGL入门教程(三)-webgl动画

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL动画有移动.旋转和缩放,我们将移动.旋转和缩放图形,然后将其绘制到屏幕上,称为变换(tr ...

  3. WebGL入门教程(二)-webgl绘制三角形

    前面已经介绍过了webgl,WebGL入门教程(一)-初识webgl(http://www.cnblogs.com/bsman/p/6128447.html),也知道了如何绘制一个点,接下来就用web ...

  4. 无废话ExtJs 入门教程五[文本框:TextField]

    无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: ...

  5. PySide——Python图形化界面入门教程(五)

    PySide——Python图形化界面入门教程(五) ——QListWidget 翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-the-qlistw ...

  6. Elasticsearch入门教程(五):Elasticsearch查询(一)

    原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  7. RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)

    原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

  8. WebGL简易教程(十一):纹理

    目录 1. 概述 2. 实例 2.1. 准备纹理 2.2. 配置纹理 2.3. 使用纹理 3. 结果 4. 参考 1. 概述 在之前的之前的教程<WebGL简易教程(九):综合实例:地形的绘制& ...

  9. WCF入门教程五[WCF的通信模式]

    一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...

随机推荐

  1. 【10-25】intelliji ide 学习笔记

    快捷键 /** alter+enter 导包,异常处理等提示 psvm 快速main函数 sout 快速sysout语句 fi 快速for循环 ctrl+d 重复一行 Ctrl+X 删除行 Ctrl+ ...

  2. sql注入时易被忽略的语法技巧以及二次注入

    那些容易被忽略.容易被弄错的地方 sql注入时的技巧 ========================================================================= ...

  3. Eclipse常用快捷键汇总

    经常使用eclipse进行开发,不掌握快捷键步行啊,在此整理了一些快捷键,大家要灵活运用啊... (注:红色标出来的是经常使用到的快捷键,磨刀不误砍柴工啊...) Ctrl+1 快速修复(最经典的快捷 ...

  4. android中xml tools属性详解

    第一部分 安卓开发中,在写布局代码的时候,ide可以看到布局的预览效果. 但是有些效果则必须在运行之后才能看见,比如这种情况:TextView在xml中没有设置任何字符,而是在activity中设置了 ...

  5. Qt - 错误总结 - 在自定义类头文件中添加Q_OBJECT 编译时报错(undefined reference to ‘vtable for xxThread)

    错误提示:在添加的QThread子类头文件添加Q_OBJECT时,编译程序,出现"undefined reference to 'vtable for xxThread'"错误提示 ...

  6. c/c++中关于sizeof、strlen的使用说明

    sizeof: 一般指类型.变量等占用的内存大小(由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小) strlen: c字符串的长度(参数必须是字符型指针 char*,当数组名作 ...

  7. 转:IOC框架

    CSND上看了王泽滨的博客关于IOC的,觉得说的很透彻,地址为:http://blog.csdn.net/wanghao72214/article/details/3969594 1 IoC理论的背景 ...

  8. 在cygwin部署hadoop出现的问题:$ ./bin/hadoop version 显示错误: 找不到或无法加载主类 org.apache.hadoop.util.VersionInfo

    解决方案 找到hadoop主目录的bin文件夹下的hadoop文件,将倒数第二行 exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS & ...

  9. Uiautomator-----新建工程

    一.前提: 安装好安卓开发环境:jdk.安卓SDK.ADT.ant.eclipse   配置环境   二.新建uiautomator工程 1.打开eclipse,新建一个工程(这个网上资料很多,大家自 ...

  10. lanmp之一 (动静分离)

    一.lanmp--需求篇 1. 准备两台centos 6,其中一台机器跑mysql,另外一台机器跑apache,nginx + php 2. 同时安装apache和nginx,其中nginx启动80端 ...