紧接上文
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的不足。