WebGL 和 OpenGL ES 有什么区别

JavaScript和OpenGL结合创造的惊人的WebGL效果
简介:WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,为HTML5 Canvas提供硬件3D加速渲染。WebGL技术标准免去了网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等。
WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,为HTML5 Canvas提供硬件3D加速渲染。WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等。
本文将为你带来8个效果惊人的WebGL效果,你可以在最新的Chrome浏览器中查看。 1. Supershape.js
supershape.js让你可以在浏览器中试验3D superformula。Superformula是一个通用的几何变形公式,涵盖了大量在自然界中发现的几何形状。在supershape.js中,除了公式参数外,你还可以选择不同的材料,并设置灯光。 2. HolyMania
在一个扭曲的隧道中,你需要控制一个球,且不能碰到隧道的边缘。看看你的最好成绩是多少。 3. Cube
基于WebGL构建,你可以在一个立方体的纽约、东京和其他城市地图上旅游。 4. Cloth Simulation
基于WebGL、GPU加速的布料模拟程序。 5. Reactive Ball
一个具有金属质感的球。这是关于光线、液态、环境地图的试验。 6. Lorenz Attractor
这不仅是堆积随机点,而是呈现出洛伦茨吸引子(洛伦茨振子的长期行为对应的分形结构)。 7. Swiss Addresses in 3D
使用WebGL,以3D形式呈现出370万瑞士人口的分布图。 8. Cell Cycle
Cell Cycle是一个用来进行webGL设计的应用,用于创建可3D打印的细胞模型。  本系列是本人阅读、学习《WebGL编程指南》的读书笔记,主要目的是摘录、总结,以便对所学进行巩固。
  WebGL,是一项用来在网页上绘制和渲染复杂三维图形(3D图形),并允许用户与之交互的技术。随着个人计算机和浏览器的性能越来越强,我们能够在Web上创建越来越精美、越来越复杂的3D图形。 &这个网址展示了Google发布的一些示例WebGL程序,在惊叹美轮美奂的效果的同时,我们发现发布和运行也变得非常简单。(就像使用普通的网页一样)
  WebGL是一种免费的、开放的、跨平台的技术;WebGL派生于OpenGL ES,后者是专用于嵌入式计算机、智能手机、家用游戏机等设备;WebGL基于OpenGL ES 2.0。下图显示了OpenGL、OpenGL ES 和 WebGL的关系:
  从2.0版本开始,OpenGL支持了一项非常重要的特性,即可编程着色器方法。该特性被OpenGL ES 2.0继承,并成为了WebGL 1.0标准的核心部分。
  着色器,使用一种类似于C的编程语言实现了精美的视觉效果。编写着色器的语言又称为着色器语言。WebGL基于OpenGL ES 2.0,使用GLSL ES语言编写着色器。
  虽然WebGL强大到令人惊叹,但使用这项技术进行开发却异常简单:只需要一个文本编辑器(Notepad或TextEdit)和一个浏览器(Chrome)即可;并且不需要去搭建开发环境,因为WebGL是内嵌在浏览器中的。
  下图显示了WebGL程序的结构:
  由于GLSL ES通常是以字符串的形式在JavaScript中编写的,所以虽然WebGL网页更加复杂,但它仍然保持着与传统的动态网页相同的结构:只用到HTML文件和JavaScript文件。
阅读(...) 评论()《WebGL 编程指南》笔记 —— 第六章 OpenGL ES着色器语言 - 简书
《WebGL 编程指南》笔记 —— 第六章 OpenGL ES着色器语言
本章主要内容:
(1)数据、变量和变量类型。
(2)矢量、矩阵、结构体、数组、采样器(纹理)
(3)运算、程序流、函数
(4)attribute、uniform和varying变量
(5)精度限定词
(6)预处理和指令
WebGL并不支持GLSL ES 1.00的所有特性。实际上,它支持的是1.00版本的一个子集,其中只包括WebGL需要的那些核心特性。
GLEL ES编程语言是在OpenGL着色器语言(GLSL)的基础上,删除和简化一部分后形成的,降低了硬件消耗,减少了性能开销。
(1)程序式大小写敏感的
(2)每一个语句都应该以一个英文分号结束
从main函数开始执行。
着色器程序有且仅有一个main()函数,而且该函数不能接受任何参数。
main函数前的void关键字表示这个函数不返回任何值。
单行注释:
// int kp = 496;
多行注释: /*
数据值类型(数值和布尔值)
GLSL支持两种数据值类型
(1)数值类型:整数(没有小数点)和浮点数(有小数点)
(2)布尔值类型:true 和 false
不支持字符串类型
(1)只包括a-z,A-Z,0-9和下划线_
(2)变量名的首字母不能是数字
(3)不能是关键字和保留字,但是变量名的一部分可以是它们
(4)不能以gl_,webgl_,或_webgl_开头,这些前缀已经被OpenGL ES保留了
GLSL ES关键字
GLSL ES保留字
GLSL ES是强类型语言
(1)GLSL ES要求具体指明变量的数据类型: &类型& &变量名&
如: vec4 a_Position
(2)定义函数时,必须指定函数的返回值
(3)在进行赋值操作(=)的时候,等号左右两侧的数据类型也必须一样,否则就会出错
GLSL的基本类型
为变量指定类型有利于WebGL系统检查代码错误,提高程序的运行效率。
如: float klimt
// 浮点数变量
赋值和类型转换
= 用于赋值,赋值时要保证左侧变量的类型和右侧的值类型一致
float f2 = 8.0;
可以使用内置函数进行类型转换,如:
float f3 = float(8);
类型转换内置函数
基本类型的运算符
[1] 在进行逻辑与(&&)运算时,只有第一个表达式的计算值为true时才会计算第二个表达式。同样,在进行逻辑或(||)运算时,只有第一个表达式的值为false时才会计算第二个表达式。
[2] 逻辑异或(^^)运算的含义是:只有当左右两个表达式中有且仅有一个为true时,运算结果才是true,否则为false。
矢量和矩阵
(1)矢量和矩阵类型的变量都包含多个元素,每个元素是一个数值(整型数、浮点数和布尔值)
矢量将这些元素排成一列,可以用来表示顶点坐标或颜色值等,而矩阵将元素划分成行和列,可以用来表示变换矩阵。
(2)赋值和构造
(a) = 等号用于赋值,如:vec4 position = vec4(1.0, 2.0, 3.0, 4.0);
(b)构造函数:专门创建指定类型的变量的函数,构造函数的名称和其创建的变量类型名称总是一致的。
(3)矩阵构造函数
(a)想矩阵构造函数中传入矩阵的每一个元素的数值来构造矩阵,注意传入值的顺序必须是列主序的
(b)向矩阵构造函数中传入一个或多个矢量,按照列主序使用矢量里的元素值来构造矩阵。
// 使用两个vec2对象来创建mat2对象
vec2 v2_1 = vec2(1.0, 3.0);
vec2 v2_2 = vec2(2.0, 2.0);
mat2 m2_1 = mat2(v2_1, v2_2);
// 使用一个vec4对象来创建mat2对象
vec4 v4 = vec4(1.0, 3.0, 2.0, 4.0);
mat2 m2_2 = mat2(v4);
(c)向矩阵构造函数中出阿奴矢量和数值,按照列主序使用矢量里的元素值和直接传入的数值来构造矩阵
// 使用两个浮点数和一个vec2对象来创建mat2对象
mat2 m2 = mat2(1.0, 3.0, v2_2);
(d)向矩阵构造函数中传入单个数值,这样将生成一个对角线上元素都是该数值,其他元素为0.0的矩阵
mat4 m4 = mat4(1.0);
与矢量构造函数类似,如果传入的数值的数量大于1,有没有达到矩阵元素的数量,就会出错
mat4 m4 = mat4(1.0, 2.0, 3.0);
// 错误。mat4对象需要16个元素
(3)访问元素
为了访问矢量或矩阵中的元素,可以使用.或[]运算符
(a).运算符
任何适量的x,r或s分量都会返回第一个分量,y,g,t分量都会返回第二个分量。
vec3 v3 = vec3(1.0, 2.0, 3.0);
// 将v3设为(1.0, 2.0, 3.0)
// 设f为 1.0
// 设f为 2.0
// 设f为 3.0
// 设f为 1.0
// 设f为 1.0
将(同一个集合的)多个分量名共同置于点运算符后,就可以从矢量中同时抽取出多个分量。这个过程乘坐混合(swizzling)
如: v2 = v3.xz
此时的多个分量必须属于同一个集合,比如说,你不能使用v3.was
(b)[]运算符
矩阵中的元素从下标0开始按照列主序读取。
限制:[]中只能出现的索引值必须是常量索引值
常量索引值定义如下:
(a)整型字面量(0或1)
(b)用 const 修饰的全局变量或局部变量。不包括函数参数。
(c)循环索引
(d)由前述三条中的项组成的表达式
const int index = 0
// const 关键字表示变量是只读的
vec4 v4a = m4[index]
// 同m4[0]相同
注意,你不能使用未经const修饰的变量作为索引值,因为它不是一个常量索引值(除非它是循环索引)。
int index1 = 0
vec4 v4c = m4[index2]
// 错误:index不是常量索引
(4)运算符
对于矢量和矩阵,只可以使用比较运算符中的== 和 !=,不可以使用&、&、&=和&=。
如果想要比较矢量和矩阵的大小,应该是用内置函数,比如lessThan()。
如果你想逐分量比较,可以使用内置的函数equal()或notEqual()
矢量和矩阵可用的运算符
矢量和浮点数的运算
(1) 矢量运算
(2) 矩阵和浮点数的运算
(3)矩阵右乘矢量
(4) 矩阵左乘矢量
(5)矩阵与矩阵相乘
(1)结构体:用户自定义的类型,使用关键字 struct,将已存在的类型聚合到一起,就可以定义为结构体。如:
struct light {
定义结构体light
// 光的颜色
// 广元位置
light 11, 12;
// 声明了light类型的变量11和12
也可以在定义结构体的同时声明该结构体类型类型的变量,如:
struct light {
定义结构体和定义变量同时进行
// 光的颜色
// 广元位置
// 该结构体类型的变量11
(2)赋值和构造
结构体有标准的构造函数,其名称与结构体名一致。构造函数的参数的顺序必须与结构体定义中的成员顺序一致。
结构体构造函数的使用方法
(3)访问成员
在结构体变量名后跟点运算符(.),然后再加上成员名,就可以访问变量的成员。如:
vec4 color = 11.
vec3 position = 11.
ELSL ES 只支持一维数组,而且数组对象不支持pop()和push()等操作,创建数组时也不需要使用new运算符。
声明数组,只需要在变量名后加上中括号和数组长度,如:
float floatArray[4];
// 声明含有4个浮点数元素的数组
vec4 vec4Array[2];
声明含有两个vec4对象的数组
数组的长度必须是大于0的整型常量表达式,定义如下:
(a)整型字面量(如0或1)
(b)用const限定字修饰的全局变量或局部变量,不包括函数参数
(c)由前述两条中的项组成的表达式
int size = 4;
vec4 vec4Array[size];
// 错误。如果第一行为const int size = 4;则不会报错
注意,你不可以用const限定字来修饰数组本身。
只有整型常量表达式和uniform变量可以被用作数组的索引值。
数组不能在声明时被一次性地初始化,而必须显式地对每个元素进行初始化。如:
vec4Array[0] = vec4(4.0, 3.0, 6.0, 1.0);
vec4Array[1] = vec4(3.0, 2.0, 0.0, 1.0);
数组本身只支持[]运算符,但数组的元素能够参与其自身类型支持的任意运算。如:
// 将floatArray的第二个参数乘以3.14
float f = floatArray[1] * 3.14;
// 将vec4Array的第一个参数乘以vec4(1.0, 2.0, 3.0 ,4.0)
vec4 v4 = vec4Array[0] * vec4(1.0, 2.0, 3.0 ,4.0);
取样器(纹理)
必须通过取样器(sampler)类型变量访问纹理。
有两种基本类型的取样器类型:sampler2D 和 samplerCube
取样器变量只能是uniform变量,或者需要访问纹理的函数,如texture2D()函数的参数,如:
uniform sampler2D u_S
只有纹理单元编号可以给取样器变量,而且必须使用gl.uniformli()来进行赋值。
除了=、==和!=,取样器变量不可以作为操作数参与运算。
取样器变量受到着色器支持的纹理单元的最大数量限制。
着色器中取样器类型变量的最小数量
mediump是一个精度限定字
运算符优先级
程序流程控制:分支和循环
(1)if 和 if-else
if语句格式
if (distance & 0.5) {
gl_fragColor = vec4(1.0, 0.0, 0.0, 1.0);
gl_fragColor = vec4(0.0, 1.0, 0.0, 1.0);
(2)for语句
for语句格式
for (int i = 0; i & 3; i++) {
注意:循环变量i只能在初始化表达中定义,条件表达式可以为空,如果这样做,空的条件表达式返回true。
for语句的其他限制:
(a)只允许有一个循环变量,循环变量只能是int或float类型。
(b)循环表达式必须是以下的形式:i++,i--,i+=常量表达式或i-=常量表达式
(c)条件表达式必须是循环变量与整型常量的比较
(d)在循环体内,循环变量不可被赋值
这些限制的存在是为了使编译器就能够对for循环进行内联展开
(3)continue、break和discard语句
(a)continue终止包含该语句的最内层循环和执行循环表达式(递增/递减循环变量),然后执行下一次循环
(b)break中止包含该语句的最内层循环,并不在继续执行循环。
// continue case
for (int i = 0; i & 10; i++) {
if (i == 8) {
// 跳过循环体余下的部分,继续下次循环
// 当i==8时,不会执行到这里
// break case
for (int i = 0; i & 10; i++) {
if (i == 8) {
// 跳出for循环
// 当i&=8时,不会执行这里
// 当i==8时,执行这里
关于discard,它只能在片元着色器中使用,表示放弃当前片元直接处理下一片元。
函数语句格式
可以没有return语句,但是返回类型必须是void
也可以将自己定义的结构体指定为返回类型,但是结构体的成员中不能有数组。
// RGBA颜色值转为亮度值函数
float luma(vec4, color) {
return 0.2126 * color.r +
0.7162 * color.g +
0.0722 * color.b;
attribute vec4 a_Color
// 传了(r, g, b, a)的值
void main() {
float brightness = luma(a_Color);
注意,如果调用函数时传入的参数类型与生命函数时指定的参数类型不一致,就会出错。
float square(float value) {
return value *
void main() {
float x2 = square(10);
// 错误。应用10.0
因为函数声明时的参数是float类型,而调用时却传入了int类型的值。
(2)规范声明
如果函数定义在其调用之后,那么我们必须在进行调用之前先声明该函数的规范。
规范会预先告诉WebGL系统函数的参数、参数类型、返回值等等
float luma(vec4, color);
// 规范声明
float brightness = luma(a_Color);
// luma在定义之前就被调用了
float luma(vec4, color) {
return 0.2126 * color.r +
0.7162 * color.g +
0.0722 * color.b;
(3)参数限定词
GLSL ES中,可以为参数指定限定自,以控制参数的行为。
我们可以将函数参数定义成:
(a)传递给函数的
(b)将要在函数中被复制的
(c)既是传递给函数的,也是将要在函数中被赋值的。
其中(b)和(c)都有点类似于C语言中的指针
(4)内置函数
全局变量和局部变量
attribute、varying和uniform变量都必须声明为全局变量
(1)存储限定字
在GLSL ES中,我们经常使用attribute、varying和uniform限定字来修饰变量,如下图所示。此外,有时也会使用const限定字,它表示着色器中的某个变量是恒定的常量。
(2)const变量
const变量写在类型之前,声明的同时必须对它进行初始化,声明之后就不能再去改变它们的值了。
const int a = 3232
(3)Attributr变量
只能出现在顶点着色器中,只能被声明为全局变量,被用来表示逐顶点的信息。
顶点着色器中能够容纳的attribute变量的最大数目与设备有关,你可以通过访问内置的全局常量来获取最大数目的值。
但是不管设备如何,支持WebGL的环境都支持至少8个attribute变量。
(4)uniform变量
可以用在顶点着色器和片元着色器中,且必须是全局变量。
uniform变量只读,可以是除了数组或结构体之外的任意类型。
如果在顶点着色器和片元着色器中声明了同名的uniform变量,那么它就会被两种着色器共享。
uniform变量包含了一致(非逐顶点/逐片元的,各顶点或各片元公用)的数据,JS应该向其传递此类数据。
比如,变换矩阵就不是逐定点的,而是所有顶点共用的,所以它在着色器中是uniform变量。
uniform mat4 u_ViewMatrix
(5)varying变量
必须是全局变量
从顶点着色器向片元着色器传输数据。
必须在两种着色器中生命同名、同类型的varying变量
varying vec2 v_TexCoord
varying vec4 v_Color
varying变量只能是以下类型:float、vec2、vec3、vec4、mat2、mat3和mat4
顶点着色器中赋给varying变量的值并不是直接传给了片元着色器的varying变量,这其中发生了光栅化的过程:根据绘制的图形,对前者(顶点着色器varying变量)进行内插,然后再传递个后者(片元着色器varying变量)
正是因为varying变量需要被内插,所以我们需要限制它的数据类型
设备至少支持8个varying变量
精度限定字
帮助着色器程序提高运行效率,削减内存开支。
可选,不确定精度可以使用适中的默认值:
#ifdef GL_ES
WebGL中支持的3种精度
(1)在某些WebGL环境中,片元着色器可能不支持highp精度
(2)数值范围和精度实际上也是与系统环境相关,可以使用gl.getShaderPrecisionFormet()来检查
中精度浮点型变量
highp vec4
具有高精度浮点型的vec4对象
具有低精度浮点型的vec4对象
声明着色器的默认精度,这行代码必须在顶点着色器或片元着色器的顶部:
precision 精度限定自 类型名称
表示接下来所有不以精度限定自修饰的该类型标量,其精度就是默认精度,如:
只有片元着色器中的float类型没有默认精度,我们需要手动指定。
预处理指令
用来在真正编译之前对代码进行预处理,#开始
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
支持高精度,限定浮点型为高精度
不支持高精度,限定浮点型为中精度
可以只是用#version number来指定着色器使用的GLSL ES版本
可以接受的版本包括100(GLSL ES 1.00)和101(GLSL ES 1.01)。如果不使用#version命令,默认版本为100。
指定版本代码:
#version 101
#version 指令必须在着色器顶部,在它之前只能有注释和空白。
Web小前端,东野圭吾迷妹~
个人博客:http://hysunny.me/前端在线资源
本文地址:
一、前面的所以然
技术的发展日新月异,说不定回家钓几天鱼,就出来个新东西了。新事物新技术发展的初期,你无法预见其未来之趋势,生命诚可贵,没有必要花过多时间深入研究这些新东西,不过,知道了大概,了解个全貌还是很有必要的。虽不是时代缔造者,也不至于落后于时代发展大潮。
互联网的发展相当的神速,其他不说,就前端技术这块,出现的些新名词或生名词就让人眼花缭乱,应接不暇,比如说:HTML5 Canvas, WebGL, CSS Shaders, GLSL等。你是否有这样的疑问:这些都是些什么玩意?是喜欢打酱油还是客串CCTV群众演员?他们之间是否有暧昧,或是跨辈分的恩怨情仇?
好吧,我就八卦下这些前端前沿技术相关名字。
二、各自庐山面目
HTML5 Canvas
这个想必听过的人不少,所以这里匆匆数行带过。HTML5 Canvas实际上就是个画布元素,使用JavaScript在上面画图形,像是之类。
目前在web实际项目中已有不少应用。例如图像的旋转,圆角的生成等。低版本的IE浏览器不支持该元素,还在可以通过调用如下JS可以让其支持部分canvas的功能:
标题中并未出现OpenGL,一是因为标题已经很长了,而是这个东东并不专属于web前端领域。
OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库,是行业领域中最为广泛接纳的 2D/3D 图形 API,是个与硬件无关的软件接口,其自诞生至今已催生了各种计算机平台及设备上的数千优秀应用程序。
OpenGL使用简便,效率高。它具有七大功能:建模、变换、颜色模式设置、光照和材质设置、纹理映射(Texture Mapping)、位图显示和图象增强图象功能和双缓存动画(Double Buffering)。
具体可参见
WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。
由于webgl是基于OpenGL和JavaScript技术结合,而OpenGL与微软DirectX存在着竞争关系,而且微软自身也开发了Silverlight插件,与webgl其实是类似的,所以微软对webgl技术并不支持。这很好理解,好比五阿哥和尔康在争夺心爱的容嬷嬷之前是不可能相互拥抱的。
微软的不支持并不影响webgl的发展,随着firefox、谷歌和苹果等加入,webgl也开始出现了各种应用。例如小有名气的基于webgl技术的实验项目,用户可以查看3D人体结构(下图来自cnbeta)。
GLSL为OpenGL着色语言(GLSL――OpenGL Shading Language)(后面的可以不用看,都是专业术语,一个头,两个大)。 是开发人员用来在OpenGL中着色编程编写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分。比如:视图转换、投影转换等。GLSL(GL Shading Language)的着色器代码分成2个部分:Vertex Shader(顶点着色器)和Fragment(片断着色器),有时还会有Geometry Shader(几何着色器)。负责运行顶点着色的是顶点着色器。它可以得到当前OpenGL 中的状态,GLSL内置变量进行传递。
CSS Shaders
是上周举行的Adobe Max上,Adobe公司推出的一个全新的项目。
这项由Adobe和Apple、Opera合作研发的新标准已经提交至W3C,将为CSS技术带来3D图形特性。
Shader(着色器)可以理解为是一种运行于显卡端的小程序,通常用于游戏和其他图形相关的应用。着色器有两种,一种是顶点着色器,用于控制几何体的顶点以绘制出3D表面网格;另一种是片元着色器,用于控制像素的颜色。CSS Shaders技术将允许开发者同时使用顶点着色器和片元着色器。
在CSS中使用着色器可以制作出很多吸引眼球的动态效果。
Adobe展示了一些Demo视频,在第一个视频中Twitter的页面被渲染成了弯曲的表面;第二个视频更加有趣,将Google地图和街景渲染折叠了起来,像真的纸质地图那样。因为着色器可以作用于所有HTML内容,所以CSS Shaders渲染的元素包括了普通的表格、SVG甚至是HTML5 Video等等。
CSS目前已经可以制作一些3D动画效果,但是着色器这个关键角色的加入,将使这项技术变得更加灵活,提高了可编程性。CSS Shaders可以与Adobe Edge配合使用,制作出更多动态效果的网页。Adobe称未来Edge将拥有更强的表现力,而CSS Shaders正是为了达到这个目的而推出的。
CSS Shaders内置了一些常用的滤镜,包括设置模糊、阴影、色调、翻转、灰度、透明度、Gamma值等。另外也允许开发者自己编写着色器代码,使用的语言——不出所料,和WebGL一样——是GLSL。
有人可能会疑问,貌似CSS Shaders跟WebGL作用和接近,使用语言也一致,会不会发生冲突啊。根据Adobe的某些人员的说法,WebGL只能作用于一个Canvas,而CSS Shaders适用于任何Web内容。CSS的本意就是用来定义网页样式的,Shader的加入毋庸置疑可以大大增加灵活度,让开发者有更多的方式去创造出更具想象力的网页。两者是没有冲突滴~~
目前,貌似没有浏览器鸟这厮,俺们需要静观些时日。
三、关系整理
上面的表述中多少透露个各个名词之间的关系。所谓一图胜前言,什么妈妈的二姑的三舅妈的小外孙家的一条狗身上的虱子之类的话就免了,直接上图:
恩,为避免唠叨之嫌,其他我就不多说什么了。
四、文章提及&参考页面
原创文章,转载请注明来自[]
本文地址:
(本篇完)
相关文章 (0.885) (0.550) (0.550) (0.550) (0.550) (0.550) (0.550) (0.550) (0.550) (0.550) (RANDOM - 0.115)
标签: , , , , , ,
赞助商推荐():
想学到点真东西?
如果你有1~3年前端开发经验,不妨
想找个师兄入门前端?不妨
想快速入门前端?
热门总排行1603人阅读
&=即时总结=&(742)
平台-iOS(259)
平台-Html5(70)
数据呈现-OpenGL ES(124)
WebGL 中 OpenGL ES 指令与 iOS 中 C 版指令的差异简析太阳火神的美丽人生 ()本文遵循“”创作公用协议WebGL 中 OpenGL ES 指令与 iOS 中 C 版指令的差异,从整体上看,应该是 gl 前缀在 WebGL 版指令中的省略,举例对比如下:
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
gl.enable(gl.CULL_FACE);
gl.frontFace(gl.CW);
从上面的示例中,可以看出,C 版使用的是全局的函数,面向过程的用法,故无所属对象;而 WebGL 中封装成对象的方法后,通过 gl 对象(WebGL 对象的实例)的方法的形式来调用封装于 WebGL 对象中封装的与 C 版对应的指令,故省略 C 版指令的 gl 前缀也是在情理之中的。至于 gl 对象,是按如下方式创建的:
function initGL(canvas) {
gl = canvas.getContext(&experimental-webgl&);
gl.viewportWidth = canvas.
gl.viewportHeight = canvas.
} catch (e) {
if (!gl) {
alert(&Could not initialise WebGL, sorry :-(&);
上面代码中的 canvas 是 html5 中的新增标签,通常使用其获取 2d 的上下文来进行绘图,在 WebGL 时代,新增了如上实现,能对 WebGL 进行支持。
var canvas = document.getElementById(&lesson13-canvas&);
&canvas id=&lesson13-canvas& style=&border:& width=&500& height=&500&&&/canvas&
更多的差异,后续不断发现,再随时补充进来。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1228576次
积分:16494
积分:16494
排名:第646名
原创:336篇
转载:286篇
译文:131篇
评论:134条
Your browser does not support the HTML5 audio tag.
文章:15篇
阅读:27710
阅读:7767
阅读:1083
阅读:8328
文章:18篇
阅读:20090
文章:24篇
阅读:59250
阅读:15060
阅读:10491
文章:10篇
阅读:20035
(3)(1)(1)(5)(1)(6)(1)(3)(10)(57)(7)(14)(11)(5)(13)(11)(2)(18)(16)(24)(9)(18)(99)(5)(8)(29)(29)(32)(67)(16)(20)(21)(109)(72)(10)

我要回帖

更多关于 苹果7和苹果8的区别 的文章

 

随机推荐