它是一种存储限定符,表示定义一个attribute的全局变量,这种变量的数据将由外部向顶点着色器内传输,并保存顶点相关的数据,只有顶点着色器才能使用它
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="webgl" width="200" height="200"></canvas>
<script>
const webgl = document.getElementById('webgl')
const gl = webgl.getContext('webgl')
// 创建着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER)
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
// 绑定数据源
// 声明顶点着色器 attribute 变量
gl.shaderSource(vertexShader, `
attribute vec4 a_Position;
void main(){
gl_Position = a_Position;
gl_PointSize = 20.0;
}
`)
gl.shaderSource(fragmentShader, `
void main(){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`)
// 编译着色器
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)
// 创建着色器程序
const program = gl.createProgram()
// 绑定着色器
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
// 连接着色器
gl.linkProgram(program)
// 使用着色器
gl.useProgram(program)
// 定义一个类型数组保存顶点坐标值
const vertices = new Float32Array([
//x, y
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
])
// 创建缓冲区
const vertexBuffer = gl.createBuffer()
// 绑定缓冲区
// target 要把缓冲区放在webgl系统中的什么位置, buffer 缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
// 写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
// 获取到顶点着色器中变量
const a_Position = gl.getAttribLocation(program, 'a_Position')
// 从当前绑定的缓冲区中读取顶点数据(index, size, type, normalized是否顶点数据归一, stride相邻两个顶点间的字节数, offset从缓冲区的什么位置开始存储变量)
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0)
// 开启顶点数据的批处理功能
gl.enableVertexAttribArray(a_Position)
// 绘制指定位置的三角
// 点
// gl.drawArrays(gl.POINTS, 0, 3)
// 闭合线条
// gl.drawArrays(gl.LINE_LOOP, 0, 3)
// 单独三角形 (如果是正面,逆时针绘制, 实际引擎开发中用的最多,就是比较费点)
gl.drawArrays(gl.TRIANGLES, 0, 3)
// LINES 单独线段(每2组一条线)
// LINE_STRIP 线条 (线条相连,但首尾不相连)
</script>
</body>
</html>
以上四个面得绘制顺序是:
v0>v1>v2
以上一个三角形的第三条边+下一个点为基础,按照和第三条边相反的顺序,绘制三角形
v0>v2>v3
同上
v0>v3>v4
同上
v0>v4>v5
同上
webgl可绘制的面只有三角面,要绘制矩形的话,只能用两个三角形去拼
文章浏览阅读3.6k次。2020/03/27 21:00:39 CLSRSC-184: Configuration of ASM failed2020/03/27 21:00:40 CLSRSC-258: Failed to configure and start ASMDied at /u01/app/19.0.0/grid/crs/install/crsinstall.pm line 2482.ORA-..._ora-39511: start of crs resource for instance '215' failed with error:[crs-2
文章浏览阅读3.4k次,点赞45次,收藏55次。对 W25Q64 的使用可以总结如下:初始化:在开始使用 W25Q64 之前,需要通过 SPI 总线初始化芯片,并确保硬件连接正确。读操作:可以使用读取数据函数从指定地址读取数据,并将数据存储到指定的缓冲区中。写操作:可以使用页写函数向指定地址写入数据。需要考虑到写入字节数大于 256 字节和不大于 256 字节的两种情况,以及在写入数据之前需要先执行写使能操作,并在写操作完成后等待芯片忙碌状态结束。其他操作:除了读写操作外,W25Q64 还支持擦除、写使能、禁止写等其他操作,根据具体需求进_w25q64
文章浏览阅读2.8w次,点赞16次,收藏61次。2015年11月23日,鄙人在csdn发表了第一篇技术文章,掐指一算距今已有三年。遥想当年开写博客,只是为了总结经验同时分享出来,后来机缘巧合受到出版社编辑邀请并出了书,完全是无心插柳的结果。当初写作《Android Studio开发实战:从零基础到App上线》第一版前后花了一年多的时间,经过三审三校于2017年6月正式上市,其实这本书出来之时没能赶上好时候,从2017年开始App学习热潮被人工智..._android studio开发实战:从零基础到app上线 第二版 pdf
文章浏览阅读2.8k次。习惯了使用notepad++,就知道它的好,尤其是当前文件过滤搜索,下文记录下ubuntu安装的心得。_ubuntu安装notepad
文章浏览阅读6.9k次,点赞44次,收藏326次。本篇博客包含ACM,NOIP所涉及的基础算法,涵盖七个模块:基础算法,数据结构,搜索与图论,STL,数学知识(数论),动态规划,贪心。涵盖内容范围较为全面,是面向初学者的算法汇总,第八个章节是所涉及的算法板子,可以直接使用。因为是面向算法竞赛,本文的所有设计算法都是用C++进行实现的,不提供其他语言的代码,共涉及106道算法题目,以题代讲,在题目中理解算法的内涵。_acm-icpc基本算法pdf
文章浏览阅读1.6k次。通信系统中ZF(Zero Forcing,零迫)、ML(Maximum Likelihood,最大似然)、MRC(Maximum Ratio Combining,最大比合并)和MMSE(Minimum Mean Square Error,最小均方误差)是四种常见的信号检测算法。这些算法在通信系统中用于从接收信号中恢复出原始发送信号。_mrc信号检测的缺点
文章浏览阅读201次。1qt5安装软件中心中安装 qt creater,此时Qt无法显示中文 且无法输入中文如果要设置中文等语言,还要下载一些语言文件。可以到http://qt-project.org上下载一个包,安装后把语言文件都复制到/usr/share/qtcreator/translations。2中文输入首先语言包要安装完整 系统设置 》语言设置中可以安装中文语言包下澡并安装 搜狗拼音输入法 for linu..._fcitx-frontend-qt5_1.0.5-1_amd64.deb
文章浏览阅读2.4k次。在sciter中,要给窗口弄个阴影是非常容易的事情 <html window-frame="solid-with-shadow">效果图 但是,在Windows 7下出问题了,变成这样了经过分析,发现是Windows 7主题引起的问题只有在使用了Aero主题的情况下,窗口才会出现阴影,否则就没有。最终,我还是放弃了这个方案,使用贴阴影图片..._rust窗口阴影
文章浏览阅读501次。随机相关内容 C#实现 Unity直接可用洗牌代码//Fisher-Yates shufflestatic void Shuffle(T[] array){int n = array.Length;for (int i = 0; i < n; i++){int r = i + Random.Range(0, n - i);T t = array[r];array[r] = array[i];..._随机方向代码
文章浏览阅读1.3k次。使用Django项目开发项目中,协同开发的童鞋经常会遇到“django.db.utils.InternalError : (1050 Table ‘xxx’ already exists)”这种报错;Django再进行数据迁移过程中若表中已存在此表或者某个字段,跟当前开发环境中的迁移记录不匹配情况才会发生这种报错,解决办法:1、删除当前的迁移记录文件2、删除之前创建的报错表、数据字段3、删除django_migrations当前操作的记录,重新迁移OK..._django.db.utils.internalerror: (1050, "table 'auth_sms_record' already exist
文章浏览阅读8.5k次,点赞5次,收藏64次。空间坐标系以及空间两三维坐标系转换矩阵解释因为工作的原因,需要进行不同坐标系的一个转换,在查阅了众多的网页之后,发现有用的没几个,而且众多都是抄的同一篇文章,而且都是罗列以下旋转的方式,几乎没有解释旋转角的物理意义,也不说这个旋转角怎么得到的。在折腾了一天之后,终于弄清楚了,特意写下来,既能有助于记忆,又能装b,很好很强大。基础背景空间三维坐标系转换,大多出现在像我似的搞地图的这群B人里,当然还有搞游戏的大佬们。所以需要对空间三维坐标系做一个小的总结,来防止忘记或者混乱。具体图形可百度,赖的放图_三维空间坐标系
文章浏览阅读1.5w次,点赞11次,收藏31次。Vue-router是伴随着Vue框架出现的路由系统,它也是公认的一种优秀的路由解决方案。在使用Vue-router时候,我们常常会使用其自带的路径跳转组件Link,通过实现跳转,这和传统的何其相似!但它们到底有什么具体的区别呢?官方中给出的解释是这样的:<router-link> 比起写死的 <a href="..."> 会好一些,理由如下:无论是 HTML5..._a标签和router-link的区别