webgl丢失上下文
一、原理
WebGL使用了计算机的图形硬件,而这部分资源是被操作系统管理,由包括浏览器在内的多个应用程序共享。如果一个程序接管了图形硬件,或者操作系统进入休眠,浏览器就会失去使用这些资源的权力,并导致存储在硬件中的数据丢失。在这种情况下,WebGL绘图上下文就会丢失。比如,如果你正在一台笔记本电脑或者智能手机上运行WebGL程序,然后使其进入休眠状态,通常此时浏览器的控制台会显示一条错误消息。当你将电脑或手机重新唤醒后,操作系统确实回到了休眠前的状态,但是浏览器中运行的WebGl程序却不见了。(王爷的背景色是白色,所以浏览器上一篇空白。)(计算机被从休眠模式唤醒后WebGL程序停止)
在Windows XP上,当系统具有电源管理事件,(如进入睡眠状态或屏保保护程序被激活)时,可能会发生这种状况。在Window高版本中,这种情况不多,但如果硬件挂起或驱动程序停止时仍然会发生。当设备丢失时,位于图形内存中的资源将丢失,并将忽略渲染相关操作。要想恢复,应用程序必须释放视频内存资源并重置设备。默认情况下,当发生设备丢失时,ANGLE会在GL调用上生成内存不足错误,并在EGL调用上生成上下文丢失错误,以指示上下文处于未定义状态。正确的响应是销毁所有GL上下文,重新创建上下文,然后根据需要恢复任何状态和对象。
二、错误提示:
WebGL error CONTEXT_LOST_WEBGL in uniformMatrix4fv([object WebGLUniformLocation, false, [object Float32Array])
或者:WAENING:WebGL content on the page mighthave caused the graphics card to reset
这条信息提示,系统进入休眠状态前或被唤醒后,浏览器正在调用gl.uniform-Matrix4fv(函数)并出错了。这条消息的具体内容依赖于进行上下文丢失时程序正在做什么。
三、如何响应上下文丢失
WebGL提供供了两个事件来表示这种情况,上下文丢失时触发(webglcontextlost),上下文恢复事件(当浏览器完成WebGL系统的重置后触发webglcontextrestored)
当上下文事件丢失的时候,由getWebGlContext()函数获得的渲染上下文对象gl就失效了,而之前在gl上的所有操作,如创建缓冲区对象和纹理对象,初始化着色器,设置背景色等等,也都失效了。浏览器重置WebGl系统后,就出发了上下文恢复事件,这时我们需要重新完成上述步骤。在javascript中保存的变量不会受到影响,可以照常使用。
我们需要使用<canvas>的addEventLisenter()函数注册上下文丢失事件和上下文恢复事件的响应函数。<canvas>并不支持某个特殊的属性来注册关于上下文事件的响应函数,所以必须使用addEventListener()函数。(如果上下文丢失后,浏览器还没有发现出错,系统就已经休眠了,那么系统被唤醒后浏览器就会继续执行程序,发现并报告错误。)
canvas.addEventListener('webglcontextlost',contextLost, false); canvas.addEventListener('webglcontextrestored',function(ev){start(canvas);false}, false); funtion contextLost(ev){ cancelAnimationFrame(g_requestID);//停止动画,mian()函数中定义的全局变量,函数的返回值。(停止调用产生动画的函数以保证在上下文恢复之前不再尝试重绘) ev。preventDefault();//组织浏览器的默认处理行为。(浏览器对上下文丢失事件的默认行为是,不再触发上下文恢复事件,而本例是需要触发事件,所以我们要阻止浏览器的默认行为。) }