绘制多个顶点

使用缓冲区对象

  1. 创建缓冲区对象

    var vertexBuffer = gl.createBuffer();
    
    if(!vertexBuffer) {
    console.log('Failed to create the buffer object ');
    return -1;
    }
  2. 绑定缓冲区对象

    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  3. 将数据写入缓冲区对象

    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  4. 将缓冲区对象分配给一个attribute变量

    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  5. 开启attribute变量

    gl.enableVertexAttribArray(a_Position);

类型化数组

使用类型化数组存储大量相同类型的数据,比如顶点的坐标和颜色数据。

var vertices = new Float32Array{
[0.0,0.5,-0.5,-0.5,0.5,-0.5]
};

使用drawArrays()函数绘制图形

第一个参数是代表不同的绘制图形的方式。



以上顺序的绘制图形效果如下所示:

图形的移动

利用表达式实现移动

//顶点着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform vec4 u_Translation;\n' +
'void main() {\n' +
' gl_Position = a_Position + U_Translation;\n' +
'}\n';
var Tx = 0.5,Ty = 0.5,Tz = 0.0;
...
function main()
{
var u_Translation = gl.getUniformLocation(gl.program,'u_Translation');
...
gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
}

即相同类型的变量之间的赋值操作,通过a_Position和u_Translation之间相加传给gl_Position;在gl.uniform4f最后一个分量为0.0的原因是这是一个平移矢量,不是一个点,因此在齐次坐标中最后一个分量是0.0;

通过以上代码后每次调用gl.drawArrays(gl.TRIANGLES,0,n)执行顶点着色器都会执行以下三步:

  1. 将顶点坐标传给a_Position;
  2. 向a_Position加上u_Translation;
  3. 结果赋值给gl_Position;

利用旋转矩阵实现移动

图形的旋转

描述一个旋转需要指明

  1. 旋转轴
  2. 旋转方向
  3. 旋转角度

利用表达式实现旋转

//顶点着色器
var VSHADER_SOURCE =
//x' = x cos b - y sin b
//y' = y sin b + y cos b
//z' = z
'attribute vec4 a_Position;\n' +
'uniform float u_CosB,u_SinB;\n' +
'void main() {\n' +
' gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n'+
' gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;\n'+
'}\n'; var angle = 90.0;
...
function main()
{
var radian = Math.PI * angle / 180.0;//转为弧度制
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
var u_CosB = gl.getUniformLocation(gl.program, 'u_CosB');
var u_SinB = gl.getUniformLocation(gl.program, 'u_SinB');
...
gl.uniform1f(u_CosB,cosB);
gl.uniform1f(u_SinB,sinB);
}

利用变换矩阵实现旋转

三阶矩阵实现

四阶矩阵(保持和移动阶数相同)

使用变换矩阵程序代码(旋转)

//顶点着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform mat4 u_xformMatrix;\n' +//变换矩阵的定义,使用mat4表示4阶
'void main() {\n' +
' gl_Position = u_xformMatrix * a_Position;\n' +
'}\n'; var angle = 90.0;
...
function main()
{
var radian = Math.PI * angle / 180.0;//转为弧度制
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
var xformMatrix = new Float32Array{[
cosB, sinB, 0.0, 0.0,
-sinB, cosB, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]};
...
var u_xformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix');
...
gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
}

WebGL中矩阵元素是按照列主序存储在数组中的

如[a,e,i,m,b,f,i,n,c,g,k,o,d,n,l,p]排序:

平移的变换矩阵实现代码和旋转类似。

图形的缩放

利用变换矩阵实现

代码和上述旋转代码类似。

WebGL学习笔记(二)的更多相关文章

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

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

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

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

  3. WebGL学习笔记二

    前一章就是第二章主要学的是通过WebGL实现先是在webGL内赋值,但是不实用后来通过定义attribute和uniform存储限定符来将javascript中的数据传到webGL中,大致的流程是1. ...

  4. webgl学习笔记五-纹理

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

  5. webgl学习笔记四-动画

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

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

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

  7. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  8. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  9. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  10. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

随机推荐

  1. Scala_运算符

    Scala运算符与操作数的位置关系,可分为  前缀运算符.中缀运算符.后缀运算符 算术运算符 + - * / % ++ -- 关系运算符 == != < > >= <= 逻辑运 ...

  2. Windows全版本KMS激活脚本

    搭建了个KMS服务器,制作了个批处理激活脚本,所有代码可以看到,让你再也不用担心系统会被有些激活工具强改主页,留有后门的风险了. 本脚本可以激活Windows全版本,安全.绿色. 1.首先你的系统必须 ...

  3. JavaWeb总结(六)

    获取原始表单数据 - POST请求不仅可以传输文本信息还可以传输二进制数据 - 如果想得到请求中参数的原始字节数据,可以使用HttpServletRequest对象提供的getInputSteam() ...

  4. .net core中automapper的使用

    automapper 是将两个类中的相同字段进行映射,也可以指定字段进行映射:将 UserDao的id 映射为 User 的age CreateMap<UserDao, User>() . ...

  5. 10min 手写一个内存监控系统

    本文的目的在于,尽可能用简单的代码,让大家了解内存监控的原理,及思想.更容易去理解Nagios.Zabbix.Ganglia监控原理,文章最后还有视频教程链接哦,从零敲出来的全过程 思路分为下面几块: ...

  6. 关于SDK-manager中我们需要下载哪些?

    废话少说,直接看图说话…… 图片取自博客文章——链接跳转:点击跳转

  7. 大数据中HBase的Java接口封装

    该文前提为已经搭建好的HBase集群环境,参见 HBase集群搭建与配置 ,本文主要是用Java编写一个Servlet接口,部署在Tomcat服务器上,用于提供http的接口供其他地方调用,接口中集成 ...

  8. Fortran的数组与指针

    个人理解,欢迎指正 指针就是记录数据的内存地址的变量.指针可以指向单个变量,也可以指向数组. 数组是一个概念,是若干个类型相同的元素的有序集合.在Fortran语言中,数组中存放的元素,可以是整数,实 ...

  9. Python科学计算库-Numpy

    NumPy 是 Python 语言的一个扩充程序库.支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库,也是学习 python 必学的一个库. 1. 读取文件 numpy.gen ...

  10. hdu1754 I Hate It(线段树单点更新,区间查询)

    传送门 有更新单个学生成绩和查询某个区间内学生成绩最大值两种操作 线段树代码 #include<bits/stdc++.h> using namespace std; +; using n ...