WebGL学习之路:2. WebGL的第一个程序——画一个点

前言

上篇介绍了WebGL的基本概念和基础知识,本文记录一下怎么实现WebGL的第一个程序,通过绘制图元来继续介绍WebGL的api使用。

绘图

初始化

初始化其实就是把上文的代码再写一遍,然后开始绘制图形:

  • 创建画布
html 复制代码
<canvas id="canvas" width="500" height="500"></canvas>
  • 编写着色器代码
html 复制代码
<!-- 顶点着色器 -->
  <script id="vertex-shader" type="x-shader/x-vertex">
    void main() {
     gl_PointSize = 10.0;
     gl_Position = vec4(0.0, 0.0, 1.0, 1.0);
    }
  </script>

  <!-- 片段着色器 -->
  <script id="fragment-shader" type="x-shader/x-fragment">
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  </script>
  • 创建着色器程序
js 复制代码
    // 1. 获取canvas元素和webgl上下文
    const canvas = document.getElementById("canvas")
    const gl = canvas.getContext("webgl")
    // 2. 创建着色器对象
    const vertexShader = gl.createShader(gl.VERTEX_SHADER)
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
    // 3. 获取着色器源码
    const vertexSource = document.getElementById('vertex-shader').innerText
    const fragmentSource = document.getElementById('fragment-shader').innerText
    // 4. 绑定着色器源码然后编译
    // 绑定
    gl.shaderSource(vertexShader, vertexSource)
    gl.shaderSource(fragmentShader,fragmentSource)
    // 编译
    gl.compileShader(vertexShader)
    gl.compileShader(fragmentShader)
    // 5. 创建程序对象
    const program = gl.createProgram()
    gl.attachShader(program, vertexShader)
    gl.attachShader(program, fragmentShader)
    gl.linkProgram(program)
    gl.useProgram(program)
  • 绘制

然后就到了本文的重点内容,绘制图形------画一个点,画图之前,先看一下WebGL是怎样绘制图元的:

WebGL只能绘制绘制三种形状:点、线、三角形。其他形状必须通过这三种基本形状在3D空间的组合来绘制,WebGL绘图要使用gl.drawArrays()gl.drawElements()方法,前者使用缓冲数组,后者使用操作元素数组缓冲区。(所有提到的gl都代表WebGL的上下文,重要的是后边的方法),缓冲区会在下文介绍。

gl.drawArrays()gl.drawElements()方法的第一个参数都代表要绘制的形状的常量,参数如下:

  • gl.POINTS:将每个顶点当成一个点来绘制
  • gl.LINES:将数组作为一系列顶点,在这些顶点间绘制直线,每个顶点既是起点也是终点,所以数组中的顶点必须是偶数才能开始绘制。
  • gl.LINE_LOOP:将数组作为一系列顶点,在这些顶点间绘制直线,从第一个顶点到第二个顶点绘制一条直线,再从第二个顶点到第三个顶点绘制一条直线,以此类推,到最后一个顶点,再从最后一个顶点到第一个顶点绘制一条直线。
  • gl.LINE_STRIP:和gl.LINE_LOOP的区别就是不会从最后一个顶点到第一个顶点再绘制一条直线
  • gl.TRIANGLES:将数组作为一系列顶点,在这些顶点间绘制三角形,如果不特殊指定,每个三角形都分开绘制,不共享顶点
  • gl.TRIANGLES_STRIP:和gl.TRIANGLES的区别是,在前3个顶点之后的顶点会作为第三个顶点与其前面的两个顶点构成三角形。例如,数组中的顶点是A、B、C、D,那么第一个三角形使用ABC,第二个三角形使用BCD。
  • gl.TRIANGLES_FAN:和gl.TRIANGLES的区别是,在前3个顶点之后的顶点会作为第三个顶点与其前面的顶点第一个顶点构成三角形。例如,数组中的顶点是A、B、C、D,那么第一个三角形使用ABC,第二个三角形使用BCD。

这些参数就是gl.drawArrays()gl.drawElements()方法可以接受的参数,那么现在传入gl.POINTS参数来绘制点:

js 复制代码
gl.drawArrays(gl.POINTS, 0, 1)

第二个参数代表数组缓冲区的起点索引,第三个参数代表数组缓冲区包含的顶点集合的数量,因为只画一个点,所以相当于没有用到数组缓冲区,所以缓冲区这里先不介绍,下文将介绍缓冲区。画图如下:

图中边框就是canvas的区域,片段着色器代码中设置了颜色为(1.0, 0.0, 0.0, 1.0),对应rgba也就是红色,所以这里绘制出了一个红色的点。

总结

本文通过绘制一个红色点的实践,串联了 WebGL 的核心渲染流程,如下图: 并介绍了WebGL可以绘制的图形,即点、线、三角形。下文将介绍线的绘制,并且讲述缓冲区等概念。

相关推荐
JELEE.31 分钟前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫4 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友4 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理6 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻6 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front7 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰7 小时前
纯flex布局来写瀑布流
前端·javascript·css
一袋米扛几楼988 小时前
【软件安全】什么是XSS(Cross-Site Scripting,跨站脚本)?
前端·安全·xss
向上的车轮8 小时前
Actix Web适合什么类型的Web应用?可以部署 Java 或 .NET 的应用程序?
java·前端·rust·.net