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

效果图:

WebGL入门教程(一)-初识webgl中,知道如何绘制一个点

//绘制一个点
gl.drawArrays(gl.POINTS, 0, 1);

但是图形是有多个点组成,那么就应该考虑如何绘制多个点,WebGL提供了一种很方便的机制,缓冲区对象(buffer object),它是WebGL系统中的一块内存区域,它可以一次性向着色器传入多个顶点的数据,然后将这些数据保存在其中,供顶点着色器使用。

首先先找到三个点,操作步骤:

1.创建HTML5 canvas

2.获取画布 canvas 的 ID

3.获取WebGL

4.编译着色器

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

6.绘制图像

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

 4.编译着色器

修改顶点着色器,去掉gl_PointSize,这个只有绘制点的时候才有用

//顶点着色器程序
var VSHADER_SOURCE =
"attribute vec4 a_Position;" +
"void main() {" +
//设置坐标
"gl_Position = a_Position; " +
"} ";

 5.使用缓冲区对象向顶点传入多个顶点数据又分为五步

 5.1创建缓冲区对象

 //创建缓冲区对象
var vertexBuffer = gl.createBuffer();

 5.2绑定缓冲区对象

//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);

其中gl.ARRAY_BUFFER表示缓冲区对象包含了顶点的数据,要是换成gl.ELEMENT_ARRAY_BUFFER则表示包含了顶点的索引;vertexBuffer表示上一步创建的缓存区对象。

 5.3将数据写入缓冲区对象

//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);

其中:gl.ARRAY_BUFFER表示目标;vertices表示写入缓存区对象的数据(类型化数组);第三个参数有3种(

gl.STATIC_DRAW:表示只会向缓存区对象写入一次数据,但需要绘制很多次;
gl.STREAM_DRAW:表示只会向缓存区对象写入一次数据,然后绘制若干次;
gl.DYNAMIC_DRAW:表示会向缓存区对象多次写入数据,并绘制很多次;

其中第二个参数,类型化数组是WEBGL为了优化性能引入的一种特殊的数组,该数组不支持push,pop有(

Int8Array :8位整形数

UInt8Array :8位无符号整形数

Int16Array :16位整形数

UInt8Array :16位无符号整形数

Int32Array :32位整形数

UInt8Array :32位无符号整形数

Float32Array :单精度32位浮点数

Float64Array :双精度64位浮点数

)属性方法有get(index)、set(index,value)、set(array,offset)、length

这种数组一定要new,否则报错,错误信息如下:

GL ERROR :GL_INVALID_OPERATION :glDrawArrays: attempt to access out of range vertices in attribute 0

例如:

var vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5]);

 5.4将缓冲区对象分配给一个attribute变量

 //将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

第一个参数:指定待分配attribute变量的存储位置

第二个参数:指定缓存区中每个顶点的分量个数(1~4)

第三个参数:类型有,gl.UNSIGNED_BYTE无符号字节,gl.SHORT短整数,gl.UNSIGNED_SHORT无符号短整数,gl.INT整型,gl.UNSIGNED_INT无符号整型,gl.FLOAT浮点型。

第四个参数:表示是否将非浮点型的数据归到[0,1][-1,1]区间

第五个参数:相邻两个顶点的字节数。默认为0

第六个参数:表示缓存区对象的偏移量(以字节为单位),就是attribute变量从缓冲区中的何处开始存储。

 5.5开启attribute变量

//连接a_Position变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);

就是开启attribute变量,是缓存区对attribute变量分配生效,使顶点着色器能够访问缓冲区内的数据。

6.绘制图像

WebGL可以绘制的图形有:
gl.POINTS 一系列点,绘制v0,v1……。
线段 gl.LINES 一系列单独的线段,绘制(v0,v1),(v2,v3)……如果是奇数,最后一个省略。
线条 gl.LINE_STRIP 一系列连接的线段,绘制(v0,v1),(v1,v2),(v2,v3)……除了第一个和最后一个,其他的点点即是起点又是终点。
回路 gl.LINE_LOOP 一系列连接的线段,绘制(v0,v1),(v1,v2),(v2,v3)……(vn,v0),最后一个点会连接起点。
三角形 gl.TRIANGLES 一系列单独的三角形,绘制(v0,v1,v2),(v3,v4,v5)……如果不是3的倍数,剩下的将会被忽略。
三角带 gl.TRIANGLES_STRIP 一系列连接的三角形,绘制(v0,v1,v2),(v2,v1,v3),(v2,v3,v4)……以此类推,第二个是(v2,v1,v3)而不是(v1,v2,v3)是为了保持绘制按照逆时针绘制
gl.drawArrays(gl.TRIANGLES, 0, n);

完整代码:

html代码

<!DOCTYPE html>
<html>
<head>
<meta lang="en">
<meta charset="UTF-8">
<title>WebGL study</title>
<link href="../ClickedPoints/style.css">
<script type="text/javascript" src="../Triangle/js.js"></script>
</head>
<body>
<canvas id="canvas" width="200px" height="200px"></canvas>
</body>
</html>

javascript代码

/**
* Created by HBX on 2016/12/3.
*/
window.onload = function () { //顶点着色器程序
var VSHADER_SOURCE =
"attribute vec4 a_Position;" +
"void main() {" +
//设置坐标
"gl_Position = a_Position; " +
"} "; //片元着色器
var FSHADER_SOURCE =
"void main() {" +
//设置颜色
"gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +
"}";
//获取canvas元素
var canvas = document.getElementById('canvas');
//获取绘制二维上下文
var gl = canvas.getContext('webgl');
if (!gl) {
console.log("Failed");
return;
}
//编译着色器
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, VSHADER_SOURCE);
gl.compileShader(vertShader); var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, FSHADER_SOURCE);
gl.compileShader(fragShader);
//合并程序
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram); //获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position'); if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return;
} var n = initBuffers(gl,shaderProgram); if(n<0){
console.log('Failed to set the positions');
return;
}
// 清除指定<画布>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 清空 <canvas>
gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, n);
} function initBuffers(gl,shaderProgram) {
var vertices = new Float32Array([
0.0, 0.5, -0.5, -0.5, 0.5, -0.5
]);
var n = 3;//点的个数
//创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if(!vertexBuffer){
console.log("Failed to create the butter object");
return -1;
}
//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
//获取坐标点
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
//连接a_Position变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
return n; }

WebGL入门教程(二)-webgl绘制三角形的更多相关文章

  1. WebGL入门教程(五)-webgl纹理

    前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 WebGL入门教程(四)-webgl颜色 这里就需要用到 ...

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

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

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

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

  4. WebGL简易教程(三):绘制一个三角形(缓冲区对象)

    目录 1. 概述 2. 示例:绘制三角形 1) HelloTriangle.html 2) HelloTriangle.js 3) 缓冲区对象 (1) 创建缓冲区对象(gl.createBuffer( ...

  5. 无废话ExtJs 入门教程二十一[继承:Extend]

    无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...

  6. 无废话ExtJs 入门教程二十[数据交互:AJAX]

    无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...

  7. 无废话ExtJs 入门教程二[Hello World]

    无废话ExtJs 入门教程二[Hello World] extjs技术交流,欢迎加群(201926085) 我们在学校里学习任何一门语言都是从"Hello World"开始,这里我 ...

  8. VB6 GDI+ 入门教程[4] 文字绘制

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[4] 文字绘制 2009 年 6 月 18 日 7条评论 ...

  9. mongodb入门教程二

    title: mongodb入门教程二 date: 2016-04-07 10:33:02 tags: --- 上一篇文章说了mongodb最基本的东西,这边博文就在深入一点,说一下mongo的一些高 ...

随机推荐

  1. ClassNotFoundException: org.apache.catalina.loader.DevLoader 自己摸索,丰衣足食

    使用tomcat插件时遇到的问题: ClassNotFoundException: org.apache.catalina.loader.DevLoader 解决方案: 参考了许多文章,对我自己的目录 ...

  2. 利用gcc自带的功能-fstack-protector检测栈溢出及其实现

    最近又遇到了一个崩溃,栈回溯非常怪异. /lib/i386-linux-gnu/libc.so.(gsignal+0x4f) [0xb2b751df] /lib/i386-linux-gnu/libc ...

  3. Java Web ——http协议响应报文

    HTTP 响应报文 HTTP 响应报文由状态行.响应头部.空行 和 响应包体 4 个部分组成,如下图所示: 下面对响应报文格式进行简单的分析: 状态行:状态行由 HTTP 协议版本字段.状态码和状态码 ...

  4. MySQL主从复制原理及配置详细过程以及主从复制集群自动化部署的实现

    一.复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...

  5. Html报表用Excel打开保持表格线【Html报表模板】

    注:本人调试的最简版,前两处红色部分是为了输出Excel表格线:x:str表示输出为文本样式,避免被输出为科学计数法. <!DOCTYPE html PUBLIC "-//W3C//D ...

  6. 关于JavaScript设计模式(一)

    以后都在简书写文章了,所以这个转载我在简书中写的.地址这里 http://www.jianshu.com/p/c7b3c2c148c5

  7. 页面滚动到底部自动 Ajax 获取文章

    页面滚动到底部自动 Ajax 获取文章  代码如下 复制代码 var _timer = {};function delay_till_last(id, fn, wait) {    if (_time ...

  8. 奇怪的bug(ant-design)

    ant-motion模板代码启动报错. 多了一层 import 会导致 less 编译的顺序发生变化,很奇怪的问题,还需要再深入看看.目前 ant-d.less 可以先改成这样来解决: + @impo ...

  9. C语言 插入排序 算法导论chapter2

    #include <stdio.h> #define N 10 //INSERTION-SORT int main() { ,,,,,,,,,}; int key; ;j<N;j++ ...

  10. 修改jetty的默认端口号

    jetty默认端口是8080,修改端口号也很简单,首先进入到jetty服务器安装目录下会看到start.ini配置文件,这里就是jetty启动时加载的配置,其中包括要加载的模块,超时时间配置还有这里的 ...