diff --git a/src/game-lib-a-1-event.js b/src/game-lib-a-1-event.js index 70bcd07..e13dfac 100644 --- a/src/game-lib-a-1-event.js +++ b/src/game-lib-a-1-event.js @@ -34,7 +34,7 @@ GameLib.Event.TEXTURE_ANIMATED_CHANGE = 0x10; GameLib.Event.ANIMATE_TEXTURE_INSTANCE = 0x11; GameLib.Event.REMOVE_PARTICLE_ENGINE = 0x12; GameLib.Event.GAME_PAUSE = 0x13; -//GameLib.Event.TEXTURE_INSTANCE_UPDATED = 0x14; +GameLib.Event.SHADER_UPDATE = 0x14; GameLib.Event.PLAY_AUDIO = 0x15; GameLib.Event.MATERIAL_INSTANCE_UPDATED = 0x16; GameLib.Event.PAUSE_AUDIO = 0x17; @@ -161,7 +161,7 @@ GameLib.Event.GetEventName = function(number) { case 0x11 : return 'animate_texture_instance'; case 0x12 : return 'remove_particle_engine'; case 0x13 : return 'pause'; - case 0x14 : return 'texture_instance_updated'; + case 0x14 : return 'shader_update'; case 0x15 : return 'play_audio'; case 0x16 : return 'material_instance_updated'; case 0x17 : return 'pause_audio'; diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 76e6924..8980905 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -206,7 +206,7 @@ GameLib.Component.prototype.updateInstance = function(property) { if (property === 'parentEntity') { - if (this.parentEntity && this.parentEntity.loaded) { + if (this.parentEntity instanceof GameLib.Entity) { this.parentEntity.addComponent(this); this.buildIdToObject(); diff --git a/src/game-lib-api-image.js b/src/game-lib-api-image.js index 6568e2d..2833113 100644 --- a/src/game-lib-api-image.js +++ b/src/game-lib-api-image.js @@ -9,6 +9,8 @@ * @param path * @param contentType * @param size + * @param width + * @param height * @constructor */ GameLib.API.Image = function( diff --git a/src/game-lib-custom-code.js b/src/game-lib-custom-code.js index 2668193..3a1dd54 100644 --- a/src/game-lib-custom-code.js +++ b/src/game-lib-custom-code.js @@ -101,19 +101,47 @@ GameLib.CustomCode.prototype.launchEditor = function(){ }.bind(this) ); - this.editor = this.coder.instance( - document.body, - { - value : this.code, - mode : 'javascript', - lineNumbers : true, - scrollbarStyle : 'overlay', - indentWithTabs: true, - indentUnit : 4 - } - ); + if (this instanceof GameLib.D3.Shader.Vertex) { + this.editor = this.coder.instance( + document.body, + { + value: this.code, + mode: 'x-shader/x-vertex', + lineNumbers: true, + scrollbarStyle: 'overlay', + indentWithTabs: true, + indentUnit: 4 + } + ); + } else if (this instanceof GameLib.D3.Shader.Fragment) { + this.editor = this.coder.instance( + document.body, + { + value: this.code, + mode: 'x-shader/x-fragment', + lineNumbers: true, + scrollbarStyle: 'overlay', + indentWithTabs: true, + indentUnit: 4 + } + ); + } else { + this.editor = this.coder.instance( + document.body, + { + value: this.code, + mode: 'javascript', + lineNumbers: true, + scrollbarStyle: 'overlay', + indentWithTabs: true, + indentUnit: 4 + } + ); + } - this.editor.on('change', function(){ + + + this.editor.on('change', function(){ this.code = this.editor.getValue(); diff --git a/src/game-lib-d3-api-fog.js b/src/game-lib-d3-api-fog.js index 9991461..e4b5f1f 100644 --- a/src/game-lib-d3-api-fog.js +++ b/src/game-lib-d3-api-fog.js @@ -65,23 +65,3 @@ GameLib.D3.API.Fog = function( GameLib.D3.API.Fog.prototype = Object.create(GameLib.API.Component.prototype); GameLib.D3.API.Fog.prototype.constructor = GameLib.D3.API.Fog; - -/** - * Returns an API scene from an Object scene - * @param objectFog - * @constructor - */ -GameLib.D3.API.Fog.FromObject = function(objectFog) { - - return new GameLib.D3.API.Fog( - objectFog.id, - objectFog.name, - objectFog.exponential, - objectFog.color, - objectFog.near, - objectFog.far, - objectFog.density, - objectFog.parentEntity - ); - -}; diff --git a/src/game-lib-d3-api-shader-a.js b/src/game-lib-d3-api-shader-a.js index 4b03e89..8a86b8f 100644 --- a/src/game-lib-d3-api-shader-a.js +++ b/src/game-lib-d3-api-shader-a.js @@ -4,6 +4,7 @@ * @param name * @param shaderType * @param parentEntity + * @param parentMaterialShader * @param code * @constructor */ @@ -12,6 +13,7 @@ GameLib.D3.API.Shader = function( name, shaderType, parentEntity, + parentMaterialShader, code ) { @@ -46,8 +48,24 @@ GameLib.D3.API.Shader = function( } this.name = name; + if (GameLib.Utils.UndefinedOrNull(parentMaterialShader)) { + parentMaterialShader = null; + } + this.parentMaterialShader = parentMaterialShader; + if (GameLib.Utils.UndefinedOrNull(code)) { - code = ''; + switch (this.shaderType) { + case GameLib.D3.API.Shader.SHADER_TYPE_VERTEX: + code = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; + break; + case GameLib.D3.API.Shader.SHADER_TYPE_FRAGMENT: + code = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; + break; + default : + console.warn('unhandled shader type to initialize code for:' + this.name); + code = ''; + break; + } } this.code = code; diff --git a/src/game-lib-d3-api-shader-fragment.js b/src/game-lib-d3-api-shader-fragment.js index be3503d..d1c6588 100644 --- a/src/game-lib-d3-api-shader-fragment.js +++ b/src/game-lib-d3-api-shader-fragment.js @@ -23,6 +23,7 @@ GameLib.D3.API.Shader.Fragment = function( apiShader.name, apiShader.shaderType, apiShader.parentEntity, + apiShader.parentMaterialShader, apiShader.code ); }; diff --git a/src/game-lib-d3-api-shader-vertex.js b/src/game-lib-d3-api-shader-vertex.js index a6e796c..7f769e7 100644 --- a/src/game-lib-d3-api-shader-vertex.js +++ b/src/game-lib-d3-api-shader-vertex.js @@ -23,6 +23,7 @@ GameLib.D3.API.Shader.Vertex = function( apiShader.name, apiShader.shaderType, apiShader.parentEntity, + apiShader.parentMaterialShader, apiShader.code ); }; diff --git a/src/game-lib-d3-fog.js b/src/game-lib-d3-fog.js index 1ccacbb..1de343c 100644 --- a/src/game-lib-d3-fog.js +++ b/src/game-lib-d3-fog.js @@ -132,22 +132,3 @@ GameLib.D3.Fog.prototype.toApiObject = function() { ); }; - -/** - * Converts a scene Object to a GameLib.D3.Fog object - * @param graphics GameLib.GraphicsRuntime - * @param objectFog Object - * @returns {GameLib.D3.Fog} - * @constructor - */ -GameLib.D3.Fog.FromObject = function( - graphics, - objectFog -) { - var apiFog = GameLib.D3.API.Fog.FromObject(objectFog); - - return new GameLib.D3.Fog( - graphics, - apiFog - ); -}; diff --git a/src/game-lib-d3-material-shader-a.js b/src/game-lib-d3-material-shader-a.js index 438a4fd..f3ebf04 100644 --- a/src/game-lib-d3-material-shader-a.js +++ b/src/game-lib-d3-material-shader-a.js @@ -17,7 +17,6 @@ GameLib.D3.Material.Shader = function( }; } - GameLib.D3.API.Material.Shader.call( this, apiMaterialShader, @@ -52,46 +51,65 @@ GameLib.D3.Material.Shader = function( GameLib.D3.Material.Shader.prototype = Object.create(GameLib.D3.Material.prototype); GameLib.D3.Material.Shader.prototype.constructor = GameLib.D3.Material.Shader; +GameLib.D3.Material.Shader.prototype.commonInstance = function() { +}; + /** * Creates an instance of our texture object * @returns {*} */ GameLib.D3.Material.Shader.prototype.createInstance = function() { - var fragmentShader = ''; - var vertexShader = ''; + if (this.instance) { - if (this.fragmentShader && this.fragmentShader.instance) { - fragmentShader = this.fragmentShader.instance; - } + /** + * We already have an instance from Child Class + */ - if (this.vertexShader && this.vertexShader.instance) { - vertexShader = this.vertexShader.instance; - } + } else { - this.instance = new THREE.ShaderMaterial( - { - clipping : this.clipping, - defaultAttributeValues : this.defaultAttributeValues, - extensions : this.extensions, - fog : this.fog, - fragmentShader : fragmentShader, - linewidth : this.linewidth, - morphTargets : this.morphTargets, - morphNormals : this.morphNormals, - skinning : this.skinning, - uniforms : this.uniforms, - vertexColors : this.vertexColors, - vertexShader : vertexShader, - wireframe : this.wireframe, - wireframeLinewidth : this.wireframeLinewidth + if ( + GameLib.Utils.UndefinedOrNull(this.vertexShader) || + GameLib.Utils.UndefinedOrNull(this.vertexShader.instance) + ) { + console.warn('shader material ' + this.name + 'not ready for instance - needs a vertex shader'); + return; } - ); + + if ( + GameLib.Utils.UndefinedOrNull(this.fragmentShader) || + GameLib.Utils.UndefinedOrNull(this.fragmentShader.instance) + ) { + console.warn('shader material ' + this.name + 'not ready for instance - needs a fragment shader'); + return; + } + + this.instance = new THREE.ShaderMaterial( + { + clipping : this.clipping, + defaultAttributeValues : this.defaultAttributeValues, + extensions : this.extensions, + fog : this.fog, + fragmentShader : this.fragmentShader.instance, + linewidth : this.linewidth, + morphTargets : this.morphTargets, + morphNormals : this.morphNormals, + skinning : this.skinning, + uniforms : this.uniforms, + vertexColors : this.vertexColors, + vertexShader : this.vertexShader.instance, + wireframe : this.wireframe, + wireframeLinewidth : this.wireframeLinewidth + } + ); + } if (GameLib.Utils.Defined(this.index0AttributeName)) { this.instance.index0AttributeName = this.index0AttributeName; } + console.log('shader material instance created'); + GameLib.D3.Material.prototype.createInstance.call(this); }; @@ -101,7 +119,19 @@ GameLib.D3.Material.Shader.prototype.createInstance = function() { GameLib.D3.Material.Shader.prototype.updateInstance = function(property) { if (!this.instance) { - console.warn('shader material not ready'); + + if ( + property === 'vertexShader' || + property === 'fragmentShader' + ) { + this.createInstance(); + } + + /** + * If we don't return here - we risk storing this incomplete type with the entity.. + */ + + return; } if (property === 'clipping') { @@ -125,8 +155,13 @@ GameLib.D3.Material.Shader.prototype.updateInstance = function(property) { } if (property === 'fragmentShader') { - this.instance.fragmentShader = this.fragmentShader.instance; - this.instance.needsUpdate = true; + + if (this.fragmentShader && this.fragmentShader.instance) { + this.instance.fragmentShader = this.fragmentShader.instance; + this.instance.needsUpdate = true; + } else { + console.warn('fragment shader for material has been removed or not linked - using last valid fragment shader'); + } return; } @@ -166,8 +201,14 @@ GameLib.D3.Material.Shader.prototype.updateInstance = function(property) { } if (property === 'vertexShader') { - this.instance.vertexShader = this.vertexShader.instance; - this.instance.needsUpdate = true; + + if (this.vertexShader && this.vertexShader.instance) { + this.instance.vertexShader = this.vertexShader.instance; + this.instance.needsUpdate = true; + } else { + console.warn('vertex shader for material has been removed or not linked - using last valid vertex shader'); + } + return; } diff --git a/src/game-lib-d3-material-shader-raw.js b/src/game-lib-d3-material-shader-raw.js index 63fd8b1..49e60b8 100644 --- a/src/game-lib-d3-material-shader-raw.js +++ b/src/game-lib-d3-material-shader-raw.js @@ -39,15 +39,20 @@ GameLib.D3.Material.Shader.Raw.prototype.constructor = GameLib.D3.Material.Shade */ GameLib.D3.Material.Shader.Raw.prototype.createInstance = function() { - var fragmentShader = ''; - var vertexShader = ''; - - if (this.fragmentShader && this.fragmentShader.instance) { - fragmentShader = this.fragmentShader.instance; + if ( + GameLib.Utils.UndefinedOrNull(this.vertexShader) || + GameLib.Utils.UndefinedOrNull(this.vertexShader.instance) + ) { + console.warn('shader material ' + this.name + 'not ready for instance - needs a vertex shader'); + return; } - if (this.vertexShader && this.vertexShader.instance) { - vertexShader = this.vertexShader.instance; + if ( + GameLib.Utils.UndefinedOrNull(this.fragmentShader) || + GameLib.Utils.UndefinedOrNull(this.fragmentShader.instance) + ) { + console.warn('shader material ' + this.name + 'not ready for instance - needs a fragment shader'); + return; } this.instance = new THREE.RawShaderMaterial( @@ -56,24 +61,20 @@ GameLib.D3.Material.Shader.Raw.prototype.createInstance = function() { defaultAttributeValues : this.defaultAttributeValues, extensions : this.extensions, fog : this.fog, - fragmentShader : fragmentShader, + fragmentShader : this.fragmentShader.instance, linewidth : this.linewidth, morphTargets : this.morphTargets, morphNormals : this.morphNormals, skinning : this.skinning, uniforms : this.uniforms, vertexColors : this.vertexColors, - vertexShader : vertexShader, + vertexShader : this.vertexShader.instance, wireframe : this.wireframe, wireframeLinewidth : this.wireframeLinewidth } ); - if (GameLib.Utils.Defined(this.index0AttributeName)) { - this.instance.index0AttributeName = this.index0AttributeName; - } - - GameLib.D3.Material.prototype.createInstance.call(this); + GameLib.D3.Material.Shader.prototype.createInstance.call(this); }; /** diff --git a/src/game-lib-d3-scene.js b/src/game-lib-d3-scene.js index b2017d9..ce9592d 100644 --- a/src/game-lib-d3-scene.js +++ b/src/game-lib-d3-scene.js @@ -79,12 +79,12 @@ GameLib.D3.Scene = function ( }.bind(this) ); - if (typeof this.fog !== 'string') { + if (this.fog instanceof GameLib.D3.API.Fog) { this.fog = new GameLib.D3.Fog( this.graphics, this.fog ) - } + }; this.gridColor = new GameLib.Color( this.graphics, diff --git a/src/game-lib-d3-shader-a.js b/src/game-lib-d3-shader-a.js index cff9731..fb23227 100644 --- a/src/game-lib-d3-shader-a.js +++ b/src/game-lib-d3-shader-a.js @@ -22,10 +22,16 @@ GameLib.D3.Shader = function( apiShader.name, apiShader.shaderType, apiShader.parentEntity, + apiShader.parentMaterialShader, apiShader.code ); - GameLib.Component.call(this); + GameLib.Component.call( + this, + { + parentMaterialShader : GameLib.D3.Material.Shader + } + ); }; GameLib.D3.Shader.prototype = Object.create(GameLib.CustomCode.prototype); @@ -58,6 +64,17 @@ GameLib.D3.Shader.prototype.updateInstance = function(property) { if (property === 'code') { this.instance = this.code; + + if (this.parentMaterialShader && this.parentMaterialShader.instance) { + + this.parentMaterialShader.instance.program.destroy(); + +// this.parentMaterialShader.instance.needsUpdate = true; + + } else { + console.warn('parent material shader not running or linked'); + } + return; } @@ -74,6 +91,7 @@ GameLib.D3.Shader.prototype.toApiObject = function() { this.name, this.shaderType, GameLib.Utils.IdOrNull(this.parentEntity), + GameLib.Utils.IdOrNull(this.parentMaterialShader), this.code ); }; diff --git a/src/game-lib-system-gui.js b/src/game-lib-system-gui.js index 4e33b5f..20832bc 100644 --- a/src/game-lib-system-gui.js +++ b/src/game-lib-system-gui.js @@ -1205,6 +1205,7 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, 'basic': GameLib.D3.API.Material.MATERIAL_TYPE_BASIC, 'phong': GameLib.D3.API.Material.MATERIAL_TYPE_PHONG, 'shader': GameLib.D3.API.Material.MATERIAL_TYPE_SHADER, + 'raw shader': GameLib.D3.API.Material.MATERIAL_TYPE_SHADER_RAW, 'points': GameLib.D3.API.Material.MATERIAL_TYPE_POINTS // 'toon': GameLib.D3.API.Material.MATERIAL_TYPE_TOON, // 'line basic' : GameLib.D3.API.Material.MATERIAL_TYPE_LINE_BASIC diff --git a/src/game-lib-system-render.js b/src/game-lib-system-render.js index cc8d710..8506a2c 100644 --- a/src/game-lib-system-render.js +++ b/src/game-lib-system-render.js @@ -28,6 +28,8 @@ GameLib.System.Render = function( this.excludeFromEnvironmentSubscription = null; + this.shaderUpdateSubscription = null; + /** * Images */ @@ -119,6 +121,11 @@ GameLib.System.Render.prototype.start = function() { this.setActiveRenderConfiguration ); + this.shaderUpdateSubscription = GameLib.Event.Subscribe( + GameLib.Event.SHADER_UPDATE, + this.shaderUpdate.bind(this) + ); + // this.delayedInstanceEncounteredSubscription = GameLib.Event.Subscribe( // GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED, // this.delayedInstanceEncountered.bind(this) @@ -290,6 +297,19 @@ GameLib.System.Render.prototype.windowResize = function(data) { }; +GameLib.System.Render.prototype.shaderUpdate = function(data) { + + this.activeRenderConfiguration.activeScenes.map( + function(scene){ + this.activeRenderConfiguration.activeRenderer.instance.compile( + scene.instance, + this.activeRenderConfiguration.activeCamera.instance + ); + }.bind(this) + ); + +}; + GameLib.System.Render.prototype.textureUpdated = function(data) { GameLib.EntityManager.Instance.queryComponentsByConstructor(GameLib.D3.Material).map( @@ -732,6 +752,8 @@ GameLib.System.Render.prototype.stop = function() { */ this.textureUpdatedSubscription.remove(); + this.shaderUpdateSubscription.remove(); + // this.delayedInstanceEncounteredSubscription.remove(); // window.removeEventListener( diff --git a/src/game-lib-system-storage.js b/src/game-lib-system-storage.js index c4762ee..ebd0d7c 100644 --- a/src/game-lib-system-storage.js +++ b/src/game-lib-system-storage.js @@ -864,7 +864,7 @@ GameLib.System.Storage.prototype.loadImage = function(data, callback, errorCallb if (this.response.type.indexOf('application/json') !== -1) { - var base64 = 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoWEQMQBXD4hQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABRSURBVGje7c8xDQAwCAAwmA3koA/PU8FB0jpo1nRc9uI4AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBgX0fjEoBa8xN1z4AAAAASUVORK5CYII='; + var base64 = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gIPDBcYqg62uwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAaSURBVCjPY/z//z8DKYCJgUQwqmFUw9DRAABVbQMdny4VogAAAABJRU5ErkJggg=='; function fixBinary (bin) { var length = bin.length;