13. Html5的局:WebGL的模糊边界

紧接上文

WebGL是一套跨平台的渲染技术,向上提供统一的标准API,向下屏蔽了硬件厂商的差异,最大化的降低OpenGL的移植成本,同时也失去了一些特色的高级GL功能。
先看看常用的纹理数据的变化。

WebGL的标准的落地与否

标准不代表WebKit支持

就像JavaScript的E6标准不是所有浏览器都支持一样,WebGL的很多标准在不同的平台不一定支持,比如Texture的GL_BGR格式,在PC的WebKit上是支持的,在移动端的WebKit上就不一定支持,因为这一特性属于OpenGL ,但不是OpenGL ES2.0的标准。
查看OpenGL的gl.h文件,我们可以找到:

/* bgra */
#define GL_BGR                            0x80E0
#define GL_BGRA                           0x80E1

但在OpenGL ES2.0的gl.h却没有这个属性的定义,反而是在扩展文件glext.h找到了不完整的定义:

#if GL_APPLE_texture_format_BGRA8888
#define GL_BGRA_EXT                                             0x80E1
#endif

不仅属性名称发生了变化,是否支持也成了硬件的可选条件。

bold 结论:
标准是扩平台的,硬件是有差异的,标准不一定会实现。

标准在硬件上的差异

WebGL只是将OpenGL在不同硬件平台做了一套,基于OpenGL和OpenGL ES2.0的统一的规范,OpenGL 与OpenGL ES2.0在标准和用法上存在差异,而ES2.0是GL的子集。那么同一个API必然在某些场景下的用法,会存在差异。
比如,我们最常用的glTexImage2D在OpenGL的定义为:

void glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);

在GL中,internalformat和format参数可以不一致;level可以是正整数;pixels可以为空;
但在OpenGL ES2.0的规范中,API的定义可谓是完全相同:

void glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);

可是真正使用起来,参数解释就不同了,比如:在ES2.0中,internalformat和format必须相同;level必须是0;pixels在某些平台为了安全不能为空。
bold 结论
因为GL是跨平台的标准,不可能只采用ES2.0的规范,每当遇到GL与ES2.0的边缘场景,事情就会变得复杂化,再加上不同的硬件的支持不完全一致,这个时候,怎么办呢?

标准在软件上的差异

纵观网络的技术博客,我们仍然以glTexImage2D为例,关于internaformat与format参数是否一致的情况,网上出现了两种结论:

1. 以实际主义为事实的说法:可以不一致:

http://blog.csdn.net/csxiaoshui/article/details/27543615
提到:

internalFormat:指定OpenGL是如何管理纹理单元中数据格式的。网络上很多解释说这个参数必须和后面的format参数一样,这个说法是不正确的

2. 各大厂商的标准文档:必须保持一致

https://msdn.microsoft.com/zh-cn/library/dn302435(v=vs.85).aspx
提到:

format [in]
Type: Number
Contains the format for the source pixel data. Must match internalformat (see above).

这其实是OpenGL与WebGL的差异,也就是OpenGL的开发者转到WebGL开发,也是需要改变很多的,那么各大浏览器厂商在实现上,采用哪种说法呢?

3. WebKit VS FireFox:各自为政

对于internalformat与format,WebKit是直接拿来使用,不做强制约束:

    texImage2DBase(target, level, internalformat, width, height, border, format, type, data, ec);

而FireFox是严格的遵守WebGl标准,做了严格的判断:

    if (format != internalformat)
        return ErrorInvalidOperation("texImage2D: format does not match internalformat");

总结:
WebGL只是H5领域的一个标准, 无法做到对OpenGLES2.0完美的兼容,甚至有些标准属于Web独有的。熟悉WebGL的标准对于前端开发是很有帮助的,同事Native与H5的代码移植,技术挑战很大。

下回再见

WebGL弱化了OpenGL与硬件的差异,形式上统一了GL在前端的用法。WebGL的路上,既然有凸起,那么一定有凹坑,WebGL标准通过舍去一些高级特性达到统一的目的,那么就会有弥补凹坑,把一些硬件不支持的特性补充完整。
下一回,我们谈谈如何使用CPU来弥补WebGL的不足。

上一篇:datapump跨平台升级迁移的对比测试和优化


下一篇:19. Html5的局: 手把手写一个100行的VR程序