Light layer setup

This commit is contained in:
Felipe Alfonso 2017-08-02 23:06:13 -04:00
parent d3789a305e
commit b0c578477d
15 changed files with 360 additions and 1 deletions

View file

@ -1,4 +1,4 @@
var CHECKSUM = {
build: '49cc5c90-77e7-11e7-8cb3-6774896fb46c'
build: '83ce9c80-77f8-11e7-8ef9-b95451dc5563'
};
module.exports = CHECKSUM;

View file

@ -8,6 +8,7 @@ module.exports = {
Blitter: require('./blitter/Blitter'),
DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapText'),
EffectLayer: require('./effectlayer/EffectLayer'),
LightLayer: require('./lightlayer/LightLayer'),
Graphics: require('./graphics/Graphics.js'),
Group: require('./group/Group'),
Image: require('./image/Image'),

View file

@ -0,0 +1,3 @@
module.exports = {
MAX_LIGHTS: 10
};

View file

@ -0,0 +1,9 @@
var DeferredRenderer = function (renderer, src, interpolationPercentage, camera)
{
if (this.renderMask !== this.renderFlags)
{
return;
}
};
module.exports = DeferredRenderer;

View file

@ -0,0 +1,9 @@
var ForwardRenderer = function (renderer, src, interpolationPercentage, camera)
{
if (this.renderMask !== this.renderFlags)
{
return;
}
};
module.exports = ForwardRenderer;

View file

@ -0,0 +1,31 @@
var Class = require('../../utils/Class');
var Light = new Class({
initialize:
function Light (x, y, z, r, g, b, attenuation)
{
this.x = x;
this.y = y;
this.z = z;
this.r = r;
this.g = g;
this.b = b;
this.attenuation = attenuation;
},
set: function (x, y, z, r, g, b, attenuation)
{
this.x = x;
this.y = y;
this.z = z;
this.r = r;
this.g = g;
this.b = b;
this.attenuation = attenuation;
}
});
module.exports = Light;

View file

@ -0,0 +1,211 @@
var Class = require('../../utils/Class');
var GameObject = require('../GameObject');
var Components = require('../components');
var Render = require('./LightLayerRender');
var Light = require('./Light');
var SpriteNormalPair = require('./SpriteNormalPair');
var WebGLSupportedExtensions = require('../../renderer/webgl/WebGLSupportedExtensions');
var Const = require('./Const');
var LightLayer = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Flip,
Components.GetBounds,
Components.Origin,
Components.RenderTarget,
Components.ScaleMode,
Components.ScrollFactor,
Components.Size,
Components.Transform,
Components.Visible,
Render
],
initialize:
function LightLayer (scene, x, y, width, height)
{
GameObject.call(this, scene, 'LightLayer');
var resourceManager = scene.game.renderer.resourceManager;
this.renderer = scene.game.renderer;
this.passShader = null;
this.gl = null;
this.deferred = WebGLSupportedExtensions.has('WEBGL_draw_buffers');
this.ambientLightColorR = 0.0;
this.ambientLightColorG = 0.0;
this.ambientLightColorB = 0.0;
this.lightPool = [];
this.spritePool = [];
this.lights = [];
this.sprites = [];
this.lightsLocations = [];
if (resourceManager !== undefined && !this.deferred)
{
this.gl = scene.game.renderer.gl;
this.passShader = resourceManager.createShader('Phong2DShaderForward', {vert: `
precision mediump float;
uniform mat4 uProjection;
attribute vec2 vertPosition;
attribute vec2 vertTexCoord;
attribute vec3 vertColor;
attribute float vertAlpha;
varying vec2 fragTexCoord;
varying vec3 fragColor;
varying float fragAlpha;
void main()
{
fragTexCoord = vertTexCoord;
fragColor = vertColor;
fragAlpha = vertAlpha;
gl_Position = uProjection * vec4(vertPosition, 0.0, 1.0);
}
`, frag: `
precision mediump float;
struct Light
{
vec3 position;
vec3 color;
float attenuation;
};
uniform sampler2D uMainTexture;
uniform sampler2D uNormTexture;
uniform vec3 uAmbientLightColor;
uniform Light uLights[` + Const.MAX_LIGHTS + `];
varying vec2 fragTexCoord;
varying vec3 fragColor;
varying float fragAlpha;
void main()
{
/* Just Pass through for now */
gl_FragColor = texture2D(uMainTexture, fragTexCoord) * vec4(fragColor, fragAlpha);
}
`});
this.ambientLightColorLoc = this.passShader.getUniformLocation('uAmbientLightColor');
for (var index = 0; index < Const.MAX_LIGHTS; ++index)
{
this.lightsLocations[index] = {
position: this.passShader.getUniformLocation('uLights[' + index + '].position'),
color: this.passShader.getUniformLocation('uLights[' + index + '].color'),
attenuation: this.passShader.getUniformLocation('uLights[' + index + '].attenuation')
};
}
}
this.setPosition(x, y);
this.setSize(width, height);
this.setOrigin(0, 0);
},
setAmbientLightColor: function (r, g, b)
{
this.ambientLightColorR = r;
this.ambientLightColorG = g;
this.ambientLightColorB = b;
},
/* This will probably be removed later */
addSprite: function (sprite, normalTexture)
{
var spriteNormalPair;
if (this.spritePool.length > 0)
{
spriteNormalPair = this.spritePool.pop();
spriteNormalPair.set(sprite, normalTexture);
}
else
{
spriteNormalPair = new SpriteNormalPair(sprite, normalTexture);
}
this.sprites.push(spriteNormalPair);
},
removeSprite: function (sprite)
{
var length = this.sprites.length;
for (var index = 0; index < length; ++index)
{
if (this.sprites[index].spriteRef === sprite)
{
this.spritePool.push(this.sprites[index]);
this.sprites.splice(index, 1);
break;
}
}
return sprite;
},
addLight: function (x, y, z, r, g, b, attenuation)
{
if (this.lights.length < Const.MAX_LIGHTS)
{
var light = null;
if (this.lightPool.length > 0)
{
light = this.lightPool.pop();
light.set(x, y, z, r, g, b, attenuation);
}
else
{
light = new Light(x, y, z, r, g, b, attenuation);
}
this.lights.push(light);
return light;
}
return null;
},
removeLight: function (light)
{
var index = this.lights.indexOf(light);
if (index >= 0)
{
this.lightPool.push(light);
this.lights.splice(index, 1);
}
},
updateLights: function()
{
if (this.gl !== null)
{
var locations = this.lightsLocations;
var lights = this.lights;
var length = lights.length;
var gl = this.gl;
var passShader = this.passShader;
passShader.setConstantFloat3(this.ambientLightColorLoc, this.ambientLightColorR, this.ambientLightColorG, this.ambientLightColorB);
for (var index = 0; index < length; ++index)
{
var light = lights[index];
passShader.setConstantFloat3(locations[index].position, light.x, light.y, light.z);
passShader.setConstantFloat3(locations[index].color, light.r, light.g, light.b);
passShader.setConstantFloat3(locations[index].attenuation, light.attenuation);
}
}
}
});
module.exports = LightLayer;

View file

@ -0,0 +1,7 @@
var LightLayerCanvasRenderer = function (renderer, src, interpolationPercentage, camera)
{
};
module.exports = LightLayerCanvasRenderer;

View file

@ -0,0 +1,19 @@
var LightLayer = require('./LightLayer');
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
var BuildGameObject = require('../BuildGameObject');
var LightLayerCreator = function (scene, config)
{
var x = GetAdvancedValue(config, 'x', 0);
var y = GetAdvancedValue(config, 'y', 0);
var width = GetAdvancedValue(config, 'width', 512);
var height = GetAdvancedValue(config, 'height', 512);
var pass = new LightLayer(scene, x, y, width, height);
BuildGameObject(scene, pass, config);
return pass;
};
module.exports = LightLayerCreator;

View file

@ -0,0 +1,8 @@
var LightLayer = require('./LightLayer');
var LightLayerFactory = function (scene, x, y, width, height)
{
return new LightLayer(scene, x, y, width, height);
};
module.exports = LightLayerFactory;

View file

@ -0,0 +1,6 @@
module.exports = {
renderCanvas: require('./LightLayerCanvasRenderer'),
renderWebGL: require('./LightLayerWebGLRenderer')
};

View file

@ -0,0 +1,14 @@
var WebGLSupportedExtensions = require('../../renderer/webgl/WebGLSupportedExtensions');
module.exports = (function () {
if (WebGLSupportedExtensions.has('WEBGL_draw_buffers'))
{
return require('./DeferredRenderer');
}
else
{
return require('./ForwardRenderer');
}
})();

View file

@ -0,0 +1,19 @@
var Class = require('../../utils/Class');
var SpriteNormalPair = new Class({
initialize:
function SpriteNormalPair (sprite, normalTexture)
{
this.spriteRef = sprite;
this.normalTextureRef = normalTexture;
},
set: function (sprite, normalTexture)
{
this.spriteRef = sprite;
this.normalTextureRef = normalTexture;
}
});

View file

@ -16,6 +16,7 @@ var StaticTilemapFactory = require('../gameobjects/tilemap/static/StaticTilemapF
var TextFactory = require('../gameobjects/text/static/TextFactory');
var TileSpriteFactory = require('../gameobjects/tilesprite/TileSpriteFactory');
var ZoneFactory = require('../gameobjects/zone/ZoneFactory');
var LightLayerFactory = require('../gameobjects/lightlayer/LightLayerFactory');
var GameObjectFactory = new Class({
@ -127,6 +128,11 @@ var GameObjectFactory = new Class({
zone: function (x, y, width, height)
{
return this.displayList.add(ZoneFactory(this.scene, x, y, width, height));
},
lightLayer: function (x, y, width, height)
{
return this.displayList.add(LightLayerFactory(this.scene, x, y, width, height));
}
});

View file

@ -0,0 +1,16 @@
var WebGLSupportedExtensions = (function () {
var gl = document.createElement('canvas').getContext('webgl');
var extensionList = gl ? gl.getSupportedExtensions() : [];
return {
has: function (name)
{
return false; //extensionList.indexOf(name) >= 0;
}
};
}());
module.exports = WebGLSupportedExtensions;