一起学 WebGL:绘制三角形

这篇具有很好参考价值的文章主要介绍了一起学 WebGL:绘制三角形。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

大家好,我是前端西瓜哥。画了好几节课的点,这次我们来画三角形了。

三角形可太重要了,再复杂的三维模型都是由一个个小三角形组合而成,越多越精细越真实。

绘制三角形

这次绘制三角形,要绘制的点就有三个了,不再是一个。为此我们需要用到缓存区对象(buffer object)。

通过缓存区对象,我们可以一次性向顶点着色器传入多个顶点数据。

Float32Array

首先我们来用 Float32Array 数组保存需要用到的三个点的位置信息。

// 顶点数据
const vertices = new Float32Array([
  // 第一个点
  0, 0.5,
  // 第二个点
  -0.5, -0.5,
  // 第三个点
  0.5, -0.5
]);

为了更简单一些,这里先不考虑 z 维度,每个顶点只用了 x 和 y 分量。到时候传递到顶点着色器的 gl_Position 时,z 会自动填充默认的 0。

Float32Array 是一个比较特殊的 JavaScript 数组,最初也是为了和 WebGL 配合使用的,它可以创建一个 32 位浮点数的强类型数组。

普通的 JS 数组没有类型的概念,数组元素可能是数字、字符串、对象的混合体,传给 WebGL,要处理也麻烦,不太合适。

需要注意的是这种强类型数组的 API 和普通数组不一样,比如不能用 push 方法。

缓冲区对象的创建和数据写入

// 创建缓冲区对象
const vertexBuffer = gl.createBuffer();
// 绑定缓冲区对象到上下文
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 向缓冲区对象写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

首先是用 gl.createBuffer 方法创建一个缓冲区对象。

然后用 gl.bindBuffer(target, buffer) 将缓存区绑定到 gl 上下文指定目标(gl.ARRAY_BUFFER)中。target 参数还有另一个值是 gl.ELEMENT_ARRAY_BUFFER,这个我们后面章节讲如何绘制立方体的时候会用到哈。

buffer 参数就是刚刚创建的缓冲区对象。

最后往缓冲区对象写入我们刚刚的数组数据。最后一个参数 gl.STATIC_DRAW,表示数据写入后不会再被修改,去绘制 静态 场景。

绑定到顶点着色器上

接着就是让缓冲区对象对接上顶点着色器的变量。

// 获取 a_Position 变量地址
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
// 将缓冲区对象分配给 a_Position 变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 允许访问缓存区
gl.enableVertexAttribArray(a_Position);

首先通过 gl.getAttribLocation 拿到顶点着色器中声明的 a_Position 变量的地址。

然后是比较复杂的 gl.vertexAttribPointer 方法。参数说明:

  1. location,待分配的 attribute 变量地址;
  2. size,每个顶点分量分量个数,就是一次从中取几个作为一个顶点数据,不够的补缺省值;
  3. type,指定数据格式,gl.FLOAT 表示使用的是 Float32Array 的类型;
  4. normalize,是否将浮点数归一化到 [0, 1] 或 [-1, 1] ;
  5. stride,相邻两个顶点之间的字节数,以后用数组保存多种信息数据时会用到;
  6. offset,指定缓冲区对象中的偏移量。

目前我们只需要知道 location 和 size 就行了。最后两个参数会在绘制颜色渐变的三角形用到,这里不细说。

最后是用调用 gl.enableVertexAttribArray(a_Position),表示 a_Position 变量对应的缓冲区被开启了。开启后,我们就不能再用原来的 gl.vertexAttrib3f 来传递数据了,WebGL 会从缓存区一个个拿。如果你想关闭分配,可以调用

绘制

/*** 绘制 ***/
// 清空画布,并指定颜色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

最后是清空画布,然后绘制三角形。

这里 gl.drawArrays 方法的第一个 mode 参数换成了 gl.TRIANGLES(三角形图元),不再是原来的 gl.POINTS。

绘制效果:

一起学 WebGL:绘制三角形

如果用原来的 gl.POINTS,并设置好 gl_PointSize 指定点大小,则会绘制出下面的效果:

一起学 WebGL:绘制三角形

代码

下面是完整的代码实现。

/** @type {HTMLCanvasElement} */
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");

const vertexShaderSrc = `
attribute vec4 a_Position;
void main() {
 gl_Position = a_Position;
 gl_PointSize = 10.0;
}
`;

const fragmentShaderSrc = `
void main() {
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

/**** 渲染器生成处理 ****/
// 创建顶点渲染器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
// 创建片元渲染器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
// 程序对象
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.program = program;

// 顶点数据
const vertices = new Float32Array([
  // 第一个点
  0,
  0.5,
  // 第二个点
  -0.5,
  -0.5,
  // 第三个点
  0.5,
  -0.5
]);

// 创建缓存对象
const vertexBuffer = gl.createBuffer();
// 绑定缓存对象到上下文
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 向缓存区写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 获取 a_Position 变量地址
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
// 将缓冲区对象分配给 a_Position 变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

// 允许访问缓存区
gl.enableVertexAttribArray(a_Position);

/*** 绘制 ***/
// 清空画布,并指定颜色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

在线 demo:

https://codesandbox.io/s/gbh1xf?file=/index.js

结尾

我是前端西瓜哥,欢迎关注我,学习更多 WebGL 知识。

下一节,我们讲讲 WebGL 支持绘制的图元有哪些,可以通过怎么的模式绘制点、线、三角形。文章来源地址https://www.toymoban.com/news/detail-417680.html

到了这里,关于一起学 WebGL:绘制三角形的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java使用Maven工程操作OpenGL ES绘制三角形和圆形;绘制完成后操作键盘控制然图形移动

    PS:想快速看到效果的小伙伴,可以在引入依赖后,先跳到完整代码部分 第一步:依赖引入 第二步:创建类,引入需要的包,设置全局参数 1.创建类 2. 包引入 3. 全局参数 第三步:定义一个初始化方法 init() 1. GLFW 错误信息的回调函数 这样做,在发生 GLFW 错误时,错误信息将

    2024年02月08日
    浏览(44)
  • css实现圆角三角形,圆角三角形的实现

    今天给大家带来一个如何实现圆角三角形的方案,这个方案虽然可以实现,但是也是借助拼凑等方式来实现的,假如想一个div来实现圆角三角形,还是比较困难的。之前文章讲了如何实现对话框,里面介绍了三角形的实现方式。今天讲讲如何实现圆角三角形。 想要生成一个带

    2024年02月09日
    浏览(53)
  • 用python写九九乘法表(左上三角、左下三角、右上三角、右下三角、正三角形、倒三角形格式)

    1.左上三角格式:   2.左下三角格式:   3.右上三角格式:     4.右下角格式:     5.倒三角格式:      

    2024年02月11日
    浏览(60)
  • C语言程序设计:输入一个三角形的三条边长,求出三角形的面积。

    已知三角形的三边长a,b,c,则该三角形的面积公式为:           area=  其中s = (a+b+c)/2

    2024年02月06日
    浏览(61)
  • OpenCV项目开发实战-- 将一个三角形变形为另一个三角形 ( C++ / Python )代码实现

     文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:左图中蓝色三角形内的所有像素都已转换为右图中的蓝色三角形。 在本教程中,我们将看到如何将图像中的单个三角形变形为不同图像中的另一个三角形。 在计算机图形学中,人们一直在处理扭曲三角形,因为任

    2024年02月09日
    浏览(86)
  • 【数字三角形】

    题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走

    2024年02月05日
    浏览(55)
  • css实现三角形

       1. Border 2. transform 3.  :before 和 :after 伪元素 4. clip-path

    2024年02月09日
    浏览(45)
  • CSS 画三角形

    1、transform: rotate + overflow: hidden 就是利用BFC的特性,在封闭的盒子里面,以图形的左下角(left bottom)作为旋转中心,进行旋转,把超出部分隐藏、 2、clip-path 剪切 clip-path 可以将一个容器裁剪成任何我们想要的样子 3、border + transparent 设置一个宽高为0的盒子,用边框大小来控

    2024年01月25日
    浏览(50)
  • 【数字三角形】(C++版)

    题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走

    2024年02月16日
    浏览(66)
  • stl格式-3D三角形

    https://www.youtube.com/watch?v=u5-Df1YlxCI 注 : vtk9.1在github上有 首先说一下,这个stl不是cpp中的stl库. 指的是以.stl结尾的文件( S T ereo L ithography) STL(Standard Tessellation Language):STL是一种用于 表示三角网格的一种文件格式 ,它将模型表示为一系列连接的 三角形 。STL文件通常分为两种类

    2024年02月08日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包