《laya 源码分析》layaAir引擎渲染主循环

1.引擎启动入口

工程的入口文件一般为Main.ts,这里面不仅需要处理项目相关的逻辑初始化,也会调用Laya3D.init()进行Laya引擎的初始化。

在init中,可以看到创建了两个画布,mainCanvas是引擎的主画布,所有游戏内的canvas和webgl渲染都用这个画布。canvas是一个全局离线画布,不会加到DOM上,主要用来测量字体、获取image数据。

《laya 源码分析》layaAir引擎渲染主循环_第1张图片

这里也可以直接查看Chrome的结构

《laya 源码分析》layaAir引擎渲染主循环_第2张图片

接下来创建一系列timer

Timer

《laya 源码分析》layaAir引擎渲染主循环_第3张图片

《laya 源码分析》layaAir引擎渲染主循环_第4张图片

然后创建一个LoaderManager 赋值给Laya.loader

LoaderManager

loaderManager负责加载,加载完后的资源放到_ResMap  / @资源map,url做key,resinfo

loaderManager默认支持五个线程 ,可修改 maxLoader

《laya 源码分析》layaAir引擎渲染主循环_第5张图片

接下来就是创建舞台

最后是创建渲染器

Render

下面看一下render的构造函数都发生了什么

	/**
	 * 初始化引擎。
	 * @param	width 游戏窗口宽度。
	 * @param	height	游戏窗口高度。
	 */
    constructor(width: number, height: number, mainCanv: HTMLCanvas) {
		Render._mainCanvas = mainCanv;
		let source:HTMLCanvasElement = Render._mainCanvas.source as HTMLCanvasElement;
        //创建主画布。改到Browser中了,因为为了runtime,主画布必须是第一个
        source.id = "layaCanvas";
        source.width = width;
        source.height = height;
        if (Render.isConchApp) {
            document.body.appendChild(source);
        }

        this.initRender(Render._mainCanvas, width, height); // 初始化wegGL环境
        window.requestAnimationFrame(loop);
        function loop(stamp: number): void {
            ILaya.stage._loop();
            window.requestAnimationFrame(loop);
        }
        ILaya.stage.on("visibilitychange", this, this._onVisibilitychange);
    }

这里发现游戏渲染的主循环是通过 window.requestAnimationFrame不断loop实现的,是程序的主要更新源头

注意 这里的window.requestAnimationFrame并不是原生的浏览器重绘接口函数,已经在前面的 brower._init_方法被覆盖了

        //兼容requestAnimationFrame
        win.requestAnimationFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || win.msRequestAnimationFrame || function (fun: any): any {
            return win.setTimeout(fun, 1000 / 60);
        }

initRender()为话不初始化函数,创建和保存了WebGL上下文环境。如需更改canvas的参数,如设置是否抗锯齿,请在初始化引擎之前设置。(修改config)

《laya 源码分析》layaAir引擎渲染主循环_第6张图片

Stage

Stage中的_loop()函数就是帧循环函数,函数内部调用render函数用于渲染当前context渲染上下文和更新逻辑。

《laya 源码分析》layaAir引擎渲染主循环_第7张图片

这里主要的功能是:清空画布-----提交渲染----更新逻辑,计时器都是在渲染后更新的

Laya的帧率只有两种,高帧率模式固定60帧,低帧率模式
为双帧处理一次渲染,固定30帧。

Sprite

stage的父物体是Sprite,Sprite是基本的显示图形的显示列表节点。默认没有宽高,默认不接受鼠标事件,通过graphics可以绘制图片或者矢量图,支持旋转,缩放,位移等操作。同时也是容器类,可用来添加多个子节点。LayaAir引擎API设计精简巧妙。核心显示类只有一个Sprite,Sprite针对不同的情况做了渲染优化,所以保证一个类实现丰富功能的同时,又达到高性能

/**
     * 更新、呈现显示对象。由系统调用。
     * @param	context 渲染的上下文引用。
     * @param	x X轴坐标。
     * @param	y Y轴坐标。
     */
    render(ctx: Context, x: number, y: number): void {
        RenderSprite.renders[this._renderType]._fun(this, ctx, x + this._x, y + this._y);
        this._repaint = 0;
}

Sprite的renders函数对renders数组(RenderSprite数组)中的第this._renderType个RenderSprite精灵进行渲染(调用_fun函数),_fun函数是RenderSprite类的方法,定义了属于不同类型的不同的渲染方式,里面都是通过调用Context类的方法进行绘制的
需要注意的是RenderSprite在Laya.init初始化的时候就已经创建了,默认是预创建了8192*2个精灵渲染器。它的渲染_fun类型会根据传入的Sprite的_renderType决定渲染方式。

Context

Context扩展类主要用来进行绘制。

流程图

《laya 源码分析》layaAir引擎渲染主循环_第8张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(laya,源码)