12. Html5的局:WebGL跨平台的取与舍

简介: # 紧接上文 在阅读WebKit源码中,讨论了Canvas在iOS平台使用的CoreGraphics框架作为渲染的工具,它运行在CPU上。WebGL是直接运行在GPU上的API,因此优化空间更大,对程序员要求更高。这次我们看看,WebGL如何对格式转换的,为我们后续three.js导入数据模型做铺设。 #常见的纹理格式 ## OpenGL ES2.0在多终端的差异 在WebKit中,默

紧接上文

在阅读WebKit源码中,讨论了Canvas在iOS平台使用的CoreGraphics框架作为渲染的工具,它运行在CPU上。WebGL是直接运行在GPU上的API,因此优化空间更大,对程序员要求更高。这次我们看看,WebGL如何对格式转换的,为我们后续three.js导入数据模型做铺设。

常见的纹理格式

OpenGL ES2.0在多终端的差异

在WebKit中,默认支持纹理格式,主要有:
screenshot

现实却是很残酷,iOS设备以上格式都是支持的,Android设备差异化就不同了,简单的说,要想确认Android是否支持某种纹理,只需要在glext.h文件中查找宏定义即可.
比如,在Android的glext.h中,却无此定义,而在iOS的OpenGL ES2.0库中,我们可以找到

#define GL_RGB16F_EXT                                           0x881B

OpenGL ES2.0中纹理格式的扩展

区别于上图的主流的纹理格式,在OpenGL ES2.0中存在大量的扩展功能

Android独有的

Android作为通用平台为不同厂家的硬件做了支持,比如AMD系列有以下扩展

/*------------------------------------------------------------------------*
 * AMD extension tokens
 *------------------------------------------------------------------------*/

/* GL_AMD_compressed_3DC_texture */
#ifndef GL_AMD_compressed_3DC_texture
#define GL_3DC_X_AMD                                            0x87F9
#define GL_3DC_XY_AMD                                           0x87FA
#endif

/* GL_AMD_compressed_ATC_texture */
#ifndef GL_AMD_compressed_ATC_texture
#define GL_ATC_RGB_AMD                                          0x8C92
#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD                          0x8C93
#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD                      0x87EE
#endif

······

iOS独有的

苹果为苹果自家的平台做了大量的高级扩展

/*------------------------------------------------------------------------*
 * APPLE extension tokens
 *------------------------------------------------------------------------*/
#if GL_APPLE_color_buffer_packed_float
#define GL_R11F_G11F_B10F_APPLE                                 0x8C3A
#define GL_RGB9_E5_APPLE                                        0x8C3D
#endif

#if GL_APPLE_clip_distance
#define GL_CLIP_DISTANCE0_APPLE           0x3000
#define GL_CLIP_DISTANCE1_APPLE           0x3001
#define GL_CLIP_DISTANCE2_APPLE           0x3002
#define GL_CLIP_DISTANCE3_APPLE           0x3003
#define GL_CLIP_DISTANCE4_APPLE           0x3004
#define GL_CLIP_DISTANCE5_APPLE           0x3005
#define GL_CLIP_DISTANCE6_APPLE           0x3006
#define GL_CLIP_DISTANCE7_APPLE           0x3007
#define GL_MAX_CLIP_DISTANCES_APPLE       0x0D32
#endif

······

Android与iOS都有,命名不同的

Android中定义为:

#define GL_BGRA_EXT                                             0x80E1

iOS中的定义:

#define GL_BGRA                                                 0x80E1

WebGL如何屏蔽底层硬件的差异

WebKit作为WebGL标准实现的程序,首先就要面临的是PC/Android/iOS/Linux等多平台,在硬件兼容上的差异。既然底层硬件无法统一,必然在标准的实现上就会有取舍。
我们先看看WebGL对应OpenGL ES2.0硬件支持的定义.

使用方式相似,数值是一样的

【类型变化了,先挖个坑,后续我们在讨论】
Native采用宏定义:

#define GL_RGBA                                          0x1908
glActiveTexture(tex);
typeof tex is unsigned int

JS使用成员变量:

var gl = canvas.getContext('webgl');
alert(gl.RGBA);
gl.activeTexture(tex);
typeof tex is WebGLTexture!

继承与兼容

OpenGL ES2.0的头文件有两个:一个是gl.h,一个是glext.h。为什么有两个,他们之间的关系是什么呢?
从表面上看,一个基本的功能包,一个扩展功能,就像打魔兽一样,等到程序员在不断的打怪升级,经验提升到6级以后,就可以开启大招了。
每个英雄就像我们的选择的GPU,基本属性都有力量、敏捷、智力、攻击力,这些功能都是大同小异的,可以完成日常的开发和bug修复。各个英雄都有自己独特的技能,就像上面我们提到的Android与iOS的差异。

gl.h是通用的

gl.h中的定义与函数,在WebGL中都可以找到,用法完全相同【暂时这么讲,先挖坑】。

定义参数 300+
定义函数 150+
都要背会哦

glext.h是各个平台的扩展

这个头文件里的内容,大不相同,为了满足部分高级程序员更高的渲染特效、性能优化,采用了各个平台的支持,比如:深度测试、蒙版测试、多种纹理格式、多线程支持、离屏渲染、管道操作、纹理压缩、视频流等等,包罗万象。
这里告诉大家一个好消息和一个坏消息。
好消息是:

WebGL对这个文件的大部分API都不支持~~

坏消息是:

该支持的API,还是要支持滴~~

兼容glext.h

实在无法统一的API,WebGL直接屏蔽掉,主要考虑两个问题:

  1. WebGL的目标是跨平台,兼容就要有牺牲
  2. 有些功能不常用,也不是行业标注

第一步,就是统一多平台的参数命名:

#define GL_DEPTH_STENCIL                        0x84F9
#define GL_DEPTH_STENCIL_ATTACHMENT             0x821A

······

第二步,增加平台无关的自定义参数

#define GL_UNPACK_FLIP_Y_WEBGL                  0x9240
#define GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL       0x9241
#define GL_CONTEXT_LOST_WEBGL                   0x9242
#define GL_UNPACK_COLORSPACE_CONVERSION_WEBGL   0x9243
#define GL_BROWSER_DEFAULT_WEBGL                0x9244

第三步,采用C/C++补全硬件平台的缺陷
例如,常见纹理格式的转换,在Android平台增加:

#define GL_RGB16F_EXT               0x881B
#define GL_RGBA16F_EXT              0x881A

#define GL_RGB32F_EXT               0x8815
#define GL_RGBA32F_EXT              0x8814

#define GL_BGRA                     GL_BGRA_EXT
#define GL_SRGB_EXT                 0x8C40
#define GL_SRGB_ALPHA_EXT           0x8C42

#define GL_ALPHA16F_EXT             0x881C
#define GL_LUMINANCE16F_EXT         0x881E
#define GL_LUMINANCE_ALPHA32F_EXT   0x8819

#define GL_ALPHA32F_EXT             0x8816
#define GL_LUMINANCE32F_EXT         0x8818
#define GL_LUMINANCE_ALPHA16F_EXT   0x881F

······

下回再见

下一章,我们继续今天的话题。

看了这么多代码,也没明白讲什么~~我也不知道该怎么讲,这可能就是OpenGL的难懂的原因吧。
众所周知,WebGL是基于OpenGL ES2.0版本的标准,而OpenGL ES2.0只是OpenGL的子集。目前所有的Mobile设备通常采用OpenGL ES2.0的硬件,以达到成本、节能、性能最大化。
但,如果是在PC上呢?PC拥有强大的GPU和完整的OpenGL能力,要自废武功来实现这个憋足的OpenGL ES2.0嘛。

目录
相关文章
|
JavaScript 前端开发 Web App开发
带你读《Three. js开发指南: 基于WebGL和HTML5在网页上渲染 3D图形和动画(原书第3版)》之一:使用Three.js创建你的第一个三维场景
本书将介绍如何直在浏览器中创建漂亮的3D场景和动画,并且充分发挥WebGL和现代浏览器的潜能。首先介绍基本概念和基础组件,然后通过逐渐扩展示例代码逐步深讲解更多高级技术。在本书中读者将学到如何从外部加载3D模型和具有真实效果的材质纹理、学习使用Three.js提供的摄像机组件来实现在3D场景中飞行和走动、如何将HTML5视频和画布作为材质贴在3D模型表面。此外还将学习变形动画和骨骼动画,甚至还会涉及在场景中使用物理模拟的方法,例如重力、碰撞检测等等。
|
3月前
|
移动开发 监控 前端开发
基于 HTML5 WebGL 和 VR 技术的 3D 机房数据中心可视化
基于 HTML5 WebGL 和 VR 技术的 3D 机房数据中心可视化
|
4月前
|
移动开发 JavaScript 前端开发
webgl学习笔记3_javascript的HTML DOM
webgl学习笔记3_javascript的HTML DOM
50 0
webgl学习笔记3_javascript的HTML DOM
|
Web App开发 移动开发 iOS开发
如何在浏览器中启用 WebGL 以使用 HTML5 3D 查看器
如何在浏览器中启用 WebGL 以使用 HTML5 3D 查看器
148 0
|
存储 移动开发 数据可视化
使用 WebGL 为 HTML5 游戏创建逼真的地形
在本文中,我将分享我们应对这些有趣挑战之一的方法:一种创建逼真的大型地形的简单方法。
67 0
|
移动开发 小程序 图形学
如何在HTML5中使用WebGL实现3D效果?底层原理是什么?
如何在HTML5中使用WebGL实现3D效果?底层原理是什么?
268 0
|
JavaScript HTML5 移动开发
带你读《Three. js开发指南: 基于WebGL和HTML5在网页上渲染 3D图形和动画(原书第3版)》之三:学习使用Three.js中的光源
本书将介绍如何直在浏览器中创建漂亮的3D场景和动画,并且充分发挥WebGL和现代浏览器的潜能。首先介绍基本概念和基础组件,然后通过逐渐扩展示例代码逐步深讲解更多高级技术。在本书中读者将学到如何从外部加载3D模型和具有真实效果的材质纹理、学习使用Three.js提供的摄像机组件来实现在3D场景中飞行和走动、如何将HTML5视频和画布作为材质贴在3D模型表面。此外还将学习变形动画和骨骼动画,甚至还会涉及在场景中使用物理模拟的方法,例如重力、碰撞检测等等。
|
JavaScript HTML5 移动开发
带你读《Three. js开发指南: 基于WebGL和HTML5在网页上渲染 3D图形和动画(原书第3版)》之二:构建Three.js应用的基本组件
本书将介绍如何直在浏览器中创建漂亮的3D场景和动画,并且充分发挥WebGL和现代浏览器的潜能。首先介绍基本概念和基础组件,然后通过逐渐扩展示例代码逐步深讲解更多高级技术。在本书中读者将学到如何从外部加载3D模型和具有真实效果的材质纹理、学习使用Three.js提供的摄像机组件来实现在3D场景中飞行和走动、如何将HTML5视频和画布作为材质贴在3D模型表面。此外还将学习变形动画和骨骼动画,甚至还会涉及在场景中使用物理模拟的方法,例如重力、碰撞检测等等。
|
移动开发 HTML5 容器
基于 HTML5 WebGL 的 3D 网络拓扑结构图
现在,3D 模型已经用于各种不同的领域。在医疗行业使用它们制作器官的精确模型;电影行业将它们用于活动的人物、物体以及现实电影;视频游戏产业将它们作为计算机与视频游戏中的资源;在科学领域将它们作为化合物的精确模型;建筑业将它们用来展示提议的建筑物或者风景表现;工程界将它们用于设计新设备、交通工具、结构以及其它应用领域;在最近几十年,地球科学领域开始构建三维地质模型,而且 3D 模型经常做成动画,例如,在故事片电影以及计算机与视频游戏中大量地应用三维模型。
2084 0