当前位置: 首页 > article >正文

WebGL系列教程三(使用缓冲区绘制三角形)

目录

  • 1 前言
  • 2 缓冲区介绍
  • 3 声明顶点的位置和颜色
  • 4 回忆Shader的初始化
  • 5 开始缓冲区的逻辑
    • 5.1 声明顶点坐标
    • 5.2 创建并绑定缓冲区
    • 5.3 获取顶点着色器中的变量
    • 5.4 使变量从缓冲区取值
    • 5.5 绘制
    • 5.6 完整代码
  • 7 总结

1 前言

  上一篇中我们介绍了WebGL的环境搭建及Shader的初始化,并绘制了一个点,这一篇我们来绘制一个三角形,并介绍缓冲区的使用方法。

2 缓冲区介绍

  缓冲区就是一块存储数据的区域,为了方便我们一次性把所需的数据都传给WebGL,而不是每次都去传。这次我们的流程和上一篇的操作流程基本是一致的,唯一不同的在于绘制时使用缓冲区的数据绘制三角形,我们还是将整个流程梳理一下:

  1. 创建着色器对象
  2. 获取着色器对象的源代码
  3. 绑定着色器的源
  4. 编译着色器
  5. 创建并关联项目
  6. 创建并绑定缓冲区
  7. 读取缓冲区数据并绘制三角形

  最后就我们要的三角形是这样的,颜色是红色:
在这里插入图片描述

3 声明顶点的位置和颜色

  这一块的代码并没有什么特别之处,只是去掉了声明点的那一句代码gl_PointSize = 10.0;,因为这次我们不再需要绘制点了,其他的保持原样。

 <script id="vertex-shader" type="x-shader/x-vertex">
     //声明一个点,vec2表示2维向量
     attribute vec2 aPos;
     void main(){
     	 //点的位置,将vec2补齐为vec4
         gl_Position = vec4(aPos,0.0,1.0);
     }
 </script>
 <script id="fragment-shader" type="x-shader/x-fragment">
     precision highp float;
     void main(){
         //点的颜色,rgba形式,红色
         gl_FragColor = vec4(1.0,0.0,0.0,1.0);
     }
 </script>

4 回忆Shader的初始化

  这一块的代码我们在上一篇已经介绍过了,这里不再细说,全部一次性给出,由于我们之后的每一篇博文都有这个操作,因此,这块的代码可以封装为一个函数重复调用,之后的博文也将不再列出。

 const canvas = document.getElementById("canvas");
 const gl = canvas.getContext("webgl");
 //创建着色器对象
 let vertexShader = gl.createShader(gl.VERTEX_SHADER);
 let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
 //获取着色器对象的源
 let vertexSource = document.getElementById("vertex-shader").innerText;
 let fragmentSource = document.getElementById("fragment-shader").innerText;
 //绑定着色器的源
 gl.shaderSource(vertexShader,vertexSource);
 gl.shaderSource(fragmentShader,fragmentSource);
 //编译着色器
 gl.compileShader(vertexShader);
 gl.compileShader(fragmentShader);
 console.log(gl.getShaderInfoLog(vertexShader));
 //创建并关联项目
 let program = gl.createProgram();
 gl.attachShader(program,vertexShader);
 gl.attachShader(program,fragmentShader);
 gl.linkProgram(program);
 gl.useProgram(program);

5 开始缓冲区的逻辑

5.1 声明顶点坐标

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

5.2 创建并绑定缓冲区

gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);

5.3 获取顶点着色器中的变量

let aPos = gl.getAttribLocation(program,"aPos");

5.4 使变量从缓冲区取值

//指定aPos如何读取缓冲区  两个值表示一个坐标,float类型,不使用归一化,2个值所占的字节长度,从偏移0倍字节开始读取
gl.vertexAttribPointer(aPos,2,gl.FLOAT,false,2*Float32Array.BYTES_PER_ELEMENT,0);
//允许aPos变量从缓冲区取值
gl.enableVertexAttribArray(aPos);

什么是归一化?
  举个例子,假设我们的数据范围是从0-10,变为0-1的过程,就叫归一化。那怎么变为0-1呢?很简单,将每个值都除以10就可以了。这里我们不使用归一化,意味着不允许WebGL修改我们的数据。

5.5 绘制

//绘制三角形,从零好索引开始,绘制三个点
gl.drawArrays(gl.TRIANGLES,0,3);

大功告成,看一下效果:
在这里插入图片描述

5.6 完整代码

//声明顶点坐标
const vertices = new Float32Array([
    -0.5,0.0,
    0.0,1.0,
    0.5,0.0,
]);
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
let aPos = gl.getAttribLocation(program,"aPos");
//绑定坐标
//指定aPos如何读取缓冲区  两个值表示一个坐标,float类型,不使用归一化,2个值所占的字节长度,从偏移0倍字节开始读取
gl.vertexAttribPointer(aPos,2,gl.FLOAT,false,2*Float32Array.BYTES_PER_ELEMENT,0);
gl.enableVertexAttribArray(aPos);
//绘制三角形,从零开始,绘制三个点
gl.drawArrays(gl.TRIANGLES,0,3);

7 总结

  本篇中,我们首先回忆了Shader的初始化过程,然后介绍了如何使用缓冲区进行三角形的绘制,并详细介绍了如何从缓冲区进行取值,及各个参数的含义,下一篇我们讲如何将三角形变为彩色的,回见~


http://www.kler.cn/a/296854.html

相关文章:

  • 【网络原理】❤️Tcp 连接管理机制❤️ “三次握手” “四次挥手”的深度理解, 面试最热门的话题,没有之一, 保姆式教学 !!!
  • 如何使用命令行快速下载Google Drive/OneDrive大文件
  • 数据治理策略:确保数据资产的安全与高效利用
  • ubuntu任何版本 卡死 解决办法
  • 【性能测试】一篇文章告诉你什么是 Kafka 和 MQ!
  • 【自考zt】【软件工程】【21.10】
  • 系统架构设计师:软件工程
  • Keil导入包出错
  • 使用ChatGPT生成爆款小红书文案,有手就行!
  • 数据结构:树与二叉树
  • 【MATLAB源码-第262期】基于simulink的OFDM+QPSK多径信道下图片传输系统仿真,多径数目为5,子载波64,对比前后的图片
  • 你可能不知道的Activity启动的诡异现象探索
  • 记一次公有云遇到的bug(随手记)
  • python binning data openAI gym
  • 如何使用Docker快速启动Nginx服务器
  • Docker端口映射
  • 测试即服务(TaaS):概念、优势及应用场景!
  • 易灵思FPGA开发(一)——软件安装
  • 软考学习 数据结构 排序
  • 【机器学习-神经网络】循环神经网络