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

快速导航(持续更新中)

WebGL系列教程一(开篇)
WebGL系列教程二(环境搭建及着色器初始化)
WebGL系列教程三(使用缓冲区绘制三角形)
WebGL系列教程四(绘制彩色三角形)
WebGL系列教程五(使用索引绘制彩色立方体)
WebGL系列教程六(纹理映射与立方体贴图)
WebGL系列教程七(二维及三维旋转、平移、缩放)
WebGL系列教程八(GLSL着色器基础语法)
WebGL系列教程九(动画)
WebGL系列教程十(模型Model、视图View、投影Projection变换)
WebGL系列教程十一(光照原理及Blinn Phong着色模型)

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");

let length = Float32Array.BYTES_PER_ELEMENT;//数组中单个元素的字节长度
//指定aPos如何读取缓冲区  两个值表示一个坐标,float类型,不使用归一化,2个值所占的字节长度,从偏移0倍字节开始读取
gl.vertexAttribPointer(aPos,2,gl.FLOAT,false,2*length,0);
gl.enableVertexAttribArray(aPos);
//绘制三角形,从零号索引开始,绘制三个点
gl.drawArrays(gl.TRIANGLES,0,3);

6 总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIGIS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值