处理Stage3D下的不同情况

昨天, Terry Paton在Google Plus上发了一条信息,是关于使用Stage3D(Molehill)检测不同的情况,比如说它是否软件加速或者Stage3D在我的SWF里面是否可用?

这让我意识到,不同情况下,一个小的说明可能对用户来说是有帮助的。刚开始的时候可能会觉得有点复杂,但事实上并不难。一旦你将这些集成到你的代码里,就设置好了所有情况应对方式。

你需要处理的第一个情况是,当硬件配置无法满足要尝试播放的内容时候。要记住,Stage3D有一个内置自动回滚到软件加速状态,这意味着即使驱动被列黑名单,或者显卡不兼容,Stage3D会回滚到软件加速状态,然后播放内容,这保证了你的用户不会显示黑屏。

这实际上对于检测是否用软件加速很重要,原因如下:

1、告知用户这些,让他知道性能体验可能不是最佳的,让他更新驱动以提升性能。
2、或者你可以选择悄悄地回滚到软件加速状态,没有任何提示,然后调整应用中的图形,以便删除会让运行变慢的复杂效果。

一个好的做法是,依靠ContextEDRenderMode.AUTO,Stage3D会尝试在硬件加速,如果驱动太旧(2009年1月1日以前发布)、显卡不支持Pixel Shader 2.x、显卡的芯片组被列黑名单,都将回滚到软件加速状态。

所以我们会用以下的代码:

// listen to the context creation event
myStage3D.addEventListener(Event.CONTEXT3D_CREATE, onContextCreated);

// request the 3d context
myStage3D.requestContext3D(Context3DRenderMode.AUTO);

// when the context is available, grab it
function onContextCreated ( e:Event ):void
{
    // grab the 3D context
    var context3D:Context3D = myStage3D.context3D;

    // are we running hardware of software ?
    var isHW:Boolean = context3D.driverInfo.toLowerCase().indexOf("software") == -1;
}

你可能会疑惑,为什么我用indexOf来检测"software"字符串,是这样的,驱动返回的确切的字符串信息是:"Software(Direct blitting)"。

因而检测整串字符可能存在失误,我们只需要查找其中"Software"字符串。

现在已经有了简单的逻辑去检查软件加速还是硬件加速。现在让我们处理其他情况。记得使用错误的嵌入值(wmode)可能导致访问Context3D对象失败。当调用Stage3D里的requestContext3D方法时,使用任何与"direct"不同的东西,会出现运行时异常,所以处理这个情况,只要侦听ErrorEvent.ERROR事件:

// listen to the error
myStage3D.addEventListener(ErrorEvent.ERROR, onStage3DError);

// display message
function onStage3DError ( e:ErrorEvent ):void
{
    legend.text = "This content is not correctly embedded. Please change the wmode value to allow this content to run.";
}

接下来,还有设备丢失上下文要处理,通常显卡资源丢失的时候出现。在屏保显示或在Windows系统下按下CTRL+ALT+DEL的情况下会出现这个错误。要处理这个情况,你需要模拟这些情况,并确定你的应用在这种情况下重新正确初始化。要模拟丢失事件,只需要用stage3D侦听Event.CONTEXT3D_CREATE事件,然后调用context3D.dispose().

还有最后一个情况,你不想强制升级到指定的Flash Player版本,保持一致的SWF需求,但是检测是否播放器运行你的SWF有特定的API可用。就如 Si和 Zwetan提到的,有可以用以下的代码:

var stage3DAvailable:Boolean = ApplicationDomain.currentDomain.hasDefinition( "flash.display.Stage3D" );

或者用更简短的舞台对象,如StageVideo或Stage3D

var stage3DAvailable:Boolean = stage.hasOwnProperty("stage3Ds");

完成了,你已经全部设置好处理使用Stage3D(Molehill)的各种情况。

原文链接:http://www.bytearray.org/?p=3443

你可能感兴趣的:(Flash,3D,actionscript)