WebGL初探
webgl渲染的一般步骤:
1、准备画布,并得到WebGL的渲染上下文
1.1在html上创建Canvas画布。
创建html的canvas标签
Canvas好比是一个画布。但同时需要在webgl上获取这块画布。
获取画布
1.2获取webgl渲染上下文
canvas.getContext(contextType, contextAttributes);
通过 WebGL字符串或experimental-webgl 作为 contentType。
contextAttributes参数是可选的。
contextAttributes对象这好比就是画笔,光有纸是不够的还要有可以绘制的画笔。
2、定义几何并将其存储在缓冲区的对象上
2.1 定义几何体
定点几何体对象
定义几何体对象 定义颜色对象
创建索引
创建索引这下看不懂没关系这些数据都要放到着色器中处理,大致知道有24个顶点就可以了。索引号为0-24。
2.2 缓冲区对象
说得通俗一点缓冲区对象就是负责把数据传入gpu的手段。那么我们如何使用缓冲区对象达到与gpu沟通呢?
A.创建缓冲区。最先肯定就是创建我们的缓冲区对象了。通过canvas.createBuffer();方法来实现,而canvas是我们的画笔,也就是我们之前的webgl上下文。
B.绑定缓冲区。创建好缓冲区后需要绑定这个缓冲区,同时也给他定义是什么类型的缓冲区。通过canvas.bindBuffer(enum target, Object buffer);target总共有两种缓冲数据类型为:
顶点缓冲区对象 (VBO) − 它保持所述图形模型,要被渲染的每个顶点的数据。我们使用顶点缓冲对象中的WebGL存储和处理关于顶点诸如顶点坐标,法线,色彩,纹理坐标数据。
索引缓冲区对象(IBO) − 它保持所述图形模型的索引(索引数据),这是要被渲染的。分别对应下列的表达。
ARRAY_BUFFER 表示顶点的数据。
ELEMENT_ARRAY_BUFFER 表示索引数据
buffer为用户创建的缓冲区对象。
C.把数据传递到缓冲区,设置好缓冲数据类型后,我们把之前的数据传入到缓冲区中。通过canvas.bufferData(enum target, Object data, enum usage);方法传入。前一个参数遇上一个方法一样表示缓冲数据的类型。第二个data为之前的数据,通过传递数组来达到效果。
注意WebGL提供了一种特殊类型数组称为类型数组来传输数据元素,如索引顶点和纹理。这些类型的数组存储大量数据并处理它们在本地二进制格式,这将产生更好的性能。使用WebGL类型数组是Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,UInt32Array,Float32Array和Float64Array。
通常,用于存储顶点数据,我们用Float32Array; 要存储索引数据,我们使用Uint16Array。可以创建类型数组就像使用new关键字JavaScript数组。
最后一个参数为指定如何来使用缓冲区对象数据来绘制形状。类型有:
gl.STATIC_DRAW − 数据将指定一次,多次使用。
gl.STREAM_DRAW − 数据将指定一次,使用几次。
gl.DYNAMIC_DRAW − 数据将被重复指定和多次使用。
D.最后为取消缓冲区绑定,绘制完后建议解除绑定,使得代码更加规范,通过绑定null来解除。
示例代码:
缓冲区对象
3、创建和编译着色器程序
由于在着色器里面用的语言是ES SL,所以这里只是随便提一下,具体的之后会写另外的文章去写与OpenGL有关系。
3.1顶点着色器代码
3.2片段着色器代码
3.3编译着色器
A.创建着色器
创建一个空的着色器并附上着色器的类型,通过createShader(enum type);type类型如下
canvas.VERTEX_SHADER创建顶点着色器
canvas.FRAGMENT_SHADER 创建片段着色器。
B.附加源到shader
主要通过shaderSource(Object shader, string source);方法,两个参数分别为:
shader − 着色器对象。
Source − 必须以字符串格式传入着色器程序代码。
C.编译程序
通过canvas.compileShader(Object shader);方法来进行编译。
示例代码:
编译着色器3.4合并程序
上述只是创建了着色器,如果要使用还必须将程序合并,需要如下操作。
A.创建程序对象
通过canvas.createProgram();方法,返回空的程序对象。
B.附加着色器
通过canvas.attachShader(Object program, Object shader);
Program − 通过创建的程序对象作为参数
Shader − 传递的着色器编译程序中的一个(顶点着色器,片段着色器)
C.链接着色器
通过canvas.linkProgram(shaderProgram);方法。
D.使用程序
通过canvas.useProgram(shaderProgram);方法。此方法放在属性等赋值之后。
4、关联缓冲区对象和着色器程序
这一部分需要关联属性和缓冲区对象。如果要把顶点缓冲对象的顶点着色器程序的属性联系起来,必须按照下面的步骤。
4.1 获取属性的位置
通过canvas.getAttribLocation(Object program, string name);
program为程序对象,name为着色器中的变量。
4.2 点属性顶点缓冲区对象
分配属性,分配属性的方有很多,这里就举例vertexAttribPointer方法,这里附上api文档WebGLRenderingContext - Web APIs | MDN
void gl .vertexAttribPointer(index,size,type,normalized,stride,offset);
index:指定需要修改的顶点属性的索引。
size:指定每个顶点的属性的组件数,必须是1,2,3或4。
type:指定数据中每个组件的数据类型。
normalized:指定整数数据值是与否归一化。
stride:指定连续顶点属性开头之间的偏移量。
offset:指定顶点属性数组中第一个组件的偏移量。
4.3 启用属性
通过void gl .enableVertexAttribArray(index);方法启用。
index为定唯一标识要启用的顶点属性的索引号,就是通过getAttribLocation获取的。
5、绘制所需的对象
把各种条件设定好后,执行绘制图像的步骤,有两种方法绘制图像。
void drawArrays(enum mode, int first, long count);这种用于使用顶点来绘制模型方法。
void drawElements(enum mode, long count, enum type, long offset);是用于绘制用顶点和索引模型方法。
mode为绘制类型
first为绘制起点
count为绘制长度
type此选项指定必须是UNSIGNED_BYTE或UNSIGNED_SHORT索引的数据类型。
offset此选项指定渲染起点。它通常是第一个元素(0)。
但在这之前还需要一些操作:
A.清除canvas,clearColor();通过此方法可以设置背景颜色。
B.启用深度测试,gl.enable(gl.DEPTH_TEST); 通过此方法可以开启深度测试。
C.清除颜色缓冲区位。通过clear()方法,如下:gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
D.设置浏览窗口,通过gl.viewport(0,0,canvas.width,canvas.height);
方法。
我不到怎么添加代码只好先放一个结果啦:
结果代码