欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《WebGL编程指南》---从示例代码中学习WebGL之初识【1】

程序员文章站 2022-05-23 14:09:47
...

写在前面

  笔者希望学习WebGL很久了,但是鉴于种种的事一直没有开展,恰好研究生复试过了,在这空档时间段内想学一门新技术,于是想到了WebGL,经前同事推荐,果断买了《WebGL编程指南》这本书,于是,我的学习之旅就开始了。对于编程人员来说,案例代码是最好的教科书了。即将与读者见面的这一系列短文章是我在学习过程中的一些记录和感想,这一系列的短文章,通过解读书中的示例代码来记录学习WebGL之旅。文章中用到的代码段绝大部分出自《WebGL编程指南》这本书,彩色的代码段表示下方会有相关的说明,在这期间会引用很多书中的话语,因为是引用,所以难免会有所简略,想知道更多知识细节的读者,建议找原书来通读,你们也可以上书本的帮助网站https://sites.google.com/site/webglbook/查看相关的例子。若有读者对此有疑问,希望你们多多与我交流和指正,我的邮箱:aaa@qq.com,谢谢大家。

简单认识WebGL

  WebGL可以理解为Web版的OpenGL,WebGL程序在屏幕上同时使用HTML和JavaScript来创建和显示三维图形,此外还会用到GLSL ES(着色器代码)。所以说要入门WebGL,读者最好是掌握一定的编程语言基础,不一定是HTML、JavaScript,很多直接从C++转过来的人也可以学得很好,此外,如果读者有一定的图形学基础,那学习起来会轻松很多。WebGL采用HTML5中新引入的<canvas>元素(标签),它定义了网页上的绘图区域。有了WebGL,JavaScript就能在canvas上面绘制三维图形了,否则就只能绘制二维图形。WebGL程序使用3种语言进行开发:HTML、JavaScript和GLSL ES,但是着色器代码GLSL ES是可以内嵌在JavaScript中的,所以WebGL网页的文件结构和传统网页一样,只用到HTML和JavaScript两种文件。接下来我们会通过代码示例,一步步走向WebGL的殿堂。

1.初识canvas

DrawRectangle.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Draw a blue retangle</title>
</head>
<body onload="main()">
<canvas id="example" width="400" height="400">
    Please use a browser that supports "canvas"
</canvas>
<script src="DrawRectangle.js">
</script>
</body>
</html>

<body onload="main()"></body>

在这行代码中,<body>标签指定onload属性,main()函数作为JavaScript程序的入口,然后让浏览器加载JavaScript文件,而main()函数在JavaScript文件中定义。使用如下语句来加载js文件:

<script src="DrawRetangle.js"></script>

HTML文件中引入了<canvas>标签,允许JavaScript动态地绘制图形。<canvas>元素提供一些简单的绘制函数,用来绘制点、线、矩形、圆等等。

<canvas id="example" width="400" height="400"></canvas>

在这行代码中,id属性为<canvas>指定了唯一的标识符,在对应的JavaScript文件中会用到这个id,width和height属性规定了它的区域,比如,上面表示400x400像素的区域。默认的<canvas>是透明的,如果不通过JavaScript代码画东西,<canvas>一般不可见。使用<canvas>要求浏览器支持<canvas>,但有些老的浏览器就不支持,此时会忽略此行代码。所以可以在标签中加入一行代码,用于提醒。如下所示:

<canvas id="example" width="400" height="400">

Please use a browser that supports "canvas"

</canvas>

DrawRectangle.js

function main() {
    var canvas=document.getElementById('example');
    if(!canvas){
        console.log('Failed to retrieve the <canvas> element');
        return;
    }

    var ctx=canvas.getContext('2d');
    if(!ctx){
        console.log('Failed to retrieve the <ctx> context');
        return;
    }
    ctx.fillStyle='rgba(0,0,255,1.0)';
    ctx.fillRect(120,10,150,150);
}

在上面的代码中,作为HTML文件中<body>元素中的onload属性值的main()函数,完成了在<canvas>上绘制蓝色矩阵的三步:

<1>获取<canvas>元素;

var canvas=document.getElementById('example');

if(!canvas){console.log('Failed to retrieve the <canvas> element');return;}

上述代码获取获取<canvas>元素并做错误判断,在项目中执行此步是一个很好的编程习惯,特别是写一些底层代码的时候,这一步很重要,对于排查程序错误点很有帮助。

<2>向该元素请求二维“图形的上下文”;

var ctx=canvas.getContext('2d');

if(!ctx){console.log('Failed to retrieve the <ctx> context');return;}

上述的代码向<canvas>元素请求二维“图形的上下文”,canvas.getContext()方法的参数指定上下文的类型(2d的还是3d的)。

注:若是三维图形,就要获取三维“图形的上下文”。

<3>在图形的上下文”上调用相应的绘图函数绘制图形

ctx.fillStyle='rgba(0,0,255,1.0)';

此行代码设置了填充颜色为蓝色,也可以根据自己的喜好修改rgba()的前3个参数来改变颜色,rbga()指定了r(红)、g(绿)、b(蓝)、a(alpha:透明度),前三者的范围是0-255,最后一个的范围是0.0-1.0,这种颜色格式为RGBA格式。

ctx.fillRect(120,10,150,150);

此行代码使用ctx.fillRect()函数来绘制矩形,它的参数决定了矩形在<canvas>中的位置和宽高,前两个参数指定矩形的左上顶点在<canvas>的坐标,后两个参数决定宽和高

注:<canvas>的坐标系统原点在屏幕左上方,以横轴为x轴(正方向朝右),纵轴为y轴(正方向朝下),均以像素为单位。

运行HTML文件,我们在网页上得到如下的显示:

《WebGL编程指南》---从示例代码中学习WebGL之初识【1】


2.最简单的WebGL程序

这个程序的功能就是用背景色清空(填充)了<canvas>标签的绘图区。在写这个程序之前,读者可以到网上先下载好相关的WebGL通用函数库。

HelloCanvas.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Clear canvas</title>
</head>
<body onload="main()">
<canvas id="webgl" width="400" height="400">
    Please use a browser that supports "canvas"
</canvas>
<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>
<script src="lib/cuon-utils.js"></script>
<script src="HelloCanvas.js"></script>
</body>
</html>

<canvas id="webgl" width="400" height="400">

Please use a browser that supports "canvas"

</canvas>

在上面的代码中,<canvas>标签的id设为了webgl,在对应的JavaScript文件中可以通过id来获取到<canvas>。

<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>

<script src="lib/cuon-utils.js"></script>

上面的代码引入一些专门为WebGL准备的、事先定义好的函数库。在示例项目中,将函数库的文件夹放在了与HTML和JavaScript文件的同一目录下src路径是相对路径

HelloCanvas.js

function main() {
    var canvas=document.getElementById('webgl');
    if(!canvas){
        console.log('Failed to retrieve the <canvas> element');
        return;
    }

    var gl=getWebGLContext(canvas);
    if(!gl){
        console.log('Failed to get the rendering context for WebGL');
        return;
    }
    gl.clearColor(0.0,0.0,0.0,1.0);

    gl.clear(gl.COLOR_BUFFER_BIT);
}

在这个文件中,开始真正使用WebGL来绘制三维图形。它依然遵循着上面示例代码的三个步骤:

<1>获取<canvas>元素;

与HTML 文件对应,document.getElementById()函数的参数变为了webgl字符串。

<2>获取绘图上下文;

var gl=getWebGLContext(canvas);
    if(!gl){
        console.log('Failed to get the rendering context for WebGL');
        return;

    }

在上面的代码中,一般来说,要用canvas.getContext()函数来获取绘图上下文,但是在获取WebGL的绘图上下文的时候,canvas.getContext()函数接收的参数在不同的浏览器中会有所不同,所以书本的作者写了一个函数getWebGLContext()来隐藏不同浏览器之间的差异,传入的参数是<canvas>元素。它被定义在cuon-utils.js文件中,可以通过该js文件查看该函数的规范原型。此时,三维的绘图上下文就储存在了gl这个变量中。

<3>进行绘图,包括设置背景色和清空<canvas>;

gl.clearColor(0.0,0.0,0.0,1.0);gl.clear(gl.COLOR_BUFFER_BIT);

学过OpenGL的读者可能会对这两行代码感到熟悉,没错,它们对应的就是OpenGL或者OpenGL ES 2.0的glClearColor()和glClear()函数。gl.clearColor()负责清空背景色,以RGBA格式来设置背景色,一旦指定背景色后,在下一次调用gl.clearColor()方法前背景色都不会改变;gl.clear()负责用之前指定的背景色清空<canvas>,gl.clear()的参数是缓冲区,缓冲区有深度缓冲区DEPTH_BUFFER_BIT(对应gl.clearDepth(),参数默认值为1.0)、颜色缓冲区COLOR_BUFFER_BIT(对应gl.clearColor(),参数默认值为(0.0,0.0,0.0,0.0))和模板缓冲区STENCIL_BUFFER_BIT(对应gl.clearStencil(),参数默认值为0)。在本示例代码中是清空背景色,我们可以随意更改gl.clearColor()的参数来变换<canvas>背景色。

示例代码效果如图所示:

《WebGL编程指南》---从示例代码中学习WebGL之初识【1】


好了,这一节就只有这么多。Have a good day!


相关标签: WebGL Shader