Cesium高阶学习四、Cesium绘制渲染的流程

一、从构造函数入手
new Cesium.Viewer()是Cesium一切的起点,我们从该构造函数开始,看看Cesium绘制一帧的大概流程,打开Viewer.js源码:
在这里插入图片描述

我们可以看到在Viewer类的构造函数中,通过我们传递进来的参数,进行了一些初始化,其中最核心的是:

 // Cesium widget
  const cesiumWidget = new CesiumWidget(cesiumWidgetContainer, {
   
    baseLayer:
      createBaseLayerPicker ||
      defined(options.baseLayer) ||
      defined(options.imageryProvider)
        ? false
        : undefined,
    clock: clock,
    skyBox: options.skyBox,
    skyAtmosphere: options.skyAtmosphere,
    sceneMode: options.sceneMode,
    mapProjection: options.mapProjection,
    globe: options.globe,
    orderIndependentTranslucency: options.orderIndependentTranslucency,
    contextOptions: options.contextOptions,
    useDefaultRenderLoop: options.useDefaultRenderLoop,
    targetFrameRate: options.targetFrameRate,
    showRenderLoopErrors: options.showRenderLoopErrors,
    useBrowserRecommendedResolution: options.useBrowserRecommendedResolution,
    creditContainer: defined(options.creditContainer)
      ? options.creditContainer
      : bottomContainer,
    creditViewport: options.creditViewport,
    scene3DOnly: scene3DOnly,
    shadows: options.shadows,
    terrainShadows: options.terrainShadows,
    mapMode2D: options.mapMode2D,
    blurActiveElementOnCanvasFocus: options.blurActiveElementOnCanvasFocus,
    requestRenderMode: options.requestRenderMode,
    maximumRenderTimeChange: options.maximumRenderTimeChange,
    depthPlaneEllipsoidOffset: options.depthPlaneEllipsoidOffset,
    msaaSamples: options.msaaSamples,
  });

通过传递到Viewer中的参数,构造了一个CesiumWiget对象。

二、CesiumWiget.render

打开CesiumWidget.js源码:
在这里插入图片描述

此类中创建了scene对象
在这里插入图片描述

注意我们发现使用了默认的循环渲染,我们看看该属性的定义

  this._useDefaultRenderLoop = undefined;
  this.useDefaultRenderLoop = defaultValue(
      options.useDefaultRenderLoop,
      true
   );

在这里插入图片描述

以看到在startRenderLoop函数内调用requestAnimationFrame函数进行不断地循环渲染,我们所说的绘制一帧,就是requestAnimationFrame函数执行一次的过程。在requestAnimationFrame函数内部,核心代码为:

1、widget.resize();
2、widget.render();

widget.resize方法:主要作用是根据当前窗口的宽高,更新canvas大小,然后更新相机和视口大小。

/**
 * Updates the canvas size, camera aspect ratio, and viewport size.
 * This function is called automatically as needed unless
 * <code>useDefaultRenderLoop</code> is set to false.
 */
CesiumWidget.prototype.resize = function () {
   
  const canvas = this._canvas;
  if (
    !this._forceResize &&
    this._canvasClientWidth === canvas.clientWidth &&
    this._canvasClientHeight === canvas.clientHeight &&
    this._lastDevicePixelRatio === window.devicePixelRatio
  ) {
   
    return;
  }
  this._forceResize = false;

  configureCanvasSize(this);
  configureCameraFrustum(this);

  this._scene.requestRender();
};

widget.render方法:里面主要是调用scene对象的方法,首先是调用scene.initializeFrame初始化帧的状态,然后调用scene.render方法并传入当前时间进行渲染。

/**
 * Renders the scene.  This function is called automatically
 * unless <code>useDefaultRenderLoop</code> is set to false;
 */
CesiumWidget.prototype.render = function () {
   
  if (this._canRender) {
   
    this._scene.initializeFrame();
    const currentTime = this._clock.tick();
    this._scene.render(currentTime);
  } else {
   
    this._clock.tick();
  }
};

绘制流程图谱:
在这里插入图片描述

三、剖析Scene.render()

打开Scene.js源码:
在这里插入图片描述

Scene类构造函数中的重要初始化操作,

1、创建Context绘图上下文对象,使用原生WebGL绘图,您绘先获取一个绘图上下文对象,而此处的绘图上下文,就是类似WebGL绘图上下文。

const context = new Context(canvas, contextOptions);

2、创建FrameState这状态对象,帧状态对象保存了当前一帧的相关信息。

this._frameState = new FrameState(
    context,
    new CreditDisplay(creditContainer, " • ", creditViewport),
    this._jobScheduler
  );

3、创建存储Primitive的集合(包含贴地类型)

 this
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cesium进阶学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值