Away3D4.0和Starling协作教程

    在新发布的Away 3D 4.0 Gold版本中,包含了一个叫做Stage3DManager的实现Stage3D结合其他ActionScript库的渲染的API。在这个教程中,我们将通过结合Away3D和Starling架构创建一个高效的渲染循环(rendering loop),自从Stage3D加入到Air和Flash Player中,出现了很多新框架,他们通过不断的升级,尝试发挥stage3D的最大性能。其中Away3D在GPU优化方面表现良好,令开发者可以创造出令人难以置信的3D交互体验,类似的,Starling是一个旨在更完全发挥Stage3D性能的2D GPU加速框架。结合这两个东西的前提条件是一些APIs方面的改动,否则这两个框架就会在各自的Stage3D实例中渲染。可惜的是此前没有引擎可以做到这些。令人庆幸的是,随着新的Away3D 4.0 Gold版本发布,提供了融合多框架到一个Stage3D实例中的功能,我们可以轻松的结合无论多少个Away3D和Starling实例。但事实上,并不是所有基于Stage3D的框架都可以被使用——详情请见页面底部。在这个教程中,底层和顶层是Starling层,中间层是Away3D层。


效果预览

预览地址请点击此处


原理介绍

    在普通项目中,如果仅仅使用了Away3D,Stage3D内容将在实例内部处理。这虽然操作简单,但是这造成了不同实例间协作的困难。我们需要的是通过一个Stage3D实例来管理所有的Stage 3D框架的实例。这可以通过Stage3DManager和Stage3Dproxy类来实现。


// Stage manager and proxy instances  
// Stage 管理和代理实例  
private var stage3DManager : Stage3DManager;  
private var stage3DProxy : Stage3DProxy;  

/**  
 * Global initialise function  
 *全局初始化函数  
 */  
private function init():void  
{  
	stage.scaleMode = StageScaleMode.NO_SCALE;  
	stage.align = StageAlign.TOP_LEFT;  
	initProxies();  
}  

/**  
 * Initialise the Stage3D proxies  
 *Stage3D代理初始化  
 */  
private function initProxies():void  
{  
	// Define a new Stage3DManager for the Stage3D objects  
	// 为Stage3D对象定义一个新的Stage3DManager ;  
	stage3DManager = Stage3DManager.getInstance(stage);  

	// Create a new Stage3D proxy to contain the separate views  
	//创建一个新的Stage 3D 代理来管理不同的视图。  
	stage3DProxy = stage3DManager.getFreeStage3DProxy();  
	stage3DProxy.addEventListener(Stage3DEvent.CONTEXT3D_CREATED, onContextCreated);  
	stage3DProxy.antiAlias = 8;  
	stage3DProxy.color = 0x0;  
}

我们可以通过getInstance()方法调用通过单例模式使用的Stage3DManager类,通过这个实例,我们可以调用下一个可用的Stage实例渲染。但是这不是马上执行的,我们必须侦听Stage3DEvent.CONTEXT3D_CREATED时间,等待Stage分配实例。当我们处理Stage3DProxy时,就可以设置一些参数包括全局抗锯齿,背景颜色。


建立图层

一旦我们侦听到了Stage3DEvent.CONTEXT3D_CREATED事件,我们就可以创建一些渲染用的图层。正如前面所说,我们将有一个Away3D场景以及两个Starling场景,我将详细叙述建立这些渲染图层的条件,而不是每个图层的内容。

private function onContextCreated( event:Stage3DEvent ):void
{
	initAway3D();
	initStarling();
	initMaterials();
	initObjects();
	initButton();
	initListeners();
	initListeners();
}

/**
 * Initialise the Away3D views 初始化Away3D view。
 */
private function initAway3D():void
{
	// Create the first Away3D view which holds the cube objects.  
	// 创建第一个包含立方体的Away3D view  
	away3dView = new View3D();
	away3dView.stage3DProxy = stage3DProxy;
	away3dView.shareContext = true;

	hoverController = new HoverController( away3dView.camera, null, 45, 30, 1200, 5, 89.999 );
	addChild( away3dView );
	addChild( new AwayStats( away3dView ));
}

/**
 * Initialise the Starling sprites
 * 初始化 Starling sprites
 */
private function initStarling():void
{
	// Create the Starling scene to add the background wall/fireplace. 
	// This is positioned on top of the floor scene starting at the top of the screen. 
	// It slightly covers the wooden floor layer to avoid any gaps appearing.  
	//创建Starling 场景并且添加背景,这将会被安置在地板场景之上,但会轻微的覆盖地板层,避免缺口出现
}

其中onContextCreated方法是典型的方式定义了3D场景,对象,材质,事件侦听器,以及实现Starling实例化。在initAway3D方法中,我们和往常一样为Away3D场景建立了View3D对象,另外我们还通过设置了.stage3DProxy属性共享到了Stage3DProxy实例,并且设置.shareContext=true允许共享执行。相似的,在initStarling 方法中创建了Starling场景。每个场景都需要传递一个引用到Starling sprite场景,舞台和分享的Stage3D,同样我们会传递一个定义了视口大小的长方形和一个引用到我们的Stage3D实例。最后,他们都可以通过Stage3DProxy实例的.viewPort和 .stage3D属性控制。NOTE:如果想重新设置Starling Sprite的视口大小,请在Starling外部修改长方体的尺寸,这样Starling.viewPort 会返回一个科隆的长方形,而不是原来那个的引用。将它传递给构造器,并且修改外部的长方体,Starling就可以正确的渲染。现在Stage3D的共享实例拥有Away3D场景和Starling Spite层的引用,其他的图层用同样方式创建,正如你在下面的实例中可以看到的一样,你可以通过鼠标转动,拖拽它。 渲染的时候,首先呢,最下一层,也就是最开始渲染的一层,是可以旋转的棋盘格样式的一个Starling图层,在这之上是一个含有5个交叉放置的立方体的Away3D场景,它在一个网格之上。最上面,也是最后渲染的,是一个Starling粒子效果图层。


渲染

当Stage3D被共享时,我们在渲染过程中需要禁用几个函数。从最简单的角度来说,渲染一个场景需要三步,1:场景被清空-clear()方法,2:渲染元素,-drawTriangles();3:显示在屏幕上:present();其中第一步和第三部导致了Stage3D不能被共享。现在呢,away3D和Starling已经被结合到了一个Stage3D的实例中,接下来要考虑的就是在Stage 3DProxy中考虑清理[.clear()]和显示[.present()]了。Stage3DProxy类提供两种渲染设置,两者很相似但是提供对清除(clearing)和展示(presenting)不同的控制。手动控制呢我们需要精确调用Both are described here.Stage3DProxy.clear() 和 .present()方法来渲染,然而自动控制可以轻松地为我们做到这一切。



控制渲染-手动

/**  
 * Set up the rendering processing event listeners  
 * 建立渲染进程侦听器  
 */  
private function initListeners():void {  
	stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);  
}  

/**  
 * The main rendering loop  
 * 主渲染循环  
 */
private function onEnterFrame(event:Event):void
{
	// Clear the Context3D object
  // 清空Context3D 对象
	stage3DProxy.clear();  

	// Render the Starling animation layer  
	// 渲染Starling动画图层  
	starlingCheckerboard.nextFrame();  

	// Render the Away3D layer  
	// 渲染Away3D图层  
	away3dView.render();  
	
	// Render the Starling stars layer  
	// 渲染Starling 星星图层  
	starlingStars.nextFrame();  

	// Present the Context3D object to Stage3D  
	// 在Stage3D中呈现Context3D  
	stage3DProxy.present();  
}

在上面一段代码中,我们侦听了舞台实例的ENTER_FRAME 事件,接着在侦听函数中,我们调用了stage3DProxy.clear()方法,然后依次渲染了各个图层,最后调用了stage3DProxy.present()方法,这是我们可以完全地控制图层的渲染顺序和调用清除.clear和呈现.present()方法。


更加轻松的方法-自动控制

/**
 * Set up the rendering processing event listeners
 * 建立渲染侦听器
 */
private function initListeners():void
{
	stage3DProxy.addEventListener( Event.ENTER_FRAME, onEnterFrame );
}

/**
 * The main rendering loop
 * 主渲染循环
 */
private function onEnterFrame( event:Event ):void
{
	// Render the Starling animation layer  
	// 渲染Starling动画图层  
	starlingCheckerboard.nextFrame();

	// Render the Away3D layer  
	// 渲染Away3D图层  
	away3dView.render();

	// Render the Starling stars layer  
	// 渲染Starling星星图层  
	starlingStars.nextFrame();
}

这种方法的巧妙之处在于,它的ENTER_FRAME侦听器是加在Stage3DProxy object 而不是在舞台中,它自己在内部调用了clear()和present()方法,然后由你决定如何渲染。上面的例子中你可以看到在事件侦听方法中被渲染。可以在这里下载演示文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值