12. Html5的局:WebGL跨平台的取与舍-阿里云开发者社区

开发者社区> 淘朗英> 正文

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嘛。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
datapump跨平台升级迁移的总结
最近测试了使用datapump来迁移百G数据的场景,因为实际需要,需要把Unix下10gR2的库迁移到Linux下11gR2,所以这个过程相对来说牵制也较多。考虑了多种方案,最后权衡后决定使用datapump来迁移。
777 0
gocommand:一个跨平台的golang命令行执行package
    最近在做一个项目的时候,需要使用golang来调用操作系统中的命令行,来执行shell命令或者直接调用第三方程序,这其中自然就用到了golang自带的exec.Command.     但是如果直接使用原生exec.
1914 0
Unity跨平台的机制原理
首先需要了解的是,Unity3D的C#基础脚本模块是通过Mono来实现的。 什么是Mono? 参考下百度百科:Mono是一个由Novell公司(由Xamarin发起)主持的项目,并由Miguel de lcaza领导的,一个致力于开创.NET在Linux上使用的开源工程。
3027 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4479 0
datapump跨平台升级迁移的对比测试和优化
    目前计划对跨平台的数据库环境进行迁移,一来降低运维成本,二来更加可控。其实对于很多机器来说,如果机器跑了很多年,一直没有重启过,那么时间长了,一个直观的感受就是稳定,这也是小机口碑远远好于PC的一个重要原因吧,但是如果机器有一天出了问题,那么可能就会让大家坐立不安。
754 0
+关注
淘朗英
专注于高性能H5内核研发,用C/C++挖掘设备硬件的潜能,让JS提升开发效率,打造一种所见即所得的开发方式。
24
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载