|
@@ -1,395 +1,398 @@
|
|
|
-module INSPECTOR {
|
|
|
+import { Tab } from "./Tab";
|
|
|
+import { Inspector } from "../Inspector";
|
|
|
+import { Scene, Engine, Nullable, SceneInstrumentation, EngineInstrumentation, Tools } from "babylonjs";
|
|
|
+import { TabBar } from "./TabBar";
|
|
|
+import { Helpers } from "../helpers/Helpers";
|
|
|
|
|
|
- export class StatsTab extends Tab {
|
|
|
+export class StatsTab extends Tab {
|
|
|
|
|
|
- private _inspector: Inspector;
|
|
|
+ private _inspector: Inspector;
|
|
|
|
|
|
- /**
|
|
|
- * Properties in this array will be updated
|
|
|
- * in a render loop - Mostly stats properties
|
|
|
- */
|
|
|
- private _updatableProperties: Array<{ elem: HTMLElement, updateFct: () => string }> = [];
|
|
|
+ /**
|
|
|
+ * Properties in this array will be updated
|
|
|
+ * in a render loop - Mostly stats properties
|
|
|
+ */
|
|
|
+ private _updatableProperties: Array<{ elem: HTMLElement, updateFct: () => string }> = [];
|
|
|
|
|
|
- private _scene: BABYLON.Scene;
|
|
|
- private _engine: BABYLON.Engine;
|
|
|
- private _glInfo: any;
|
|
|
+ private _scene: Scene;
|
|
|
+ private _engine: Engine;
|
|
|
+ private _glInfo: any;
|
|
|
|
|
|
- private _updateLoopHandler: any;
|
|
|
- private _refreshRateCounter: any;
|
|
|
- private refreshRate: any;
|
|
|
+ private _updateLoopHandler: any;
|
|
|
+ private _refreshRateCounter: any;
|
|
|
+ private refreshRate: any;
|
|
|
|
|
|
- private _sceneInstrumentation: BABYLON.Nullable<BABYLON.SceneInstrumentation>;
|
|
|
- private _engineInstrumentation: BABYLON.Nullable<BABYLON.EngineInstrumentation>;
|
|
|
+ private _sceneInstrumentation: Nullable<SceneInstrumentation>;
|
|
|
+ private _engineInstrumentation: Nullable<EngineInstrumentation>;
|
|
|
|
|
|
- private _inputElement: HTMLInputElement;
|
|
|
+ private _inputElement: HTMLInputElement;
|
|
|
|
|
|
- private _connectToInstrumentation() {
|
|
|
- if (this._sceneInstrumentation) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- this._sceneInstrumentation = new BABYLON.SceneInstrumentation(this._scene);
|
|
|
- this._sceneInstrumentation.captureActiveMeshesEvaluationTime = true;
|
|
|
- this._sceneInstrumentation.captureRenderTargetsRenderTime = true;
|
|
|
- this._sceneInstrumentation.captureFrameTime = true;
|
|
|
- this._sceneInstrumentation.captureRenderTime = true;
|
|
|
- this._sceneInstrumentation.captureInterFrameTime = true;
|
|
|
- this._sceneInstrumentation.captureParticlesRenderTime = true;
|
|
|
- this._sceneInstrumentation.captureSpritesRenderTime = true;
|
|
|
- this._sceneInstrumentation.capturePhysicsTime = true;
|
|
|
- this._sceneInstrumentation.captureAnimationsTime = true;
|
|
|
-
|
|
|
- this._engineInstrumentation = new BABYLON.EngineInstrumentation(this._engine);
|
|
|
- this._engineInstrumentation.captureGPUFrameTime = true;
|
|
|
+ private _connectToInstrumentation() {
|
|
|
+ if (this._sceneInstrumentation) {
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- constructor(tabbar: TabBar, insp: Inspector) {
|
|
|
- super(tabbar, 'Stats');
|
|
|
+ this._sceneInstrumentation = new SceneInstrumentation(this._scene);
|
|
|
+ this._sceneInstrumentation.captureActiveMeshesEvaluationTime = true;
|
|
|
+ this._sceneInstrumentation.captureRenderTargetsRenderTime = true;
|
|
|
+ this._sceneInstrumentation.captureFrameTime = true;
|
|
|
+ this._sceneInstrumentation.captureRenderTime = true;
|
|
|
+ this._sceneInstrumentation.captureInterFrameTime = true;
|
|
|
+ this._sceneInstrumentation.captureParticlesRenderTime = true;
|
|
|
+ this._sceneInstrumentation.captureSpritesRenderTime = true;
|
|
|
+ this._sceneInstrumentation.capturePhysicsTime = true;
|
|
|
+ this._sceneInstrumentation.captureAnimationsTime = true;
|
|
|
+
|
|
|
+ this._engineInstrumentation = new EngineInstrumentation(this._engine);
|
|
|
+ this._engineInstrumentation.captureGPUFrameTime = true;
|
|
|
+ }
|
|
|
|
|
|
- this._inspector = insp;
|
|
|
+ constructor(tabbar: TabBar, insp: Inspector) {
|
|
|
+ super(tabbar, 'Stats');
|
|
|
|
|
|
- this._scene = this._inspector.scene;
|
|
|
- this._engine = this._scene.getEngine();
|
|
|
- this._glInfo = this._engine.getGlInfo();
|
|
|
+ this._inspector = insp;
|
|
|
|
|
|
- this._connectToInstrumentation();
|
|
|
+ this._scene = this._inspector.scene;
|
|
|
+ this._engine = this._scene.getEngine();
|
|
|
+ this._glInfo = this._engine.getGlInfo();
|
|
|
|
|
|
- // Build the stats panel: a div that will contains all stats
|
|
|
- this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
|
|
|
- this._panel.classList.add("stats-panel")
|
|
|
-
|
|
|
- let title = Helpers.CreateDiv('stat-title1', this._panel);
|
|
|
- let fpsSpan = Helpers.CreateElement('span', 'stats-fps');
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: fpsSpan,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._inspector.scene.getEngine().getFps(), 0) + " fps" }
|
|
|
- });
|
|
|
-
|
|
|
- let versionSpan = Helpers.CreateElement('span');
|
|
|
- versionSpan.textContent = `Babylon.js v${BABYLON.Engine.Version} - `;
|
|
|
- title.appendChild(versionSpan);
|
|
|
- title.appendChild(fpsSpan);
|
|
|
-
|
|
|
- this._updateLoopHandler = this._update.bind(this);
|
|
|
- this._refreshRateCounter = 0;
|
|
|
- this.refreshRate = 4;
|
|
|
-
|
|
|
- // Count block
|
|
|
- title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
- title.textContent = "Count";
|
|
|
- {
|
|
|
- this._createStatLabel("Total meshes", this._panel);
|
|
|
- let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.meshes.length.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Draw calls", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._sceneInstrumentation!.drawCallsCounter.current.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Texture collisions", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._sceneInstrumentation!.textureCollisionsCounter.current.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Total lights", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.lights.length.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Total vertices", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.getTotalVertices().toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Total materials", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.materials.length.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Total textures", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.textures.length.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Active meshes", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.getActiveMeshes().length.toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Active indices", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.getActiveIndices().toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Active bones", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.getActiveBones().toString() }
|
|
|
- });
|
|
|
-
|
|
|
- this._createStatLabel("Active particles", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._scene.getActiveParticles().toString() }
|
|
|
- });
|
|
|
- }
|
|
|
+ this._connectToInstrumentation();
|
|
|
|
|
|
- title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
- title.textContent = "Duration";
|
|
|
- {
|
|
|
- this._createStatLabel("Properties refresh rate (per second)", this._panel);
|
|
|
- let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._inputElement = Inspector.DOCUMENT.createElement('input');
|
|
|
- this._inputElement.value = this.refreshRate;
|
|
|
- elemValue.appendChild(this._inputElement);
|
|
|
- this._inputElement.addEventListener('keyup', (evt : KeyboardEvent)=> {
|
|
|
- this.refreshRate = this._inputElement.value;
|
|
|
- })
|
|
|
- this._createStatLabel("Meshes selection", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.activeMeshesEvaluationTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Render targets", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.renderTargetsRenderTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Particles", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.particlesRenderTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Sprites", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.spritesRenderTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Animations", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.animationsTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Physics", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.physicsTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Render", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.renderTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Frame", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.frameTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("Inter-frame", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.interFrameTimeCounter.current) }
|
|
|
- });
|
|
|
- this._createStatLabel("GPU Frame time", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.current * 0.000001) }
|
|
|
- });
|
|
|
- this._createStatLabel("GPU Frame time (average)", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.average * 0.000001) }
|
|
|
- });
|
|
|
- this._createStatLabel("Potential FPS", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return BABYLON.Tools.Format(1000.0 / this._sceneInstrumentation!.frameTimeCounter.current, 0) }
|
|
|
- });
|
|
|
- this._createStatLabel("Resolution", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._engine.getRenderWidth() + "x" + this._engine.getRenderHeight() }
|
|
|
- });
|
|
|
- }
|
|
|
+ // Build the stats panel: a div that will contains all stats
|
|
|
+ this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
|
|
|
+ this._panel.classList.add("stats-panel")
|
|
|
|
|
|
- title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
- title.textContent = "Extensions";
|
|
|
- {
|
|
|
- this._createStatLabel("Std derivatives", this._panel);
|
|
|
- let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().standardDerivatives ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Compressed textures", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().s3tc ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Hardware instances", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().instancedArrays ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Texture float", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().textureFloat ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("32bits indices", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().uintIndices ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Fragment depth", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().fragmentDepthSupported ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("High precision shaders", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().highPrecisionShaderSupported ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Draw buffers", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().drawBuffersExtension ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Vertex array object", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().vertexArrayObject ? "Yes" : "No") }
|
|
|
- });
|
|
|
- this._createStatLabel("Timer query", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.getCaps().timerQuery ? "Yes" : "No") }
|
|
|
- });
|
|
|
- }
|
|
|
+ let title = Helpers.CreateDiv('stat-title1', this._panel);
|
|
|
+ let fpsSpan = Helpers.CreateElement('span', 'stats-fps');
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: fpsSpan,
|
|
|
+ updateFct: () => { return Tools.Format(this._inspector.scene.getEngine().getFps(), 0) + " fps" }
|
|
|
+ });
|
|
|
|
|
|
- title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
- title.textContent = "Caps.";
|
|
|
- {
|
|
|
- this._createStatLabel("Stencil", this._panel);
|
|
|
- let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return (this._engine.isStencilEnable ? "Enabled" : "Disabled") }
|
|
|
- });
|
|
|
- this._createStatLabel("Max textures units", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._engine.getCaps().maxTexturesImageUnits.toString() }
|
|
|
- });
|
|
|
- this._createStatLabel("Max textures size", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._engine.getCaps().maxTextureSize.toString() }
|
|
|
- });
|
|
|
- this._createStatLabel("Max anisotropy", this._panel);
|
|
|
- elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return this._engine.getCaps().maxAnisotropy.toString() }
|
|
|
- });
|
|
|
- }
|
|
|
- title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
- title.textContent = "Info";
|
|
|
- {
|
|
|
- let elemValue = Helpers.CreateDiv('stat-infos', this._panel);
|
|
|
- this._updatableProperties.push({
|
|
|
- elem: elemValue,
|
|
|
- updateFct: () => { return "WebGL v" + this._engine.webGLVersion + " - " + this._glInfo.version + " - " + this._glInfo.renderer }
|
|
|
- });
|
|
|
- }
|
|
|
+ let versionSpan = Helpers.CreateElement('span');
|
|
|
+ versionSpan.textContent = `js v${Engine.Version} - `;
|
|
|
+ title.appendChild(versionSpan);
|
|
|
+ title.appendChild(fpsSpan);
|
|
|
+
|
|
|
+ this._updateLoopHandler = this._update.bind(this);
|
|
|
+ this._refreshRateCounter = 0;
|
|
|
+ this.refreshRate = 4;
|
|
|
+
|
|
|
+ // Count block
|
|
|
+ title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
+ title.textContent = "Count";
|
|
|
+ {
|
|
|
+ this._createStatLabel("Total meshes", this._panel);
|
|
|
+ let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.meshes.length.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Draw calls", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._sceneInstrumentation!.drawCallsCounter.current.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Texture collisions", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._sceneInstrumentation!.textureCollisionsCounter.current.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Total lights", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.lights.length.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Total vertices", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.getTotalVertices().toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Total materials", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.materials.length.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Total textures", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.textures.length.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Active meshes", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.getActiveMeshes().length.toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Active indices", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.getActiveIndices().toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Active bones", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.getActiveBones().toString() }
|
|
|
+ });
|
|
|
+
|
|
|
+ this._createStatLabel("Active particles", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._scene.getActiveParticles().toString() }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- private _createStatLabel(content: string, parent: HTMLElement): HTMLElement {
|
|
|
- let elem = Helpers.CreateDiv('stat-label', parent);
|
|
|
- elem.textContent = content;
|
|
|
- return elem;
|
|
|
+ title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
+ title.textContent = "Duration";
|
|
|
+ {
|
|
|
+ this._createStatLabel("Properties refresh rate (per second)", this._panel);
|
|
|
+ let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._inputElement = Inspector.DOCUMENT.createElement('input');
|
|
|
+ this._inputElement.value = this.refreshRate;
|
|
|
+ elemValue.appendChild(this._inputElement);
|
|
|
+ this._inputElement.addEventListener('keyup', (evt: KeyboardEvent) => {
|
|
|
+ this.refreshRate = this._inputElement.value;
|
|
|
+ })
|
|
|
+ this._createStatLabel("Meshes selection", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.activeMeshesEvaluationTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Render targets", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.renderTargetsRenderTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Particles", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.particlesRenderTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Sprites", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.spritesRenderTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Animations", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.animationsTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Physics", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.physicsTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Render", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.renderTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Frame", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.frameTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Inter-frame", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._sceneInstrumentation!.interFrameTimeCounter.current) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("GPU Frame time", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.current * 0.000001) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("GPU Frame time (average)", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.average * 0.000001) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Potential FPS", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return Tools.Format(1000.0 / this._sceneInstrumentation!.frameTimeCounter.current, 0) }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Resolution", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._engine.getRenderWidth() + "x" + this._engine.getRenderHeight() }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- /** Update each properties of the stats panel */
|
|
|
- private _update() {
|
|
|
-
|
|
|
- if(this._refreshRateCounter > 1){
|
|
|
- this._refreshRateCounter--;
|
|
|
- }else{
|
|
|
- for (let prop of this._updatableProperties) {
|
|
|
- prop.elem.textContent = prop.updateFct();
|
|
|
- }
|
|
|
- if(this._inspector.scene.getEngine().getFps()/this.refreshRate == Infinity){
|
|
|
- this._refreshRateCounter = 1;
|
|
|
- }else{
|
|
|
- this._refreshRateCounter = this._inspector.scene.getEngine().getFps()/this.refreshRate;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
+ title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
+ title.textContent = "Extensions";
|
|
|
+ {
|
|
|
+ this._createStatLabel("Std derivatives", this._panel);
|
|
|
+ let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().standardDerivatives ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Compressed textures", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().s3tc ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Hardware instances", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().instancedArrays ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Texture float", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().textureFloat ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("32bits indices", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().uintIndices ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Fragment depth", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().fragmentDepthSupported ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("High precision shaders", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().highPrecisionShaderSupported ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Draw buffers", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().drawBuffersExtension ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Vertex array object", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().vertexArrayObject ? "Yes" : "No") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Timer query", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.getCaps().timerQuery ? "Yes" : "No") }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- public dispose() {
|
|
|
- this._scene.unregisterAfterRender(this._updateLoopHandler);
|
|
|
- this._sceneInstrumentation!.dispose();
|
|
|
- this._sceneInstrumentation = null;
|
|
|
- this._engineInstrumentation!.dispose();
|
|
|
- this._engineInstrumentation = null;
|
|
|
+ title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
+ title.textContent = "Caps.";
|
|
|
+ {
|
|
|
+ this._createStatLabel("Stencil", this._panel);
|
|
|
+ let elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return (this._engine.isStencilEnable ? "Enabled" : "Disabled") }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Max textures units", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._engine.getCaps().maxTexturesImageUnits.toString() }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Max textures size", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._engine.getCaps().maxTextureSize.toString() }
|
|
|
+ });
|
|
|
+ this._createStatLabel("Max anisotropy", this._panel);
|
|
|
+ elemValue = Helpers.CreateDiv('stat-value', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return this._engine.getCaps().maxAnisotropy.toString() }
|
|
|
+ });
|
|
|
}
|
|
|
+ title = Helpers.CreateDiv('stat-title2', this._panel);
|
|
|
+ title.textContent = "Info";
|
|
|
+ {
|
|
|
+ let elemValue = Helpers.CreateDiv('stat-infos', this._panel);
|
|
|
+ this._updatableProperties.push({
|
|
|
+ elem: elemValue,
|
|
|
+ updateFct: () => { return "WebGL v" + this._engine.webGLVersion + " - " + this._glInfo.version + " - " + this._glInfo.renderer }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private _createStatLabel(content: string, parent: HTMLElement): HTMLElement {
|
|
|
+ let elem = Helpers.CreateDiv('stat-label', parent);
|
|
|
+ elem.textContent = content;
|
|
|
+ return elem;
|
|
|
+ }
|
|
|
|
|
|
- public active(b: boolean) {
|
|
|
- super.active(b);
|
|
|
- if (b) {
|
|
|
- this._connectToInstrumentation();
|
|
|
- this._scene.registerAfterRender(this._updateLoopHandler);
|
|
|
+ /** Update each properties of the stats panel */
|
|
|
+ private _update() {
|
|
|
+
|
|
|
+ if (this._refreshRateCounter > 1) {
|
|
|
+ this._refreshRateCounter--;
|
|
|
+ } else {
|
|
|
+ for (let prop of this._updatableProperties) {
|
|
|
+ prop.elem.textContent = prop.updateFct();
|
|
|
+ }
|
|
|
+ if (this._inspector.scene.getEngine().getFps() / this.refreshRate == Infinity) {
|
|
|
+ this._refreshRateCounter = 1;
|
|
|
+ } else {
|
|
|
+ this._refreshRateCounter = this._inspector.scene.getEngine().getFps() / this.refreshRate;
|
|
|
}
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public dispose() {
|
|
|
+ this._scene.unregisterAfterRender(this._updateLoopHandler);
|
|
|
+ this._sceneInstrumentation!.dispose();
|
|
|
+ this._sceneInstrumentation = null;
|
|
|
+ this._engineInstrumentation!.dispose();
|
|
|
+ this._engineInstrumentation = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public active(b: boolean) {
|
|
|
+ super.active(b);
|
|
|
+ if (b) {
|
|
|
+ this._connectToInstrumentation();
|
|
|
+ this._scene.registerAfterRender(this._updateLoopHandler);
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|