David Catuhe 5 vuotta sitten
vanhempi
commit
c47293170a

+ 14 - 1
.vscode/launch.json

@@ -1,6 +1,6 @@
 {
     "version": "2.0.0",
-    "configurations": [
+    "configurations": [    
         {
             "name": "Launch Node Material Editor (Chrome)",
             "type": "chrome",
@@ -145,6 +145,19 @@
             ]
         },
         {
+            "name": "Launch Local Dev - Views mode (Chrome)",
+            "type": "chrome",
+            "request": "launch",
+            "url": "http://localhost:1338/localDev/index-views.html",
+            "webRoot": "${workspaceRoot}/",
+            "sourceMaps": true,
+            "preLaunchTask": "run",
+            "userDataDir": "${workspaceRoot}/.tempChromeProfileForDebug",
+            "runtimeArgs": [
+                "--enable-unsafe-es3-apis"
+            ]
+        },        
+        {
             "name": "Launch Local Dev (Experimental Firefox)",
             "type": "firefox",
             "request": "launch",

+ 183 - 0
localDev/index-views.html

@@ -0,0 +1,183 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+    <title>Local Development</title>
+
+    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
+    <script src="../dist/preview%20release/cannon.js"></script>
+    <script src="../dist/preview%20release/Oimo.js"></script>
+    <script src="../dist/preview%20release/ammo.js"></script>
+    <script src="../dist/preview%20release/recast.js"></script>
+    <script src="../dist/preview%20release/gltf_validator.js"></script>
+    <script src="../Tools/DevLoader/BabylonLoader.js"></script>
+
+    <style>
+        html,
+        body {
+            width: 100%;
+            height: 100%;
+            padding: 0;
+            margin: 0;
+            overflow: hidden;
+        }
+
+        .container {
+            width: 100%;
+            height: 100%;
+            display: grid;
+            grid-template-rows: 50% 50%;
+            grid-template-columns: 50% 50%;
+            font-size: 0;
+        }
+
+        .renderCanvas {            
+            width: 100%;
+            height: 100%;
+        }
+
+        #renderCanvas0 {
+            grid-row: 1;
+            grid-column: 1;
+        }
+
+        #renderCanvas1 {
+            grid-row: 1;
+            grid-column: 2;
+        }
+
+        #renderCanvas2 {
+            grid-row: 2;
+            grid-column: 1;
+        }
+
+        #renderCanvas3 {
+            grid-row: 2;
+            grid-column: 2;
+        }
+
+        #fps {
+            position: absolute;
+            background-color: black;
+            border: 2px solid red;
+            text-align: center;
+            font-size: 16px;
+            color: white;
+            top: 15px;
+            right: 10px;
+            width: 60px;
+            height: 20px;
+        }
+
+        @font-face {
+            font-family: BabylonJSglyphs;
+            /* src: url("http://www.killer-squid.com/fonts/BabylonJSglyphs.otf"); */
+            src: local("BabylonJSglyphs");
+        }
+    </style>
+</head>
+
+<body>
+    <div id="fps">0</div>
+    <div class="container">
+        <canvas class="renderCanvas" id="renderCanvas0" touch-action="none"></canvas>
+        <canvas class="renderCanvas" id="renderCanvas1" touch-action="none"></canvas>
+        <canvas class="renderCanvas" id="renderCanvas2" touch-action="none"></canvas>
+        <canvas class="renderCanvas" id="renderCanvas3" touch-action="none"></canvas>
+    </div>
+
+    <script>
+        var canvas = document.getElementById("renderCanvas0");
+        //	canvas = WebGLDebugUtils.makeLostContextSimulatingCanvas(canvas);
+        var divFps = document.getElementById("fps");
+
+        // Global to simulate PG.
+        var engine = null;
+
+        // Allow querystring to navigate easily in debug in local samples.
+        var indexjs = 'src/index';
+        var sampleSearch = /sample=([0-9]+)/i;
+        var matches = null;
+        if ((matches = sampleSearch.exec(window.location)) !== null) {
+            indexjs += '.';
+            indexjs += matches[1];
+        }
+        indexjs += '.js';
+
+        // var indexjs = "http://localhost:1234/index.js"
+
+        // Load the scripts + map file to allow vscode debug.
+        BABYLONDEVTOOLS.Loader
+            .require(indexjs)
+            .load(function() {
+                BABYLON.DracoCompression.Configuration.decoder = {
+                    wasmUrl: "../dist/preview%20release/draco_wasm_wrapper_gltf.js",
+                    wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
+                    fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
+                };
+
+                if (BABYLON.Engine.isSupported()) {
+                    if (typeof createEngine !== "undefined") {
+                        engine = createEngine();
+                    } else {
+                        engine = new BABYLON.Engine(canvas, true, { premultipliedAlpha: false, stencil: true, disableWebGL2Support: false, preserveDrawingBuffer: true });
+                    }
+
+                    BABYLONDEVTOOLS.Loader.debugShortcut(engine);
+
+                    // call the scene creation from the js.
+                    if (typeof delayCreateScene !== "undefined") {
+                        var scene = delayCreateScene();
+
+                        if (scene) {
+                            // Register a render loop to repeatedly render the scene
+
+                            engine.runRenderLoop(function() {
+                                if (scene.activeCamera) {
+                                    scene.render();
+                                }
+                                divFps.innerHTML = engine.getFps().toFixed() + " fps";
+                            });
+                        }
+                    }
+                    else {
+                        var scene = createScene();
+
+                        if (scene) {
+
+                            var processCurrentScene = function(scene) {
+                                engine.runRenderLoop(function() {
+                                    scene.render();
+                                    divFps.innerHTML = engine.getFps().toFixed() + " fps";
+                                });
+                            }
+
+                            if (scene.then) {
+                                // Handle if createScene returns a promise
+                                scene.then(function(currentScene) {
+                                    processCurrentScene(currentScene);
+                                }).catch(function(e) {
+                                    console.error(e);
+                                    onError();
+                                });
+                            } else {
+                                // Register a render loop to repeatedly render the scene
+                                processCurrentScene(scene);
+                            }
+                        }
+                    }
+
+                    // Resize
+                    window.addEventListener("resize", function() {
+                        engine.resize();
+                    });
+                }
+                else {
+                    alert('BabylonJS is not supported.')
+                }
+            });
+    </script>
+</body>
+
+</html>

+ 108 - 0
src/Engines/Extensions/engine.views.ts

@@ -0,0 +1,108 @@
+import { Engine } from "../engine";
+import { Camera } from '../../Cameras/camera';
+
+declare module "../../Engines/engine" {
+    export interface Engine {
+
+        /** Gets or sets the list of views */
+        views: {
+            target: HTMLCanvasElement,
+            camera: Camera
+        }[];
+
+        /**
+         * Register a new child canvas
+         * @param canvas defines the canvas to register
+         * @param camera defines the camera to use with this canvas (it will overwrite the scene.camera for this view)
+         * @returns the current engine
+         */
+        registerView(canvas: HTMLCanvasElement, camera: Camera): Engine;
+
+        /**
+         * Remove a registered child canvas
+         * @param canvas defines the canvas to remove
+         * @returns the current engine
+         */
+        unRegisterView(canvas: HTMLCanvasElement): Engine;        
+    }
+}
+
+Engine.prototype.registerView = function(canvas: HTMLCanvasElement, camera: Camera): Engine {
+    if (!this.views) {
+        this.views = [];
+    }
+
+    for (var view of this.views) {
+        if (view.target === canvas) {
+            return this;
+        }
+    }
+
+    this.views.push({target: canvas, camera: camera});
+
+    camera.onDisposeObservable.add(() => {
+        this.unRegisterView(canvas);
+    })
+
+    return this;    
+};
+
+Engine.prototype.unRegisterView = function(canvas: HTMLCanvasElement): Engine {
+    if (!this.views) {
+        return this;
+    }
+
+    for (var view of this.views) {
+        if (view.target = canvas) {
+            let index = this.views.indexOf(view);
+
+            if (index !== -1) {
+                this.views.splice(index, 1);
+            }
+            break;
+        }
+    }
+
+    return this;    
+};
+
+Engine.prototype._renderViews = function() {
+    if (!this.views) {
+        return;
+    }
+
+    let parent = this.getRenderingCanvas();
+
+    if (!parent) {
+        return;
+    }
+
+    for (var view of this.views) {
+        let canvas = view.target;
+        let context = canvas.getContext("2d");
+        if (!context) {
+            continue;
+        }
+        let camera = view.camera;
+        let scene = camera.getScene();
+
+        if (scene.activeCameras.length) {
+            continue;
+        }
+
+        let previewCamera = scene.activeCamera;
+        scene.activeCamera = camera;
+
+        // Render the frame
+        this._renderFrame();
+
+        // Copy to target
+        canvas.width = canvas.clientWidth;
+        canvas.height = canvas.clientHeight;
+
+        context.drawImage(parent, 0, 0, parent.clientWidth, parent.clientHeight, 0, 0, canvas.clientWidth, canvas.clientHeight);
+
+        // Restore
+        scene.activeCamera = previewCamera;
+    }
+}

+ 2 - 2
src/Engines/Extensions/engine.webVR.ts

@@ -152,7 +152,7 @@ Engine.prototype.initWebVRAsync = function(): Promise<IDisplayChangedEventArgs>
         this._onVrDisplayDisconnect = () => {
             this._vrDisplay.cancelAnimationFrame(this._frameHandler);
             this._vrDisplay = undefined;
-            this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction);
+            this._frameHandler = Engine.QueueNewFrame(this._boundRenderFunction);
             notifyObservers();
         };
         this._onVrDisplayPresentChange = () => {
@@ -299,5 +299,5 @@ Engine.prototype.isVRPresenting = function() {
 };
 
 Engine.prototype._requestVRFrame = function() {
-    this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction, this._vrDisplay);
+    this._frameHandler = Engine.QueueNewFrame(this._boundRenderFunction, this._vrDisplay);
 };

+ 2 - 1
src/Engines/Extensions/index.ts

@@ -9,4 +9,5 @@ export * from "./engine.cubeTexture";
 export * from "./engine.renderTarget";
 export * from "./engine.renderTargetCube";
 export * from "./engine.webVR";
-export * from "./engine.uniformBuffer";
+export * from "./engine.uniformBuffer";
+export * from "./engine.views";

+ 25 - 12
src/Engines/engine.ts

@@ -1359,6 +1359,20 @@ export class Engine extends ThinEngine {
         super._rebuildBuffers();
     }
 
+    public _renderFrame() {
+        // Start new frame
+        this.beginFrame();
+
+        for (var index = 0; index < this._activeRenderLoops.length; index++) {
+            var renderFunction = this._activeRenderLoops[index];
+
+            renderFunction();
+        }
+
+        // Present
+        this.endFrame();  
+    }
+
     public _renderLoop(): void {
         if (!this._contextWasLost) {
             var shouldRender = true;
@@ -1367,35 +1381,34 @@ export class Engine extends ThinEngine {
             }
 
             if (shouldRender) {
-                // Start new frame
-                this.beginFrame();
+                // Child canvases
+                this._renderViews();      
 
-                for (var index = 0; index < this._activeRenderLoops.length; index++) {
-                    var renderFunction = this._activeRenderLoops[index];
-
-                    renderFunction();
-                }
-
-                // Present
-                this.endFrame();
+                // Main frame
+                this._renderFrame();
             }
         }
 
         if (this._activeRenderLoops.length > 0) {
             // Register new frame
             if (this.customAnimationFrameRequester) {
-                this.customAnimationFrameRequester.requestID = this._queueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
+                this.customAnimationFrameRequester.requestID = this._queueNewFrame(this.customAnimationFrameRequester.renderFunction || this._boundRenderFunction, this.customAnimationFrameRequester);
                 this._frameHandler = this.customAnimationFrameRequester.requestID;
             } else if (this.isVRPresenting()) {
                 this._requestVRFrame();
             } else {
-                this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
+                this._frameHandler = this._queueNewFrame(this._boundRenderFunction, this.getHostWindow());
             }
         } else {
             this._renderingQueueLaunched = false;
         }
     }
 
+    /** @hidden */
+    public _renderViews() {
+        // Do nothing
+    }
+
     /**
      * Toggle full screen mode
      * @param requestPointerLock defines if a pointer lock should be requested from the user

+ 5 - 5
src/Engines/thinEngine.ts

@@ -345,7 +345,7 @@ export class ThinEngine {
     public _workingContext: Nullable<CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D>;
 
     /** @hidden */
-    public _bindedRenderFunction: any;
+    public _boundRenderFunction: any;
 
     private _vaoRecordInProgress = false;
     private _mustWipeVertexAttributes = false;
@@ -1024,7 +1024,7 @@ export class ThinEngine {
         }
 
         if (this._activeRenderLoops.length > 0) {
-           this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
+           this._frameHandler = this._queueNewFrame(this._boundRenderFunction, this.getHostWindow());
         } else {
             this._renderingQueueLaunched = false;
         }
@@ -1101,8 +1101,8 @@ export class ThinEngine {
 
         if (!this._renderingQueueLaunched) {
             this._renderingQueueLaunched = true;
-            this._bindedRenderFunction = this._renderLoop.bind(this);
-            this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
+            this._boundRenderFunction = this._renderLoop.bind(this);
+            this._frameHandler = this._queueNewFrame(this._boundRenderFunction, this.getHostWindow());
         }
     }
 
@@ -3544,7 +3544,7 @@ export class ThinEngine {
         this._currentBufferPointers = [];
         this._renderingCanvas = null;
         this._currentProgram = null;
-        this._bindedRenderFunction = null;
+        this._boundRenderFunction = null;
 
         Effect.ResetCache();