webgl绘制图形API——drawArrays、drawElements
文章目录
- 前言
- gl.drawArrays()——按顶点绘制
- 可绘制基本类型
- 绘制矩形和圆形
- gl.drawElements()——按索引绘制
- 使用规范
- 绘制矩形
- 总结
前言
gl.drawArrays()作为webgl中常用的函数图形绘制方法,可以在浏览器按照指定的模式绘制图形,与之相对的gl.drawElements()函数也是常用的绘制函数,本文将介绍二者的区别与使用。
gl.drawArrays()——按顶点绘制
可绘制基本类型
gl.drawArrays(mode, first, count)的使用在webgl图形绘制基础中有过详细的介绍,它的mode参数其实十分强大,可以按照不同的规则绘制不同的图形,可直接绘制的图形有七种,这七种图形是绘制其它各种复杂图形的基础。
参数名 | 图形 | 描述 |
---|---|---|
gl.POINTS | 点 | 一系列点,依次绘制 |
gl.LINES | 线段 | 每两个一组绘制线段,若点的数目为奇数,最后一个点会被舍弃 |
gl.LINES_STRIP | 线条 | 所有的点依次相连 |
gl.LINE_LOOP | 回路 | 再线条的基础上,将首尾点相连 |
gl.TRIANGLES | 三角形 | 每三个一组绘制三角形,若点的数目无法被三整除,剩余的点会被舍弃 |
gl.TRIANGLES_STRIP | 三角带 | 一系列条带状的三角形,每个三角形都存在一条边共享 |
gl.TRIANGLES_FAN | 三角扇 | 类似于扇形的图形 |
绘制矩形和圆形
绘制矩形可以通过两个三角形完成,要注意顶点数据必须按照三角形逆时针
方向给出。
const vertices = new Float32Array([// 第一个三角形-0.3, 0.3, -0.3, -0.3,0.3, -0.3,// 第二个三角形0.3, -0.3, 0.3, 0.3,-0.3, 0.3,])
绘制圆形的原理相似,当相同大小的三角形具备同一个顶点
并组成一个闭环时,就可以近似视为圆。三角形数越多,圆形越近似。
当用十个点绘制时:
const _circle = [];for (let i = 0; i <= 10; i++) {const angle = i * Math.PI * 2 / 10; // 把2Π分成10份_circle.push(0 + 0.3 * Math.sin(angle), 0 + 0.3 * Math.cos(angle));}const circle = new Float32Array(_circle);
当用一百个点绘制时:
const _circle = [];for (let i = 0; i <= 100; i++) {const angle = i * Math.PI * 2 / 100; // 把2Π分成100份_circle.push(0 + 0.3 * Math.sin(angle), 0 + 0.3 * Math.cos(angle));}const circle = new Float32Array(_circle);
完整代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>webgl</title><script src="./lib.js"></script><meta name="viewport" content="width=device-width, initial-scale=1.0" /><style>body {margin: 0;padding: 0;}canvas {margin: 50px 30px;width: 500px;height: 500px;}</style>
</head><body><canvas id="canvas"></canvas><script>/** @type {HTMLCanvasElement} *///------------------------------------------------------创建画布// 获取webgl绘图上下文const gl = canvas.getContext('webgl');if (!gl) {throw new Error('WebGL not supported');}gl.clear(gl.COLOR_BUFFER_BIT)const vertex = `attribute vec4 aPosition;void main() {gl_Position = aPosition;gl_PointSize = 10.0;}`const fragment = `precision highp float;void main(){gl_FragColor =vec4(1.0,0.0,1.0,1.0);}`// 创建programconst program = initShader(gl, vertex, fragment)// 获取attribute变量的数据存储位置const aPosition = gl.getAttribLocation(program, 'aPosition');// 创建缓冲区对象const buffer = gl.createBuffer();// 绑定缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, buffer);// 传入的数据const vertices = new Float32Array([// 第一个三角形-0.3, 0.3,-0.3, -0.3,0.3, -0.3,// 第二个三角形0.3, -0.3,0.3, 0.3,-0.3, 0.3,])const _circle = [];for (let i = 0; i <= 100; i++) {const angle = i * Math.PI * 2 / 100; // 把2Π分成100份_circle.push(0 + 0.3 * Math.sin(angle), 0 + 0.3 * Math.cos(angle));}const circle = new Float32Array(_circle);// 开辟空间并写入数据gl.bufferData(gl.ARRAY_BUFFER, circle, gl.STATIC_DRAW)// 缓冲区对象分配给attribute变量gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0)// 开启attribue变量gl.enableVertexAttribArray(aPosition)// 开始绘制gl.drawArrays(gl.TRIANGLE_FAN, 0, 1000)</script>
</body></html>
gl.drawElements()——按索引绘制
使用规范
在绘制矩形时,实际上只需要四个顶点,可是使用gl.drawArrays却存储了六个顶点,每个顶点大小为 4 * 6 = 24 个字节,绘制矩形就浪费了 48
字节的空间,为了避免这种浪费,WebGL 提供了按照顶点索引进行绘制的方法gl.drawElements
节省存储空间。
drawElements(mode, count, type, offset): 从数组数据中按照指定模式渲染图元。
- mode:绘制模式,与gl.drawArrays() 相同
- count: 绑定元素数组缓冲区的元素数
- type:元素数组缓冲区中值的类型,枚举如下:
— gl.UNSIGNED_BYTE
— gl.UNSIGNED_SHORT- offset:元素数组缓冲区中的字节偏移量
绘制矩形
效果
完整代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>webgl</title><script src="./lib.js"></script><meta name="viewport" content="width=device-width, initial-scale=1.0" /><style>body {margin: 0;padding: 0;}canvas {margin: 50px 30px;width: 500px;height: 500px;}</style>
</head><body><canvas id="canvas"></canvas><script>/** @type {HTMLCanvasElement} *///------------------------------------------------------创建画布// 获取webgl绘图上下文const gl = canvas.getContext('webgl');if (!gl) {throw new Error('WebGL not supported');}gl.clear(gl.COLOR_BUFFER_BIT)const vertex = `attribute vec4 aPosition;void main() {gl_Position = aPosition;gl_PointSize = 10.0;}`const fragment = `precision highp float;void main(){gl_FragColor =vec4(1.0,0.0,1.0,1.0);}`// 创建programconst program = initShader(gl, vertex, fragment)// 获取attribute变量的数据存储位置const aPosition = gl.getAttribLocation(program, 'aPosition');// 创建缓冲区对象const buffer = gl.createBuffer();// 绑定缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, buffer);// 传入的数据const vertices = new Float32Array([// 第一个三角形-0.3, 0.3,-0.3, -0.3,// 0.3, -0.3,// 第二个三角形0.3, -0.3,0.3, 0.3,// -0.3, 0.3,])// 索引缓冲区const index = new Uint16Array([0, 1, 2, 0, 2, 3])// 开辟空间并写入数据gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)// 缓冲区对象分配给attribute变量gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0)// 开启attribue变量gl.enableVertexAttribArray(aPosition)const indexBuffer = gl.createBuffer();//绑定索引缓冲区gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);//向索引缓冲区传递索引数据gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, index, gl.STATIC_DRAW);// 开始绘制gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);</script>
</body></html>
总结
gl.drawArrays()
- 可绘制基本类型
- gl.drawArrays()绘制矩形和圆形
gl.drawElements()按照索引绘制
- 使用规范
- 绘制矩形
webgl绘制图形API——drawArrays、drawElements相关推荐
- canvas绘制图形API(一)
canvas元素的基础知识 canvas元素是HTML5中的一个新增的重要元素,专门用来绘制图形.在页面上放置一个canvas元素,就相当于在页面上放置了一块"画布",可以在其中进 ...
- webgl绘制客厅房间的家具+座椅板凳床
一.开发环境说明 开发软件:webstorm 浏览器 : 火狐firefox 编程语言:webgl 二.内容说明 1.内容要求 实现一个小型的3D客厅环境,包括对象建模.照明.摄像机设置:必须使用纯的 ...
- OpenCV:02基础知识和绘制图形
文章目录 OpenCV的色彩空间 RGB和BGR `HSV`,`HSL`和`YUV` `HSV(HSB)` `HSL` `YUV` 颜色空间的转化 OpenCV的一种重要数据结构--Mat Mat介绍 ...
- 02- OpenCV绘制图形及图像算术变换 (OpenCV系列) (机器视觉)
知识重点 OpenCV用的最多的色彩空间是HSV. 方便OpenCV做图像处理 img2 = img.view() # 浅拷贝 img3 = img.copy() # 深拷贝 split ...
- 【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
说明 [跟月影学可视化]学习笔记. 图形系统是如何绘图的? 一个通用计算机图形系统主要包括 6 个部分,分别是: 输入设备 中央处理单元:首先,数据经过 CPU 处理,成为具有特定结构的几何信息. 图 ...
- tilemap 菱形_使用Cocos creator制作【治愈七夕】-音乐游戏图形api绘制跳舞的线
专栏概述及目录:笑苍天Smile:专栏概述及目录zhuanlan.zhihu.com 游戏截图: 游戏地址:微信扫一扫 游戏源码 游戏技术:前端引擎-Cocos creator,语言-Ts. 写作目 ...
- Canvas学习:封装Canvas绘制基本图形API
Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方法, ...
- arcgis api for js地图符号的使用(使用Draw绘制图形)
api里面用来在地图上绘制图形的工具位于 esri/toolbars/draw模块,同时还需要搭配esri/graphic模块以及点.线.面的样式相关的模块. draw 模块用来绘图,之所以还要用到g ...
- 29 WebGL绘制立方体并为立方体每个表面指定颜色
案例查看地址:点击这里 顶点着色器进行的是逐顶点的计算,接收的是逐顶点的信息.如果我们要指定表面的颜色,需要将颜色定义给顶点.比如,我们要定义一个三角形为一种颜色,必须三个顶点的颜色都为一种颜色. 但 ...
最新文章
- Careercup - Google面试题 - 4699414551592960
- tcpdump -i eth0 -n -vvv src or dst port 443
- 以SYSTEM用户运行CMD
- contains方法_【原创】Pandas数据处理系列(二):常用处理方法笔记
- python出现的意义_[转]Python中下划线以及命名空间的意义
- linux 测试本地端口是否打开,有效地测试Linux上的端口是否打开?
- 推荐系统学习(二)基于用户/物品的协同过滤算法(User-CF / Item-CF)
- WCF发布到IIS 7.0,并以https访问
- [笔记].痛哉!!!Error: Can't access JTAG chain, Error: Operation failed
- C++ 控制对象的创建方式和数量
- django的render的特殊用法
- 友情链接php源代码_2017最新ThinkPHP开发的友情链接交易系统平台源码
- 硬件-2-显示器Redmi27英寸显示器
- python如何与access配合使用_使用Python对Access读写操作方法详解
- DP83848 跑10M能行,跑100M不行 的原因
- 危夷晨:来自“AI黄埔军校”的计算机视觉创业者
- 微软azure DNS服务器,什么是 Azure 专用 DNS?
- Form通过js提交
- 如何设置电脑可以qq远程桌面连接到服务器,qq如何实现远程访问家里的电脑?
- 雷鸣的游戏人生(六) --- 如何开始学习编程?