From 5fa8e6583d4e41e5a88712ee7a23211ef3feec0f Mon Sep 17 00:00:00 2001 From: -=yb4f310 Date: Sun, 7 Jan 2018 19:51:29 +0100 Subject: [PATCH] renderer update --- src/game-lib-a-1-event.js | 4 +- src/game-lib-a-component-a.js | 9 +- src/game-lib-api-entity-manager.js | 16 - src/game-lib-api-entity.js | 8 - src/game-lib-api-plane.js | 53 +++ src/game-lib-d3-api-renderer.js | 396 ++++++++++++++----- src/game-lib-d3-api-scene.js | 2 +- src/game-lib-d3-api-viewport.js | 4 +- src/game-lib-d3-renderer.js | 594 ++++++++++++++++------------- src/game-lib-d3-scene.js | 7 + src/game-lib-entity-manager.js | 8 +- src/game-lib-entity.js | 5 +- src/game-lib-plane.js | 99 +++++ src/game-lib-system-gui.js | 37 ++ src/game-lib-system-render.js | 135 ++++--- 15 files changed, 932 insertions(+), 445 deletions(-) create mode 100644 src/game-lib-api-plane.js create mode 100644 src/game-lib-plane.js diff --git a/src/game-lib-a-1-event.js b/src/game-lib-a-1-event.js index 65fae05..088713b 100644 --- a/src/game-lib-a-1-event.js +++ b/src/game-lib-a-1-event.js @@ -97,7 +97,7 @@ GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED = 0x4f; GameLib.Event.CAST_SOURCE_CHANGED = 0x50; GameLib.Event.ANIMATION_MESH_ADDED = 0x51; GameLib.Event.ANIMATION_MESH_REMOVED = 0x52; -GameLib.Event.GET_SCENE = 0x53; +// GameLib.Event.GET_SCENE = 0x53; GameLib.Event.CUSTOM_CODE_WINDOW_RESIZE = 0x54; GameLib.Event.LOAD_FONT = 0x55; GameLib.Event.FONT_NOT_FOUND = 0x56; @@ -215,7 +215,7 @@ GameLib.Event.GetEventName = function(number) { case 0x50 : return 'cast_source_changed'; case 0x51 : return 'animation_mesh_added'; case 0x52 : return 'animation_mesh_removed'; - case 0x53 : return 'get_scene'; + case 0x53 : return 'unused';//return 'get_scene'; case 0x54 : return 'custom_code_window_resize'; case 0x55 : return 'load_font'; case 0x56 : return 'font_not_found'; diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 0ad78b2..8d1c690 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -213,7 +213,7 @@ GameLib.Component.SOCKET = 0x6; GameLib.Component.MESH = 0x7; GameLib.Component.SPLINE = 0x8; GameLib.Component.LIGHT = 0x9; -//GameLib.Component.INPUT_DRIVE = 0xa; +GameLib.Component.PLANE = 0xa; GameLib.Component.COMPOSER = 0xb; GameLib.Component.RENDER_TARGET = 0xc; GameLib.Component.PASS = 0xd; @@ -364,7 +364,12 @@ GameLib.Component.GetComponentInfo = function(number) { constructor : GameLib.D3.Light, apiConstructor : GameLib.D3.API.Light }; - case 0xa : return null; + case 0xa : return { + name : 'GameLib.Plane', + runtime : GameLib.Component.GRAPHICS_RUNTIME, + constructor : GameLib.Plane, + apiConstructor : GameLib.API.Plane + }; case 0xb : return { name : 'GameLib.D3.Composer', runtime : GameLib.Component.GRAPHICS_RUNTIME, diff --git a/src/game-lib-api-entity-manager.js b/src/game-lib-api-entity-manager.js index 5ac581a..6bc9b5e 100644 --- a/src/game-lib-api-entity-manager.js +++ b/src/game-lib-api-entity-manager.js @@ -4,16 +4,12 @@ * @param id * @param name * @param entities GameLib.API.Entity[] - * @param defaultEntity - * @param defaultRenderer * @param parentEntity */ GameLib.API.EntityManager = function( id, name, entities, - defaultEntity, - defaultRenderer, parentEntity ) { if (GameLib.Utils.UndefinedOrNull(id)) { @@ -31,16 +27,6 @@ GameLib.API.EntityManager = function( } this.entities = entities; - if (GameLib.Utils.UndefinedOrNull(defaultEntity)) { - defaultEntity = null; - } - this.defaultEntity = defaultEntity; - - if (GameLib.Utils.UndefinedOrNull(defaultRenderer)) { - defaultRenderer = null; - } - this.defaultRenderer = defaultRenderer; - GameLib.API.Component.call( this, GameLib.Component.ENTITY_MANAGER, @@ -68,8 +54,6 @@ GameLib.API.EntityManager.FromObject = function(objectEntityManager) { objectEntityManager.id, objectEntityManager.name, apiEntities, - objectEntityManager.defaultEntity, - objectEntityManager.defaultRenderer, objectEntityManager.parentEntity ); }; diff --git a/src/game-lib-api-entity.js b/src/game-lib-api-entity.js index 8b8b796..c1b8f08 100644 --- a/src/game-lib-api-entity.js +++ b/src/game-lib-api-entity.js @@ -3,7 +3,6 @@ * @param id * @param name * @param components GameLib.Component[] - * @param renderer * @param parentEntity GameLib.Entity * @constructor */ @@ -11,7 +10,6 @@ GameLib.API.Entity = function( id, name, components, - renderer, parentEntity ) { if (GameLib.Utils.UndefinedOrNull(id)) { @@ -29,11 +27,6 @@ GameLib.API.Entity = function( } this.components = components; - if (GameLib.Utils.UndefinedOrNull(renderer)) { - renderer = null; - } - this.renderer = renderer; - GameLib.API.Component.call( this, GameLib.Component.ENTITY, @@ -54,7 +47,6 @@ GameLib.API.Entity.FromObject = function(objectEntity) { objectEntity.id, objectEntity.name, objectEntity.components, - objectEntity.renderer, objectEntity.parentEntity ) }; diff --git a/src/game-lib-api-plane.js b/src/game-lib-api-plane.js new file mode 100644 index 0000000..15de4b8 --- /dev/null +++ b/src/game-lib-api-plane.js @@ -0,0 +1,53 @@ +GameLib.API.Plane = function ( + id, + name, + normal, + constant, + parentEntity +) { + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Plane (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(normal)) { + normal = new GameLib.API.Vector3(1,0,0); + } + this.normal = normal; + + if (GameLib.Utils.UndefinedOrNull(constant)) { + constant = 0; + } + this.constant = constant; + + GameLib.API.Component.call( + this, + GameLib.Component.PLANE, + parentEntity + ); +}; + + +GameLib.API.Plane.prototype = Object.create(GameLib.API.Component.prototype); +GameLib.API.Plane.prototype.constructor = GameLib.API.Plane; + +/** + * Returns an API vector from an Object vector + * @param objectPlane + * @constructor + */ +GameLib.API.Plane.FromObject = function (objectPlane) { + return new GameLib.API.Plane( + objectPlane.id, + objectPlane.name, + GameLib.API.Vector3.FromObject(objectPlane.normal), + objectPlane.constant, + objectPlane.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-renderer.js b/src/game-lib-d3-api-renderer.js index 7bf596d..e071d5b 100644 --- a/src/game-lib-d3-api-renderer.js +++ b/src/game-lib-d3-api-renderer.js @@ -1,45 +1,91 @@ /** - * This component renders a scene - * @param id String - * @param name String - * @param autoClear bool - * @param localClipping + * Renderer Data + * @param id + * @param name * @param width * @param height - * @param domElement + * @param renderMode + * @param autoClear + * @param autoClearColor + * @param autoClearDepth + * @param autoClearStencil + * @param gammaFactor + * @param gammaInput + * @param gammaOutput + * @param maxMorphTargets + * @param maxMorphNormals + * @param physicallyCorrectLights + * @param shadowMapEnabled + * @param shadowMapAutoUpdate + * @param shadowMapNeedsUpdate + * @param shadowMapType + * @param shadowMapRenderReverseSided + * @param shadowMapRenderSingleSided + * @param sortObjects + * @param toneMapping + * @param toneMappingExposure + * @param toneMappingWhitePoint + * @param premultipliedAlpha + * @param antialias + * @param stencil + * @param preserveDrawingBuffer + * @param depth + * @param logarithmicDepthBuffer + * @param fullscreen + * @param canvas + * @param renderTarget + * @param localClippingEnabled + * @param clippingPlanes * @param clearColor * @param camera * @param scenes + * @param defaultScene * @param viewports * @param parentEntity - * @param preserveDrawingBuffer - * @param clippingPlanes - * @param bufferScene - * @param bufferCamera - * @param renderTarget - * @param sortObjects - * @param defaultScene * @constructor */ GameLib.D3.API.Renderer = function ( id, name, - autoClear, - localClipping, width, height, + renderMode, + autoClear, + autoClearColor, + autoClearDepth, + autoClearStencil, + gammaFactor, + gammaInput, + gammaOutput, + maxMorphTargets, + maxMorphNormals, + physicallyCorrectLights, + shadowMapEnabled, + shadowMapAutoUpdate, + shadowMapNeedsUpdate, + shadowMapType, + shadowMapRenderReverseSided, + shadowMapRenderSingleSided, + sortObjects, + toneMapping, + toneMappingExposure, + toneMappingWhitePoint, + premultipliedAlpha, + antialias, + stencil, preserveDrawingBuffer, - domElement, + depth, + logarithmicDepthBuffer, + localClippingEnabled, + fullscreen, + canvas, + renderTarget, + clippingPlanes, clearColor, camera, scenes, - viewports, - clippingPlanes, - bufferScene, - bufferCamera, - renderTarget, defaultScene, - sortObjects, + viewports, parentEntity ) { if (GameLib.Utils.UndefinedOrNull(id)) { @@ -52,89 +98,218 @@ GameLib.D3.API.Renderer = function ( } this.name = name; + if (GameLib.Utils.UndefinedOrNull(width)) { + width = 512; + } + this.width = width; + + if (GameLib.Utils.UndefinedOrNull(height)) { + height = 512; + } + this.height = height; + + if (GameLib.Utils.UndefinedOrNull(renderMode)) { + renderMode = GameLib.D3.API.Renderer.MODE_CANVAS; + } + this.renderMode = renderMode; + if (GameLib.Utils.UndefinedOrNull(autoClear)) { autoClear = true; } this.autoClear = autoClear; - if (GameLib.Utils.UndefinedOrNull(localClipping)) { - localClipping = false; - - if (clippingPlanes && clippingPlanes.length > 0) { - localClipping = true; - } + if (GameLib.Utils.UndefinedOrNull(autoClearColor)) { + autoClearColor = true; } - this.localClipping = localClipping; + this.autoClearColor = autoClearColor; - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 800; + if (GameLib.Utils.UndefinedOrNull(autoClearDepth)) { + autoClearDepth = true; } - this.width = width; + this.autoClearDepth = autoClearDepth; - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 600; + if (GameLib.Utils.UndefinedOrNull(autoClearStencil)) { + autoClearStencil = true; } - this.height = height; + this.autoClearStencil = autoClearStencil; + + if (GameLib.Utils.UndefinedOrNull(gammaFactor)) { + gammaFactor = 2; + } + this.gammaFactor = gammaFactor; + + if (GameLib.Utils.UndefinedOrNull(gammaInput)) { + gammaInput = false; + } + this.gammaInput = gammaInput; + + if (GameLib.Utils.UndefinedOrNull(gammaOutput)) { + gammaOutput = false; + } + this.gammaOutput = gammaOutput; + + if (GameLib.Utils.UndefinedOrNull(maxMorphTargets)) { + maxMorphTargets = 8; + } + this.maxMorphTargets = maxMorphTargets; + + if (GameLib.Utils.UndefinedOrNull(maxMorphNormals)) { + maxMorphNormals = 4; + } + this.maxMorphNormals = maxMorphNormals; + + if (GameLib.Utils.UndefinedOrNull(physicallyCorrectLights)) { + physicallyCorrectLights = false; + } + this.physicallyCorrectLights = physicallyCorrectLights; + + if (GameLib.Utils.UndefinedOrNull(shadowMapEnabled)) { + shadowMapEnabled = false; + } + this.shadowMapEnabled = shadowMapEnabled; + + if (GameLib.Utils.UndefinedOrNull(shadowMapAutoUpdate)) { + shadowMapAutoUpdate = true; + } + this.shadowMapAutoUpdate = shadowMapAutoUpdate; + + if (GameLib.Utils.UndefinedOrNull(shadowMapNeedsUpdate)) { + shadowMapNeedsUpdate = false; + } + this.shadowMapNeedsUpdate = shadowMapNeedsUpdate; + + if (GameLib.Utils.UndefinedOrNull(shadowMapType)) { + shadowMapType = GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_BASIC; + } + this.shadowMapType = shadowMapType; + + if (GameLib.Utils.UndefinedOrNull(shadowMapRenderReverseSided)) { + shadowMapRenderReverseSided = true; + } + this.shadowMapRenderReverseSided = shadowMapRenderReverseSided; + + if (GameLib.Utils.UndefinedOrNull(shadowMapRenderSingleSided)) { + shadowMapRenderSingleSided = true; + } + this.shadowMapRenderSingleSided = shadowMapRenderSingleSided; + + if (GameLib.Utils.UndefinedOrNull(sortObjects)) { + sortObjects = true; + } + this.sortObjects = sortObjects; + + if (GameLib.Utils.UndefinedOrNull(toneMapping)) { + toneMapping = GameLib.D3.API.Renderer.TONE_MAPPING_LINEAR; + } + this.toneMapping = toneMapping; + + if (GameLib.Utils.UndefinedOrNull(toneMappingExposure)) { + toneMappingExposure = 1; + } + this.toneMappingExposure = toneMappingExposure; + + if (GameLib.Utils.UndefinedOrNull(toneMappingWhitePoint)) { + toneMappingWhitePoint = 1; + } + this.toneMappingWhitePoint = toneMappingWhitePoint; + + if (GameLib.Utils.UndefinedOrNull(premultipliedAlpha)) { + premultipliedAlpha = true; + } + this.premultipliedAlpha = premultipliedAlpha; + + if (GameLib.Utils.UndefinedOrNull(antialias)) { + antialias = false; + } + this.antialias = antialias; + + if (GameLib.Utils.UndefinedOrNull(stencil)) { + stencil = true; + } + this.stencil = stencil; if (GameLib.Utils.UndefinedOrNull(preserveDrawingBuffer)) { preserveDrawingBuffer = false; } this.preserveDrawingBuffer = preserveDrawingBuffer; - if (GameLib.Utils.UndefinedOrNull(domElement)) { - domElement = null; + if (GameLib.Utils.UndefinedOrNull(depth)) { + depth = true; } - this.domElement = domElement; + this.depth = depth; - if (GameLib.Utils.UndefinedOrNull(clearColor)) { - clearColor = new GameLib.API.Color(0.11, 0.11, 0.11); + if (GameLib.Utils.UndefinedOrNull(logarithmicDepthBuffer)) { + logarithmicDepthBuffer = false; } - this.clearColor = clearColor; + this.logarithmicDepthBuffer = logarithmicDepthBuffer; - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; - - if (GameLib.Utils.UndefinedOrNull(scenes)) { - scenes = []; - } - this.scenes = scenes; - - if (GameLib.Utils.UndefinedOrNull(viewports)) { - viewports = []; - } - this.viewports = viewports; - - if (GameLib.Utils.UndefinedOrNull(clippingPlanes)) { - clippingPlanes = []; - } - this.clippingPlanes = clippingPlanes; - - if (GameLib.Utils.UndefinedOrNull(bufferScene)) { - bufferScene = null; + if (GameLib.Utils.UndefinedOrNull(localClippingEnabled)) { + localClippingEnabled = false; } - this.bufferScene = bufferScene; + this.localClippingEnabled = localClippingEnabled; - if (GameLib.Utils.UndefinedOrNull(bufferCamera)) { - bufferCamera = camera; + if (GameLib.Utils.UndefinedOrNull(fullscreen)) { + fullscreen = true; } - this.bufferCamera = bufferCamera; + this.fullscreen = fullscreen; + + if (GameLib.Utils.UndefinedOrNull(canvas)) { + canvas = new GameLib.API.Canvas( + null, + null, + this.width, + this.height + ); + } + this.canvas = canvas; if (GameLib.Utils.UndefinedOrNull(renderTarget)) { renderTarget = null; } this.renderTarget = renderTarget; + if (GameLib.Utils.UndefinedOrNull(clippingPlanes)) { + clippingPlanes = []; + } + this.clippingPlanes = clippingPlanes; + + if (GameLib.Utils.UndefinedOrNull(clearColor)) { + clearColor = new GameLib.API.Color(0.11, 0.11, 0.11); + } + this.clearColor = clearColor; + + if (GameLib.Utils.UndefinedOrNull(camera)) { + camera = new GameLib.D3.API.Camera( + null, + GameLib.D3.API.Camera.PERSPECTIVE_CAMERA, + null, + null, + this.width / this.height + ); + } + this.camera = camera; + + if (GameLib.Utils.UndefinedOrNull(scenes)) { + scenes = [new GameLib.D3.API.Scene()]; + } + this.scenes = scenes; + if (GameLib.Utils.UndefinedOrNull(defaultScene)) { - defaultScene = null; + defaultScene = this.scenes[0]; } this.defaultScene = defaultScene; - if (GameLib.Utils.UndefinedOrNull(sortObjects)) { - sortObjects = true; + if (GameLib.Utils.UndefinedOrNull(viewports)) { + viewports = [new GameLib.D3.API.Viewport( + null, + null, + 1, + 1, + 0, + 0 + )]; } - this.sortObjects = sortObjects; + this.viewports = viewports; GameLib.API.Component.call( this, @@ -147,31 +322,68 @@ GameLib.D3.API.Renderer = function ( GameLib.D3.API.Renderer.prototype = Object.create(GameLib.API.Component.prototype); GameLib.D3.API.Renderer.prototype.constructor = GameLib.D3.API.Renderer; +GameLib.D3.API.Renderer.MODE_CANVAS = 0x1; +GameLib.D3.API.Renderer.MODE_TARGET = 0x2; +GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET = 0x3; + +GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_BASIC = 0; +GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_PCF = 1; +GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_PCF_SOFT = 2; + +GameLib.D3.API.Renderer.TONE_MAPPING_LINEAR = 1; +GameLib.D3.API.Renderer.TONE_MAPPING_REINHARD = 2; +GameLib.D3.API.Renderer.TONE_MAPPING_UNCHARTED_2 = 3; +GameLib.D3.API.Renderer.TONE_MAPPING_CINEON = 4; + + /** * Object to GameLib.D3.API.Renderer - * @param objectComponent + * @param objectRenderer * @constructor */ -GameLib.D3.API.Renderer.FromObject = function(objectComponent) { +GameLib.D3.API.Renderer.FromObject = function(objectRenderer) { return new GameLib.D3.API.Renderer( - objectComponent.id, - objectComponent.name, - objectComponent.autoClear, - objectComponent.localClipping, - objectComponent.width, - objectComponent.height, - objectComponent.preserveDrawingBuffer, - objectComponent.domElement, - objectComponent.clearColor, - objectComponent.camera, - objectComponent.scenes, - objectComponent.viewports, - objectComponent.clippingPlanes, - objectComponent.bufferScene, - objectComponent.bufferCamera, - objectComponent.renderTarget, - objectComponent.defaultScene, - objectComponent.sortObjects, - objectComponent.parentEntity + objectRenderer.id, + objectRenderer.name, + objectRenderer.width, + objectRenderer.height, + objectRenderer.renderMode, + objectRenderer.autoClear, + objectRenderer.autoClearColor, + objectRenderer.autoClearDepth, + objectRenderer.autoClearStencil, + objectRenderer.gammaFactor, + objectRenderer.gammaInput, + objectRenderer.gammaOutput, + objectRenderer.maxMorphTargets, + objectRenderer.maxMorphNormals, + objectRenderer.physicallyCorrectLights, + objectRenderer.shadowMapEnabled, + objectRenderer.shadowMapAutoUpdate, + objectRenderer.shadowMapNeedsUpdate, + objectRenderer.shadowMapType, + objectRenderer.shadowMapRenderReverseSided, + objectRenderer.shadowMapRenderSingleSided, + objectRenderer.sortObjects, + objectRenderer.toneMapping, + objectRenderer.toneMappingExposure, + objectRenderer.toneMappingWhitePoint, + objectRenderer.premultipliedAlpha, + objectRenderer.antialias, + objectRenderer.stencil, + objectRenderer.preserveDrawingBuffer, + objectRenderer.depth, + objectRenderer.logarithmicDepthBuffer, + objectRenderer.localClippingEnabled, + objectRenderer.fullscreen, + objectRenderer.canvas, + objectRenderer.renderTarget, + objectRenderer.clippingPlanes, + GameLib.API.Color.FromObject(objectRenderer.clearColor), + objectRenderer.camera, + objectRenderer.scenes, + objectRenderer.defaultScene, + objectRenderer.viewports, + objectRenderer.parentEntity ); }; diff --git a/src/game-lib-d3-api-scene.js b/src/game-lib-d3-api-scene.js index 10699c2..52adc21 100644 --- a/src/game-lib-d3-api-scene.js +++ b/src/game-lib-d3-api-scene.js @@ -49,7 +49,7 @@ GameLib.D3.API.Scene = function( this.meshes = meshes; if (GameLib.Utils.UndefinedOrNull(lights)) { - lights = []; + lights = [new GameLib.D3.API.Light()]; } this.lights = lights; diff --git a/src/game-lib-d3-api-viewport.js b/src/game-lib-d3-api-viewport.js index 4eafec6..8fa479c 100644 --- a/src/game-lib-d3-api-viewport.js +++ b/src/game-lib-d3-api-viewport.js @@ -30,12 +30,12 @@ GameLib.D3.API.Viewport = function( this.name = name; if (GameLib.Utils.UndefinedOrNull(width)) { - width = 800; + width = 1; } this.width = width; if (GameLib.Utils.UndefinedOrNull(height)) { - height = 600; + height = 1; } this.height = height; diff --git a/src/game-lib-d3-renderer.js b/src/game-lib-d3-renderer.js index 26ba10a..37395a8 100644 --- a/src/game-lib-d3-renderer.js +++ b/src/game-lib-d3-renderer.js @@ -20,43 +20,77 @@ GameLib.D3.Renderer = function ( this, apiRenderer.id, apiRenderer.name, - apiRenderer.autoClear, - apiRenderer.localClipping, apiRenderer.width, apiRenderer.height, + apiRenderer.renderMode, + apiRenderer.autoClear, + apiRenderer.autoClearColor, + apiRenderer.autoClearDepth, + apiRenderer.autoClearStencil, + apiRenderer.gammaFactor, + apiRenderer.gammaInput, + apiRenderer.gammaOutput, + apiRenderer.maxMorphTargets, + apiRenderer.maxMorphNormals, + apiRenderer.physicallyCorrectLights, + apiRenderer.shadowMapEnabled, + apiRenderer.shadowMapAutoUpdate, + apiRenderer.shadowMapNeedsUpdate, + apiRenderer.shadowMapType, + apiRenderer.shadowMapRenderReverseSided, + apiRenderer.shadowMapRenderSingleSided, + apiRenderer.sortObjects, + apiRenderer.toneMapping, + apiRenderer.toneMappingExposure, + apiRenderer.toneMappingWhitePoint, + apiRenderer.premultipliedAlpha, + apiRenderer.antialias, + apiRenderer.stencil, apiRenderer.preserveDrawingBuffer, + apiRenderer.depth, + apiRenderer.logarithmicDepthBuffer, + apiRenderer.localClippingEnabled, + apiRenderer.fullscreen, apiRenderer.canvas, + apiRenderer.renderTarget, + apiRenderer.clippingPlanes, apiRenderer.clearColor, apiRenderer.camera, apiRenderer.scenes, - apiRenderer.viewports, - apiRenderer.clippingPlanes, - apiRenderer.bufferScene, - apiRenderer.bufferCamera, - apiRenderer.renderTarget, apiRenderer.defaultScene, - apiRenderer.sortObjects, + apiRenderer.viewports, apiRenderer.parentEntity ); - - this.clearColor = new GameLib.Color( - this.graphics, - this.clearColor, - this - ); - -if (this.canvas) { - this.width = this.canvas.width; - this.height = this.canvas.height; - } - -if (this.canvas instanceof GameLib.API.Canvas) { + if (this.canvas instanceof GameLib.API.Canvas) { this.canvas = new GameLib.Canvas( this.canvas ); } + if (this.renderTarget instanceof GameLib.D3.API.RenderTarget) { + this.renderTarget = new GameLib.D3.RenderTarget( + this.graphics, + this.renderTarget + ) + } + + this.clippingPlanes = this.clippingPlanes.map(function(clippingPlane){ + if (clippingPlane instanceof GameLib.API.Plane) { + return new GameLib.Plane( + this.graphics, + clippingPlane + ); + } else { + return clippingPlane; + } + }.bind(this)); + + this.clearColor = new GameLib.Color( + this.graphics, + this.clearColor, + this + ); if (this.camera instanceof GameLib.D3.API.Camera) { this.camera = new GameLib.D3.Camera( @@ -67,10 +101,17 @@ if (this.canvas instanceof GameLib.API.Canvas) { this.scenes = this.scenes.map(function(scene){ if (scene instanceof GameLib.D3.API.Scene) { - return new GameLib.D3.Scene( + + var runtimeScene = new GameLib.D3.Scene( this.graphics, scene ); + + if (scene === this.defaultScene) { + this.defaultScene = runtimeScene; + } + + return runtimeScene; } else { return scene; } @@ -86,59 +127,17 @@ if (this.canvas instanceof GameLib.API.Canvas) { return viewport; } }.bind(this)); - - this.clippingPlanes = this.clippingPlanes.map(function(clippingPlane){ - if (clippingPlane instanceof GameLib.D3.API.Mesh) { - return new GameLib.D3.Mesh.Plane( - this.graphics, - clippingPlane, - clippingPlane.width, - clippingPlane.height, - clippingPlane.widthSegments, - clippingPlane.heightSegments, - clippingPlane.heightMapScale, - clippingPlane.isHeightMap, - clippingPlane.isClippingPlane, - clippingPlane.distanceFromOrigin - ); - } else { - return clippingPlane; - } - }.bind(this)); - - if (this.bufferScene instanceof GameLib.D3.API.Scene) { - this.bufferScene = new GameLib.D3.Scene( - this.graphics, - this.bufferScene - ) - } - - if (this.bufferCamera instanceof GameLib.D3.API.Camera) { - this.bufferCamera = new GameLib.D3.Camera( - this.graphics, - this.bufferCamera - ) - } - - if (this.renderTarget instanceof GameLib.D3.API.RenderTarget) { - this.renderTarget = new GameLib.D3.RenderTarget( - this.graphics, - this.renderTarget - ) - } - + GameLib.Component.call( this, { 'canvas' : GameLib.Canvas, + 'renderTarget' : GameLib.D3.RenderTarget, + 'clippingPlanes': [GameLib.Plane], 'camera' : GameLib.D3.Camera, 'scenes' : [GameLib.D3.Scene], - 'viewports' : [GameLib.D3.Viewport], - 'clippingPlanes': [GameLib.D3.Mesh.Plane], - 'bufferScene' : GameLib.D3.Scene, - 'bufferCamera' : GameLib.D3.Camera, - 'renderTarget' : GameLib.D3.RenderTarget, - 'defaultScene' : GameLib.D3.Scene + 'defaultScene' : GameLib.D3.Scene, + 'viewports' : [GameLib.D3.Viewport] } ); @@ -163,30 +162,65 @@ GameLib.D3.Renderer.prototype.createInstance = function() { this.instance = new THREE.WebGLRenderer( { - canvas : this.canvas.instance + canvas : this.canvas.instance, + alpha : this.alpha, + premultipliedAlpha : this.premultipliedAlpha, + antialias : this.antialias, + stencil : this.stencil, + preserveDrawingBuffer : this.preserveDrawingBuffer, + depth : this.depth, + logarithmicDepthBuffer : this.logarithmicDepthBuffer } ); - if (this.clippingPlanes.length > 0) { - this.instance.clippingPlanes = this.clippingPlanes.map( - function(clippingPlane) { - - if (!clippingPlane.isClippingPlane || !clippingPlane.instance || !clippingPlane.instance.clipping) { - throw new Error('is not a clipping plane or no clipping plane instance'); - } - - return clippingPlane.instance.clipping; - } - ) - } - - this.instance.localClippingEnabled = this.localClipping; - this.instance.setSize( this.width, this.height ); + this.instance.autoClear = this.autoClear; + this.instance.autoClearColor = this.autoClearColor; + this.instance.autoClearDepth = this.autoClearDepth; + this.instance.autoClearStencil = this.autoClearStencil; + + this.instance.gammaFactor = this.gammaFactor; + this.instance.gammaInput = this.gammaInput; + this.instance.gammaOutput = this.gammaOutput; + + this.instance.maxMorphTargets = this.maxMorphTargets; + this.instance.maxMorphNormals = this.maxMorphNormals; + + this.instance.physicallyCorrectLights = this.physicallyCorrectLights; + + this.instance.shadowMap.enabled = this.shadowMapEnabled; + this.instance.shadowMap.autoUpdate = this.shadowMapAutoUpdate; + this.instance.shadowMap.needsUpdate = this.shadowMapNeedsUpdate; + this.instance.shadowMap.type = this.shadowMapType; + this.instance.shadowMap.renderReverseSided = this.shadowMapRenderReverseSided; + this.instance.shadowMap.renderSingleSided = this.shadowMapRenderSingleSided; + + this.instance.sortObjects = this.sortObjects; + + this.instance.toneMapping = this.toneMapping; + this.instance.toneMappingExposure = this.toneMappingExposure; + this.instance.toneMappingWhitePoint = this.toneMappingWhitePoint; + + this.instance.premultipliedAlpha = this.premultipliedAlpha; + + this.instance.localClippingEnabled = this.localClippingEnabled; + + if (this.renderTarget) { + this.instance.setRenderTarget(this.renderTarget.instance); + } + + if (this.clippingPlanes.length > 0) { + this.instance.clippingPlanes = this.clippingPlanes.map( + function(clippingPlane) { + return clippingPlane.instance; + } + ) + } + this.instance.setClearColor( new THREE.Color( this.clearColor.r, @@ -195,54 +229,188 @@ GameLib.D3.Renderer.prototype.createInstance = function() { ), 1 - this.clearColor.a ); - - this.instance.domElement.width = this.width; - this.instance.domElement.height = this.height; - - this.instance.autoClear = this.autoClear; - this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; - - this.instance.sortObjects = this.sortObjects; - + GameLib.Component.prototype.createInstance.call(this); - }; /** - * + * Update Renderer Instance */ GameLib.D3.Renderer.prototype.updateInstance = function(property) { - if (!this.instance) { - try { - this.createInstance(); - } catch (error) { - console.error(error.message); - } - return; - } - if (!property) { - console.error('no property for renderer'); + throw new Error('no renderer property'); } - if (property === 'localClipping') { - this.instance.localClippingEnabled = this.localClipping; + if (!this.instance) { + throw new Error('no renderer instance'); } - if (property === 'canvas') { - this.instance.dispose(); - this.createInstance(); + if (property === 'width') { + + this.width = Math.round(this.width); + + this.canvas.width = this.width; + + this.canvas.updateInstance('width'); + + this.instance.setSize(this.width, this.height); } - if (property === 'width' || 'height') { + if (property === 'height') { + + this.height = Math.round(this.height); + + this.canvas.height = this.height; + + this.canvas.updateInstance('height'); + + this.instance.setSize(this.width, this.height); + } + + if (property === 'widthheight') { this.width = Math.round(this.width); this.height = Math.round(this.height); - this.setSize(this.width, this.height); + this.canvas.width = this.width; + this.canvas.height = this.height; + + this.canvas.updateInstance('width'); + this.canvas.updateInstance('height'); + + this.instance.setSize(this.width, this.height); } + if (property === 'renderMode') { + console.log('todo: render mode update'); + } + + if (property === 'autoClear') { + this.instance.autoClear = this.autoClear; + } + + if (property === 'autoClearColor') { + this.instance.autoClearColor = this.autoClearColor; + } + + if (property === 'autoClearDepth') { + this.instance.autoClearDepth = this.autoClearDepth; + } + + if (property === 'autoClearStencil') { + this.instance.autoClearStencil = this.autoClearStencil; + } + + if (property === 'gammaFactor') { + this.instance.gammaFactor = this.gammaFactor; + } + + if (property === 'gammaInput') { + this.instance.gammaInput = this.gammaInput; + } + + if (property === 'gammaOutput') { + this.instance.gammaOutput = this.gammaOutput; + } + + if (property === 'maxMorphTargets') { + this.instance.maxMorphTargets = this.maxMorphTargets; + } + + if (property === 'maxMorphNormals') { + this.instance.maxMorphNormals = this.maxMorphNormals; + } + + if (property === 'physicallyCorrectLights') { + this.instance.physicallyCorrectLights = this.physicallyCorrectLights; + } + + if (property === 'shadowMapEnabled') { + this.instance.shadowMap.enabled = this.shadowMapEnabled; + } + + if (property === 'shadowMapAutoUpdate') { + this.instance.shadowMap.autoUpdate = this.shadowMapAutoUpdate; + } + + if (property === 'shadowMapNeedsUpdate') { + this.instance.shadowMap.needsUpdate = this.shadowMapNeedsUpdate; + } + + if (property === 'shadowMapType') { + this.instance.shadowMap.type = this.shadowMapType; + } + + if (property === 'shadowMapRenderReverseSided') { + this.instance.shadowMap.renderReverseSided = this.shadowMapRenderReverseSided; + } + + if (property === 'shadowMapRenderSingleSided') { + this.instance.shadowMap.renderSingleSided = this.shadowMapRenderSingleSided; + } + + if (property === 'sortObjects') { + this.instance.sortObjects = this.sortObjects; + } + + if (property === 'toneMapping') { + this.instance.toneMapping = this.toneMapping; + } + + if (property === 'toneMappingExposure') { + this.instance.toneMappingExposure = this.toneMappingExposure; + } + + if (property === 'toneMappingWhitePoint') { + this.instance.toneMappingWhitePoint = this.toneMappingWhitePoint; + } + + if (property === 'premultipliedAlpha') { + this.instance.premultipliedAlpha = this.premultipliedAlpha; + } + + if (property === 'premultipliedAlpha') { + this.instance.premultipliedAlpha = this.premultipliedAlpha; + } + + if (property === 'antialias') { + this.instance.antialias = this.antialias; + } + + if (property === 'stencil') { + this.instance.stencil = this.stencil; + } + + if (property === 'preserveDrawingBuffer') { + this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; + } + + if (property === 'depth') { + this.instance.depth = this.depth; + } + + if (property === 'logarithmicDepthBuffer') { + this.instance.logarithmicDepthBuffer = this.logarithmicDepthBuffer; + } + + if (property === 'localClippingEnabled') { + this.instance.localClippingEnabled = this.localClippingEnabled; + } + + if (property === 'canvas') { + console.warn('experimental canvas change for renderer'); + this.instance.dispose(); + this.createInstance(); + } + + if (property === 'renderTarget') { + console.warn('todo: render target change'); + } + + if (property === 'clippingPlanes') { + console.warn('todo: clipping planes change'); + } if (property === 'clearColor') { this.instance.setClearColor( @@ -255,32 +423,24 @@ GameLib.D3.Renderer.prototype.updateInstance = function(property) { ); } - - if (property === 'autoClear') { - this.instance.autoClear = this.autoClear; + if (property === 'camera') { + console.warn('todo: camera change'); } - if (property === 'preserveDrawingBuffer') { - this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; + if (property === 'scenes') { + console.warn('todo: scenes change'); } - if (this.clippingPlanes.length > 0) { - this.instance.clippingPlanes = this.clippingPlanes.map( - function(clippingPlane) { - - if (!clippingPlane.isClippingPlane || !clippingPlane.instance || !clippingPlane.instance.clipping) { - throw new Error('is not a clipping plane or no clipping plane instance'); - } - - return clippingPlane.instance.clipping; - } - ) - } else { - this.instance.clippingPlanes = []; + if (property === 'defaultScene') { + console.warn('todo: defaultScene change'); } - if (property === 'sortObjects') { - this.instance.sortObjects = this.sortObjects; + if (property === 'viewports') { + console.warn('todo: viewports change'); + } + + if (property === 'parentEntity') { + console.warn('todo: parentEntity change'); } }; @@ -293,30 +453,56 @@ GameLib.D3.Renderer.prototype.toApiObject = function() { var apiRenderer = new GameLib.D3.API.Renderer( this.id, this.name, - this.autoClear, - this.localClipping, this.width, this.height, + this.renderMode, + this.autoClear, + this.autoClearColor, + this.autoClearDepth, + this.autoClearStencil, + this.gammaFactor, + this.gammaInput, + this.gammaOutput, + this.maxMorphTargets, + this.maxMorphNormals, + this.physicallyCorrectLights, + this.shadowMapEnabled, + this.shadowMapAutoUpdate, + this.shadowMapNeedsUpdate, + this.shadowMapType, + this.shadowMapRenderReverseSided, + this.shadowMapRenderSingleSided, + this.sortObjects, + this.toneMapping, + this.toneMappingExposure, + this.toneMappingWhitePoint, + this.premultipliedAlpha, + this.antialias, + this.stencil, this.preserveDrawingBuffer, + this.depth, + this.logarithmicDepthBuffer, + this.localClippingEnabled, GameLib.Utils.IdOrNull(this.canvas), - this.clearColor.toApiObject(), - GameLib.Utils.IdOrNull(this.camera), - this.scenes.map(function(scene){ - return GameLib.Utils.IdOrNull(scene); - }), - this.viewports.map(function(viewport){ - return GameLib.Utils.IdOrNull(viewport); - }), + GameLib.Utils.IdOrNull(this.renderTarget), this.clippingPlanes.map( - function(clippingPlane) { + function(clippingPlane){ return GameLib.Utils.IdOrNull(clippingPlane); } ), - GameLib.Utils.IdOrNull(this.bufferScene), - GameLib.Utils.IdOrNull(this.bufferCamera), - GameLib.Utils.IdOrNull(this.renderTarget), + this.clearColor.toApiObject(), + GameLib.Utils.IdOrNull(this.camera), + this.scenes.map( + function(scene){ + return GameLib.Utils.IdOrNull(scene); + } + ), GameLib.Utils.IdOrNull(this.defaultScene), - this.sortObjects, + this.viewports.map( + function(viewport){ + return GameLib.Utils.IdOrNull(viewport); + } + ), GameLib.Utils.IdOrNull(this.parentEntity) ); @@ -340,115 +526,3 @@ GameLib.D3.Renderer.FromObject = function(graphics, objectComponent) { ); }; -/** - * Convenience render function - */ -GameLib.D3.Renderer.prototype.render = function(delta, scenes) { - - if (!this.instance) { - return; - } - - if (GameLib.Utils.UndefinedOrNull(scenes)) { - scenes = this.scenes; - } - - if (this.viewports.length > 1) { - this.instance.autoClear = false; - } - - if (scenes.length > 1) { - this.instance.autoClear = false; - } - - this.instance.clear(); - - if ( - this.bufferScene && - this.bufferScene.instance && - this.bufferCamera && - this.bufferCamera.instance && - this.renderTarget && - this.renderTarget.instance - ) { - /** - * We have a buffer that should render to an offscreen render target - */ - this.instance.render( - this.bufferScene.instance, - this.bufferCamera.instance, - this.renderTarget.instance - ); - } - - this.viewports.map( - - function(viewport) { - - this.instance.setViewport( - viewport.x * this.width, - viewport.y * this.height, - viewport.width * this.width, - viewport.height * this.height - ); - - scenes.map(function(scene) { - - if (!scene.instance) { - return; - } - - if (!this.camera.instance && !(scene.renderCamera || scene.renderCamera.instance)) { - return; - } - - - if (scene.renderCamera && scene.renderCamera.instance) { - - /** - * A scene's renderCamera instance overrides the default renderer camera - */ - this.instance.render( - scene.instance, - scene.renderCamera.instance - ) - - } else { - - /** - * Ok just do a normal render - */ - this.instance.render( - scene.instance, - this.camera.instance - ) - } - - }.bind(this)); - - }.bind(this) - ); - -}; - -GameLib.D3.Renderer.prototype.setSize = function(width, height) { - - this.width = Math.round(width); - this.height = Math.round(height); - - this.canvas.width = this.width; - this.canvas.height = this.height; - - this.canvas.updateInstance('width'); - - if (this.instance) { - this.instance.setSize( - this.width, - this.height - ); - } else { - console.log('renderer not ready to set size'); - } - -}; - diff --git a/src/game-lib-d3-scene.js b/src/game-lib-d3-scene.js index d4ba8b9..c797e34 100644 --- a/src/game-lib-d3-scene.js +++ b/src/game-lib-d3-scene.js @@ -464,6 +464,10 @@ GameLib.D3.Scene.prototype.addObject = function(object) { } } + if (this.parentEntity) { + this.parentEntity.addComponent(object); + } + }; GameLib.D3.Scene.prototype.addClone = function(component) { @@ -528,6 +532,9 @@ GameLib.D3.Scene.prototype.removeObject = function(object) { object.parentScene = null; } + if (this.parentEntity) { + this.parentEntity.removeComponent(object); + } // this.buildIdToObject(); }; diff --git a/src/game-lib-entity-manager.js b/src/game-lib-entity-manager.js index fccda09..fc4cf07 100644 --- a/src/game-lib-entity-manager.js +++ b/src/game-lib-entity-manager.js @@ -13,8 +13,6 @@ GameLib.EntityManager = function(apiEntityManager) { apiEntityManager.id, apiEntityManager.name, apiEntityManager.entities, - apiEntityManager.defaultEntity, - apiEntityManager.defaultRenderer, apiEntityManager.parentEntity ); @@ -45,9 +43,7 @@ GameLib.EntityManager = function(apiEntityManager) { GameLib.Component.call( this, { - 'entities' : [GameLib.Entity], - 'defaultEntity' : GameLib.Entity, - 'defaultRenderer' : GameLib.D3.Renderer + 'entities' : [GameLib.Entity] } ); }; @@ -384,8 +380,6 @@ GameLib.EntityManager.prototype.toApiObject = function() { this.id, this.name, apiEntities, - GameLib.Utils.IdOrNull(this.defaultEntity), - GameLib.Utils.IdOrNull(this.defaultRenderer), GameLib.Utils.IdOrNull(this.parentEntity) ); diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index b04d451..42cd877 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -15,15 +15,13 @@ GameLib.Entity = function ( apiEntity.id, apiEntity.name, apiEntity.components, - apiEntity.renderer, apiEntity.parentEntity ); GameLib.Component.call( this, { - 'components' : [GameLib.Component], - 'renderer' : GameLib.D3.Renderer + 'components' : [GameLib.Component] } ); }; @@ -191,7 +189,6 @@ GameLib.Entity.prototype.toApiObject = function() { this.id, this.name, apiComponents, - GameLib.Utils.IdOrNull(this.renderer), GameLib.Utils.IdOrNull(this.parentEntity) ); diff --git a/src/game-lib-plane.js b/src/game-lib-plane.js new file mode 100644 index 0000000..145e24b --- /dev/null +++ b/src/game-lib-plane.js @@ -0,0 +1,99 @@ +/** + * Creates a Plane object + * @param graphics GameLib.GraphicsRuntime + * @param apiPlane GameLib.API.Plane + * @constructor + */ +GameLib.Plane = function( + graphics, + apiPlane +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiPlane)) { + apiPlane = {}; + } + + GameLib.API.Plane.call( + this, + apiPlane.id, + apiPlane.name, + apiPlane.normal, + apiPlane.constant, + apiPlane.parentEntity + ); + + this.normal = new GameLib.Vector3( + this.graphics, + this.normal, + this + ); + + GameLib.Component.call(this); +}; + +GameLib.Plane.prototype = Object.create(GameLib.Component.prototype); +GameLib.Plane.prototype.constructor = GameLib.Plane; + +GameLib.Plane.prototype.createInstance = function() { + + this.instance = new THREE.Plane( + this.normal.instance, + this.constant + ); + + GameLib.Component.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +GameLib.Plane.prototype.updateInstance = function(property) { + + if (property === 'normal') { + + this.normal.normalize(); + + this.instance.normal.x = this.normal.x; + this.instance.normal.y = this.normal.y; + this.instance.normal.z = this.normal.z; + } + + if (property === 'constant') { + this.instance.constant = this.constant; + } + +}; + +/** + * Converts a GameLib.Plane to a new GameLib.API.Plane + * @returns {GameLib.API.Plane} + */ +GameLib.Plane.prototype.toApiObject = function() { + + return new GameLib.API.Plane( + this.id, + this.name, + this.normal.toApiObject(), + this.constant, + GameLib.Utils.IdOrNull(this.parentEntity) + ); + +}; + +/** + * Converts from an Object Plane to a GameLib.Plane + * @param graphics GameLib.GraphicsRuntime + * @param objectPlane Object + * @returns {GameLib.Plane} + * @constructor + */ +GameLib.Plane.FromObject = function(graphics, objectPlane) { + var apiPlane = GameLib.API.Plane.FromObject(objectPlane); + return new GameLib.Plane( + graphics, + apiPlane + ); +}; diff --git a/src/game-lib-system-gui.js b/src/game-lib-system-gui.js index ce90174..976ff7d 100644 --- a/src/game-lib-system-gui.js +++ b/src/game-lib-system-gui.js @@ -872,6 +872,43 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, } ) ); + } else if (property === 'renderMode') { + controllers.push( + folder.add( + object, + property, + { + 'canvas': GameLib.D3.API.Renderer.MODE_CANVAS, + 'target': GameLib.D3.API.Renderer.MODE_TARGET, + 'canvas and target': GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET + } + ) + ); + } else if (property === 'shadowMapType') { + controllers.push( + folder.add( + object, + property, + { + 'basic': GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_BASIC, + 'pcf': GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_PCF, + 'pcf soft': GameLib.D3.API.Renderer.SHADOW_MAP_TYPE_PCF_SOFT + } + ) + ); + } else if (property === 'toneMapping') { + controllers.push( + folder.add( + object, + property, + { + 'linear': GameLib.D3.API.Renderer.TONE_MAPPING_LINEAR, + 'reinhard': GameLib.D3.API.Renderer.TONE_MAPPING_REINHARD, + 'uncharted 2': GameLib.D3.API.Renderer.TONE_MAPPING_UNCHARTED_2, + 'cineon': GameLib.D3.API.Renderer.TONE_MAPPING_CINEON + } + ) + ); } else if (property === 'opacityType') { controllers.push( folder.add( diff --git a/src/game-lib-system-render.js b/src/game-lib-system-render.js index 8dcb13a..9a3d6cd 100644 --- a/src/game-lib-system-render.js +++ b/src/game-lib-system-render.js @@ -115,14 +115,14 @@ GameLib.System.Render.prototype.windowResize = function(data) { renderers.map( function(renderer) { - renderer.setSize( - renderer.canvas.width, - renderer.canvas.height - ); - - renderer.camera.aspect = renderer.canvas.width / renderer.canvas.height; - - renderer.camera.updateInstance('aspect'); + if (renderer.fullscreen) { + renderer.width = data.width; + renderer.height = data.height; + /** + * widthheight simply saves a function call + */ + renderer.updateInstance('widthheight'); + } } ); @@ -145,13 +145,6 @@ GameLib.System.Render.prototype.instanceCreated = function(data) { if (data.component instanceof GameLib.D3.Renderer) { this.renderers.push(data.component); - GameLib.Event.Emit( - GameLib.Event.WINDOW_RESIZE, - { - width : window.innerWidth, - height : window.innerHeight - } - ); } if (data.component instanceof GameLib.Stats) { @@ -215,47 +208,87 @@ GameLib.System.Render.prototype.render = function(data) { data ); - if (this.renderers.length < 1) { - /** - * Do nothing - */ - } else if (this.renderers.length === 1) { - /** - * Quite simple - we have a renderer - it wants to render its stuff - */ - this.renderers[0].render(data.delta); + this.renderers.map( - } else { + function(renderer){ - /** - * If we have multiple renderers, we have a problem - they don't share the same webGL context - - * So, we need to get their scenes and render them individually instead of trying to have both renderers render - * to the same canvas (sharing the same webgl context does not work) - */ - var scenes = this.renderers.reduce( - function(result, renderer) { - renderer.scenes.map( - function(scene){ - result.push(scene); - } - ); - return result; - }, - [] - ); + if (renderer.viewports.length > 1) { + renderer.instance.autoClear = false; + } - var renderer = GameLib.EntityManager.Instance.defaultRenderer; + if (renderer.scenes.length > 1) { + renderer.instance.autoClear = false; + } - if (GameLib.Utils.UndefinedOrNull(renderer)) { - /** - * No default renderer, using first one - */ - renderer = this.renderers[0]; + renderer.instance.clear(); + + renderer.viewports.map( + + function(viewport) { + + var trueWidth = viewport.width * renderer.width; + var trueHeight = viewport.height * renderer.height; + + renderer.instance.setViewport( + viewport.x * renderer.width, + viewport.y * renderer.height, + viewport.width * renderer.width, + viewport.height * renderer.height + ); + + var aspect = trueWidth / trueHeight; + + renderer.scenes.map( + function (scene) { + + var camera = renderer.camera; + + /** + * A scene's renderCamera overrides the renderer camera + */ + if (scene.renderCamera && scene.renderCamera.instance) { + camera = scene.renderCamera; + } + + /** + * Ensure the camera aspect ratio + */ + if (camera.aspect !== aspect) { + camera.aspect = aspect; + camera.updateInstance('aspect'); + } + + if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_TARGET) { + renderer.instance.render( + scene.instance, + camera.instance, + renderer.target.instance + ) + } else if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS) { + renderer.instance.render( + scene.instance, + camera.instance + ) + } else if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET) { + renderer.instance.render( + scene.instance, + camera.instance, + renderer.target.instance + ); + + renderer.instance.render( + scene.instance, + camera.instance + ); + } else { + console.warn('unknown render mode:' + renderer.renderMode); + } + } + ); + } + ) } - - renderer.render(data.delta, scenes); - - } + ); GameLib.Event.Emit( GameLib.Event.AFTER_RENDER,