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(indexsizetypenormalizedstrideoffset);

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

方法。

我不到怎么添加代码只好先放一个结果啦:


结果代码
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容