render to canvas - persist loading in case of errors

beta.r3js.org
-=yb4f310 2017-10-09 10:18:59 +02:00
parent c3475ccef7
commit 5c5ea74e14
11 changed files with 320 additions and 71 deletions

View File

@ -187,6 +187,7 @@ GameLib.Component.COMPONENT_CONTROLS_KEYBOARD = 0x39;
GameLib.Component.COMPONENT_CONTROLS_MOUSE = 0x3a;
GameLib.Component.COMPONENT_MESH_TEXT = 0x3b;
GameLib.Component.COMPONENT_FONT = 0x3c;
GameLib.Component.COMPONENT_CANVAS = 0x3d;
/**
* Returns string name for component number
@ -256,6 +257,7 @@ GameLib.Component.GetComponentName = function(number) {
case 0x3a : return 'GameLib.D3.Controls.Mouse';
case 0x3b : return 'GameLib.D3.Mesh.Text';
case 0x3c : return 'GameLib.D3.Font';
case 0x3d : return 'GameLib.D3.Canvas';
break;
}

View File

@ -0,0 +1,59 @@
/**
* Raw Canvas API object - should always correspond with the Canvas Schema
* @param id
* @param name
* @param width
* @param height
* @param parentEntity
* @constructor
*/
GameLib.D3.API.Canvas = function(
id,
name,
width,
height,
parentEntity
) {
if (GameLib.Utils.UndefinedOrNull(id)) {
id = GameLib.Utils.RandomId();
}
this.id = id;
if (GameLib.Utils.UndefinedOrNull(name)) {
name = 'Canvas (' + id + ')';
}
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(parentEntity)){
parentEntity = null;
}
this.parentEntity = parentEntity;
};
GameLib.D3.API.Canvas.prototype = Object.create(GameLib.Component.prototype);
GameLib.D3.API.Canvas.prototype.constructor = GameLib.D3.API.Canvas;
/**
* Returns an API light from an Object light
* @param objectCanvas
* @constructor
*/
GameLib.D3.API.Canvas.FromObject = function(objectCanvas) {
return new GameLib.D3.API.Canvas(
objectCanvas.id,
objectCanvas.name,
objectCanvas.width,
objectCanvas.height,
objectCanvas.parentEntity
);
};

View File

@ -17,9 +17,6 @@ GameLib.D3.API.RenderTarget = function (
name,
width,
height,
minFilter,
magFilter,
format,
stencilBuffer,
texture,
parentEntity
@ -44,21 +41,6 @@ GameLib.D3.API.RenderTarget = function (
}
this.height = height;
if (GameLib.Utils.UndefinedOrNull(minFilter)) {
minFilter = GameLib.D3.RenderTarget.LINEAR_FILTER;
}
this.minFilter = minFilter;
if (GameLib.Utils.UndefinedOrNull(magFilter)) {
magFilter = GameLib.D3.RenderTarget.LINEAR_FILTER;
}
this.magFilter = magFilter;
if (GameLib.Utils.UndefinedOrNull(format)) {
format = GameLib.D3.RenderTarget.RGB_FORMAT;
}
this.format = format;
if (GameLib.Utils.UndefinedOrNull(stencilBuffer)) {
stencilBuffer = false;
}
@ -90,9 +72,6 @@ GameLib.D3.API.RenderTarget.FromObject = function(objectComponent) {
objectComponent.name,
objectComponent.width,
objectComponent.height,
objectComponent.minFilter,
objectComponent.magFilter,
objectComponent.format,
objectComponent.stencilBuffer,
objectComponent.texture,
objectComponent.parentEntity

View File

@ -14,6 +14,9 @@
* @param parentEntity
* @param preserveDrawingBuffer
* @param clippingPlanes
* @param bufferScene
* @param bufferCamera
* @param renderTarget
* @constructor
*/
GameLib.D3.API.Renderer = function (
@ -30,6 +33,9 @@ GameLib.D3.API.Renderer = function (
scenes,
viewports,
clippingPlanes,
bufferScene,
bufferCamera,
renderTarget,
parentEntity
) {
if (GameLib.Utils.UndefinedOrNull(id)) {
@ -101,6 +107,21 @@ GameLib.D3.API.Renderer = function (
}
this.clippingPlanes = clippingPlanes;
if (GameLib.Utils.UndefinedOrNull(bufferScene)) {
bufferScene = null;
}
this.bufferScene = bufferScene;
if (GameLib.Utils.UndefinedOrNull(bufferCamera)) {
bufferCamera = camera;
}
this.bufferCamera = bufferCamera;
if (GameLib.Utils.UndefinedOrNull(renderTarget)) {
renderTarget = null;
}
this.renderTarget = renderTarget;
if (GameLib.Utils.UndefinedOrNull(parentEntity)) {
parentEntity = null;
}
@ -131,6 +152,9 @@ GameLib.D3.API.Renderer.FromObject = function(objectComponent) {
objectComponent.scenes,
objectComponent.viewports,
objectComponent.clippingPlanes,
objectComponent.bufferScene,
objectComponent.bufferCamera,
objectComponent.renderTarget,
objectComponent.parentEntity
);
};

View File

@ -21,6 +21,7 @@
* @param unpackAlignment
* @param premultiplyAlpha
* @param encoding
* @param canvas
* @param parentEntity
* @constructor
*/
@ -46,6 +47,7 @@ GameLib.D3.API.Texture = function(
unpackAlignment,
premultiplyAlpha,
encoding,
canvas,
parentEntity
) {
if (GameLib.Utils.UndefinedOrNull(parentEntity)) {
@ -158,6 +160,11 @@ GameLib.D3.API.Texture = function(
}
this.encoding = encoding;
if (GameLib.Utils.UndefinedOrNull(canvas)) {
canvas = null;
}
this.canvas = canvas;
this.needsUpdate = false;
};
@ -192,6 +199,7 @@ GameLib.D3.API.Texture.FromObject = function(objectTexture) {
objectTexture.unpackAlignment,
objectTexture.premultiplyAlpha,
objectTexture.encoding,
objectTexture.canvas,
objectTexture.parentEntity
)
};

95
src/game-lib-d3-canvas.js Normal file
View File

@ -0,0 +1,95 @@
/**
* Canvas Superset - The apiCanvas properties get moved into the Canvas object itself, and then the instance is created
* @param graphics GameLib.D3.Graphics
* @param apiCanvas GameLib.D3.API.Canvas
* @constructor
*/
GameLib.D3.Canvas = function(
graphics,
apiCanvas
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiCanvas)) {
apiCanvas = {};
}
if (apiCanvas instanceof GameLib.D3.Canvas) {
return apiCanvas;
}
GameLib.D3.API.Canvas.call(
this,
apiCanvas.id,
apiCanvas.name,
apiCanvas.width,
apiCanvas.height,
apiCanvas.parentEntity
);
GameLib.Component.call(
this,
GameLib.Component.COMPONENT_CANVAS
);
};
GameLib.D3.Canvas.prototype = Object.create(GameLib.D3.API.Canvas.prototype);
GameLib.D3.Canvas.prototype.constructor = GameLib.D3.Canvas;
/**
* Creates a light instance
* @returns {*}
*/
GameLib.D3.Canvas.prototype.createInstance = function() {
var instance = document.createElement('canvas');
instance.width = this.width;
instance.height = this.height;
return instance;
};
/**
* Updates the instance with the current state
*/
GameLib.D3.Canvas.prototype.updateInstance = function() {
if (GameLib.Utils.UndefinedOrNull(this.instance)) {
this.instance = document.createElement('canvas');
this.loaded = true;
}
this.instance.width = this.width;
this.instance.height = this.height;
};
/**
* Converts a GameLib.D3.Canvas to a GameLib.D3.API.Canvas
* @returns {GameLib.D3.API.Canvas}
*/
GameLib.D3.Canvas.prototype.toApiObject = function() {
return new GameLib.D3.API.Canvas(
this.id,
this.name,
this.width,
this.height,
GameLib.Utils.IdOrNull(this.parentEntity)
);
};
/**
* Returns a new GameLib.D3.Canvas from a GameLib.D3.API.Canvas
* @param graphics GameLib.D3.Graphics
* @param objectCanvas GameLib.D3.API.Canvas
* @returns {GameLib.D3.Canvas}
*/
GameLib.D3.Canvas.FromObject = function(graphics, objectCanvas) {
return new GameLib.D3.Canvas(
graphics,
GameLib.D3.API.Canvas.FromObject(objectCanvas)
);
};

View File

@ -26,9 +26,6 @@ GameLib.D3.RenderTarget = function (
apiRenderTarget.name,
apiRenderTarget.width,
apiRenderTarget.height,
apiRenderTarget.minFilter,
apiRenderTarget.magFilter,
apiRenderTarget.format,
apiRenderTarget.stencilBuffer,
apiRenderTarget.texture
);
@ -45,35 +42,28 @@ GameLib.D3.RenderTarget = function (
GameLib.D3.RenderTarget.prototype = Object.create(GameLib.D3.API.RenderTarget.prototype);
GameLib.D3.RenderTarget.prototype.constructor = GameLib.D3.RenderTarget;
/**
* Some constants (based on THREE.js constants - update if needed)
* @type {number}
*/
GameLib.D3.RenderTarget.LINEAR_FILTER = 1006;
GameLib.D3.RenderTarget.RGB_FORMAT = 1022;
GameLib.D3.RenderTarget.RGBA_FORMAT = 1023;
/**
* Creates a Render Target instance
* @returns {*}
*/
GameLib.D3.RenderTarget.prototype.createInstance = function() {
var instance = new THREE.WebGLRenderTarget(
this.width,
this.height,
{
minFilter : this.minFilter,
magFilter : this.magFilter,
format : this.format,
stencilBuffer : this.stencilBuffer
}
);
var instance = null;
if (this.texture && this.texture.loaded) {
instance = new THREE.WebGLRenderTarget(
this.width,
this.height,
{
stencilBuffer : this.stencilBuffer
}
);
if (this.texture instanceof GameLib.D3.Texture && this.texture.instance) {
instance.texture = this.texture.instance;
}
return instance;
};
@ -81,14 +71,25 @@ GameLib.D3.RenderTarget.prototype.createInstance = function() {
* updates instance
*/
GameLib.D3.RenderTarget.prototype.updateInstance = function() {
this.instance.width = this.width;
this.instance.height = this.height;
this.instance.minFilter = this.minFilter;
this.instance.magFilter = this.magFilter;
this.instance.format = this.format;
this.instance.stencilBuffer = this.stencilBuffer;
this.instance.texture = this.texture.instance;
this.instance.texture.needsUpdate = true;
if (this.instance) {
this.instance.setSize(this.width, this.height);
this.instance.stencilBuffer = this.stencilBuffer;
if (this.texture && this.texture.loaded) {
this.instance.texture = this.texture.instance;
this.instance.texture.needsUpdate = true;
} else {
this.instance.texture = null;
}
} else {
this.instance = this.createInstance();
if (this.instance) {
this.loaded = true;
}
}
};
/**
@ -102,9 +103,6 @@ GameLib.D3.RenderTarget.prototype.toApiObject = function() {
this.name,
this.width,
this.height,
this.minFilter,
this.magFilter,
this.format,
this.stencilBuffer,
GameLib.Utils.IdOrNull(this.texture),
GameLib.Utils.IdOrNull(this.parentEntity)

View File

@ -37,6 +37,9 @@ GameLib.D3.Renderer = function (
apiRenderer.scenes,
apiRenderer.viewports,
apiRenderer.clippingPlanes,
apiRenderer.bufferScene,
apiRenderer.bufferCamera,
apiRenderer.renderTarget,
apiRenderer.parentEntity
);
@ -100,6 +103,27 @@ GameLib.D3.Renderer = function (
}
}.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
)
}
/**
* Only runtime Renderer Components have runtime statistics
*/
@ -116,7 +140,10 @@ GameLib.D3.Renderer = function (
'camera' : GameLib.D3.Camera,
'scenes' : [GameLib.D3.Scene],
'viewports' : [GameLib.D3.Viewport],
'clippingPlanes': [GameLib.D3.Mesh.Plane]
'clippingPlanes': [GameLib.D3.Mesh.Plane],
'bufferScene' : GameLib.D3.Scene,
'bufferCamera' : GameLib.D3.Camera,
'renderTarget' : GameLib.D3.RenderTarget
}
);
@ -239,6 +266,14 @@ GameLib.D3.Renderer.prototype.toApiObject = function() {
this.viewports.map(function(viewport){
return GameLib.Utils.IdOrNull(viewport);
}),
this.clippingPlanes.map(
function(clippingPlane) {
return GameLib.Utils.IdOrNull(clippingPlane);
}
),
GameLib.Utils.IdOrNull(this.bufferScene),
GameLib.Utils.IdOrNull(this.bufferCamera),
GameLib.Utils.IdOrNull(this.renderTarget),
GameLib.Utils.IdOrNull(this.parentEntity)
);
@ -285,6 +320,24 @@ GameLib.D3.Renderer.prototype.render = function(delta) {
this.instance.clear();
if (
this.bufferScene &&
this.bufferScene.loaded &&
this.bufferCamera &&
this.bufferCamera.loaded &&
this.renderTarget &&
this.renderTarget.loaded
) {
/**
* 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) {

View File

@ -43,6 +43,7 @@ GameLib.D3.Texture = function(
apiTexture.unpackAlignment,
apiTexture.premultiplyAlpha,
apiTexture.encoding,
apiTexture.canvas,
apiTexture.parentEntity
);
@ -65,11 +66,19 @@ GameLib.D3.Texture = function(
);
}
if (this.canvas instanceof GameLib.D3.API.Canvas) {
this.canvas = new GameLib.D3.Canvas(
this.graphics,
this.canvas
);
}
GameLib.Component.call(
this,
GameLib.Component.COMPONENT_TEXTURE,
{
'image' : GameLib.D3.Image
'image' : GameLib.D3.Image,
'canvas' : GameLib.D3.Canvas
}
);
};
@ -191,6 +200,8 @@ GameLib.D3.Texture.prototype.createInstance = function() {
this.image.instance
);
instance.needsUpdate = true;
} else if (this.canvas && this.canvas.instance) {
instance = new THREE.Texture(this.canvas.instance);
} else {
instance = new THREE.Texture();
}
@ -232,14 +243,20 @@ GameLib.D3.Texture.prototype.updateInstance = function() {
if (this.image && this.image.instance) {
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_NORMAL) {
if (this.instance.image !== this.image.instance) {
this.instance = new THREE.Texture(
/**
* Image overrides canvas
*/
if (this.instance.image !== this.image.instance) {
this.instance = new THREE.Texture(
this.image.instance
);
this.mapping = this.instance.mapping;
imageChanged = true;
}
} else if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_CUBE) {
if (this.instance.image[0] !== this.image.instance) {
this.instance = new THREE.CubeTexture(
@ -257,7 +274,13 @@ GameLib.D3.Texture.prototype.updateInstance = function() {
imageChanged = true;
}
}
}
} else if (
this.canvas && this.canvas.instance
) {
if (this.typeId === GameLib.D3.Texture.TEXTURE_TYPE_NORMAL) {
console.log('update canvas instance here');
}
}
this.instance.name = this.name;
this.instance.flipY = this.flipY;
@ -315,6 +338,7 @@ GameLib.D3.Texture.prototype.toApiObject = function() {
this.unpackAlignment,
this.premultiplyAlpha,
this.encoding,
GameLib.Utils.IdOrNull(this.canvas),
GameLib.Utils.IdOrNull(this.parentEntity)
);

View File

@ -922,7 +922,10 @@ GameLib.System.Linking.prototype.onParentSceneChange = function(data) {
if (data.originalScene && data.originalScene.removeObject) {
data.originalScene.removeObject(data.object);
}
data.newScene.addObject(data.object);
if (data.newScene) {
data.newScene.addObject(data.object);
}
}
};

View File

@ -422,10 +422,10 @@ GameLib.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, inc
if (clientErrorCallback) {
clientErrorCallback('Could not create a runtime component: ' + component.name);
}
throw new Error('Could not create a runtime component: ' + component.name);
//throw new Error('Could not create a runtime component: ' + component.name);
}
if (parentEntity !== null) {
if (parentEntity !== null && runtimeComponent) {
runtimeComponent.parentEntity = parentEntity;
}
}
@ -439,9 +439,11 @@ GameLib.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, inc
)
}
loaded.push(runtimeComponent);
if (runtimeComponent) {
loaded.push(runtimeComponent);
}
if (includeDependencies) {
if (includeDependencies && runtimeComponent) {
/**
* Before we announce the creation of this component, we should get
* a list of all dependencies of this component, because once we announce
@ -525,16 +527,18 @@ GameLib.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, inc
* The Linking system will then kick in and try to resolve all dependencies
*/
if (onComponentLoaded) {
if (runtimeComponent && onComponentLoaded) {
onComponentLoaded(runtimeComponent);
}
GameLib.Event.Emit(
GameLib.Event.COMPONENT_CREATED,
{
component: runtimeComponent
}
);
if (runtimeComponent) {
GameLib.Event.Emit(
GameLib.Event.COMPONENT_CREATED,
{
component: runtimeComponent
}
);
}
var toProcess = GameLib.Utils.Difference(loaded.map(function(component){return component.id}), loading);