Updated to new class structure, fixed lots of ESLint errors and moved EarCut into the geom folder and used the un-minified and latest version.

This commit is contained in:
photonstorm 2017-07-04 14:48:18 +01:00
parent dc081f0d26
commit f79db37cda
21 changed files with 1574 additions and 803 deletions

View file

@ -1,4 +1,4 @@
var CHECKSUM = {
build: '74d62650-60b8-11e7-b90e-fbadfb05faa2'
build: '4e841af0-60bf-11e7-a35c-4fb005842e0f'
};
module.exports = CHECKSUM;

View file

@ -0,0 +1,636 @@
'use strict';
module.exports = earcut;
function earcut(data, holeIndices, dim) {
dim = dim || 2;
var hasHoles = holeIndices && holeIndices.length,
outerLen = hasHoles ? holeIndices[0] * dim : data.length,
outerNode = linkedList(data, 0, outerLen, dim, true),
triangles = [];
if (!outerNode) return triangles;
var minX, minY, maxX, maxY, x, y, size;
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
if (data.length > 80 * dim) {
minX = maxX = data[0];
minY = maxY = data[1];
for (var i = dim; i < outerLen; i += dim) {
x = data[i];
y = data[i + 1];
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
// minX, minY and size are later used to transform coords into integers for z-order calculation
size = Math.max(maxX - minX, maxY - minY);
}
earcutLinked(outerNode, triangles, dim, minX, minY, size);
return triangles;
}
// create a circular doubly linked list from polygon points in the specified winding order
function linkedList(data, start, end, dim, clockwise) {
var i, last;
if (clockwise === (signedArea(data, start, end, dim) > 0)) {
for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
} else {
for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
}
if (last && equals(last, last.next)) {
removeNode(last);
last = last.next;
}
return last;
}
// eliminate colinear or duplicate points
function filterPoints(start, end) {
if (!start) return start;
if (!end) end = start;
var p = start,
again;
do {
again = false;
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
removeNode(p);
p = end = p.prev;
if (p === p.next) return null;
again = true;
} else {
p = p.next;
}
} while (again || p !== end);
return end;
}
// main ear slicing loop which triangulates a polygon (given as a linked list)
function earcutLinked(ear, triangles, dim, minX, minY, size, pass) {
if (!ear) return;
// interlink polygon nodes in z-order
if (!pass && size) indexCurve(ear, minX, minY, size);
var stop = ear,
prev, next;
// iterate through ears, slicing them one by one
while (ear.prev !== ear.next) {
prev = ear.prev;
next = ear.next;
if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {
// cut off the triangle
triangles.push(prev.i / dim);
triangles.push(ear.i / dim);
triangles.push(next.i / dim);
removeNode(ear);
// skipping the next vertice leads to less sliver triangles
ear = next.next;
stop = next.next;
continue;
}
ear = next;
// if we looped through the whole remaining polygon and can't find any more ears
if (ear === stop) {
// try filtering points and slicing again
if (!pass) {
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);
// if this didn't work, try curing all small self-intersections locally
} else if (pass === 1) {
ear = cureLocalIntersections(ear, triangles, dim);
earcutLinked(ear, triangles, dim, minX, minY, size, 2);
// as a last resort, try splitting the remaining polygon into two
} else if (pass === 2) {
splitEarcut(ear, triangles, dim, minX, minY, size);
}
break;
}
}
}
// check whether a polygon node forms a valid ear with adjacent nodes
function isEar(ear) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// now make sure we don't have other points inside the potential ear
var p = ear.next.next;
while (p !== ear.prev) {
if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.next;
}
return true;
}
function isEarHashed(ear, minX, minY, size) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// triangle bbox; min & max are calculated like this for speed
var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);
// z-order range for the current triangle bbox;
var minZ = zOrder(minTX, minTY, minX, minY, size),
maxZ = zOrder(maxTX, maxTY, minX, minY, size);
// first look for points inside the triangle in increasing z-order
var p = ear.nextZ;
while (p && p.z <= maxZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.nextZ;
}
// then look for points in decreasing z-order
p = ear.prevZ;
while (p && p.z >= minZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.prevZ;
}
return true;
}
// go through all polygon nodes and cure small local self-intersections
function cureLocalIntersections(start, triangles, dim) {
var p = start;
do {
var a = p.prev,
b = p.next.next;
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
triangles.push(a.i / dim);
triangles.push(p.i / dim);
triangles.push(b.i / dim);
// remove two nodes involved
removeNode(p);
removeNode(p.next);
p = start = b;
}
p = p.next;
} while (p !== start);
return p;
}
// try splitting polygon into two and triangulate them independently
function splitEarcut(start, triangles, dim, minX, minY, size) {
// look for a valid diagonal that divides the polygon into two
var a = start;
do {
var b = a.next.next;
while (b !== a.prev) {
if (a.i !== b.i && isValidDiagonal(a, b)) {
// split the polygon in two by the diagonal
var c = splitPolygon(a, b);
// filter colinear points around the cuts
a = filterPoints(a, a.next);
c = filterPoints(c, c.next);
// run earcut on each half
earcutLinked(a, triangles, dim, minX, minY, size);
earcutLinked(c, triangles, dim, minX, minY, size);
return;
}
b = b.next;
}
a = a.next;
} while (a !== start);
}
// link every hole into the outer loop, producing a single-ring polygon without holes
function eliminateHoles(data, holeIndices, outerNode, dim) {
var queue = [],
i, len, start, end, list;
for (i = 0, len = holeIndices.length; i < len; i++) {
start = holeIndices[i] * dim;
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
list = linkedList(data, start, end, dim, false);
if (list === list.next) list.steiner = true;
queue.push(getLeftmost(list));
}
queue.sort(compareX);
// process holes from left to right
for (i = 0; i < queue.length; i++) {
eliminateHole(queue[i], outerNode);
outerNode = filterPoints(outerNode, outerNode.next);
}
return outerNode;
}
function compareX(a, b) {
return a.x - b.x;
}
// find a bridge between vertices that connects hole with an outer ring and and link it
function eliminateHole(hole, outerNode) {
outerNode = findHoleBridge(hole, outerNode);
if (outerNode) {
var b = splitPolygon(outerNode, hole);
filterPoints(b, b.next);
}
}
// David Eberly's algorithm for finding a bridge between hole and outer polygon
function findHoleBridge(hole, outerNode) {
var p = outerNode,
hx = hole.x,
hy = hole.y,
qx = -Infinity,
m;
// find a segment intersected by a ray from the hole's leftmost point to the left;
// segment's endpoint with lesser x will be potential connection point
do {
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
if (x <= hx && x > qx) {
qx = x;
if (x === hx) {
if (hy === p.y) return p;
if (hy === p.next.y) return p.next;
}
m = p.x < p.next.x ? p : p.next;
}
}
p = p.next;
} while (p !== outerNode);
if (!m) return null;
if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint
// look for points inside the triangle of hole point, segment intersection and endpoint;
// if there are no points found, we have a valid connection;
// otherwise choose the point of the minimum angle with the ray as connection point
var stop = m,
mx = m.x,
my = m.y,
tanMin = Infinity,
tan;
p = m.next;
while (p !== stop) {
if (hx >= p.x && p.x >= mx && hx !== p.x &&
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {
m = p;
tanMin = tan;
}
}
p = p.next;
}
return m;
}
// interlink polygon nodes in z-order
function indexCurve(start, minX, minY, size) {
var p = start;
do {
if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);
p.prevZ = p.prev;
p.nextZ = p.next;
p = p.next;
} while (p !== start);
p.prevZ.nextZ = null;
p.prevZ = null;
sortLinked(p);
}
// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
function sortLinked(list) {
var i, p, q, e, tail, numMerges, pSize, qSize,
inSize = 1;
do {
p = list;
list = null;
tail = null;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q.nextZ;
if (!q) break;
}
qSize = inSize;
while (pSize > 0 || (qSize > 0 && q)) {
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
e = p;
p = p.nextZ;
pSize--;
} else {
e = q;
q = q.nextZ;
qSize--;
}
if (tail) tail.nextZ = e;
else list = e;
e.prevZ = tail;
tail = e;
}
p = q;
}
tail.nextZ = null;
inSize *= 2;
} while (numMerges > 1);
return list;
}
// z-order of a point given coords and size of the data bounding box
function zOrder(x, y, minX, minY, size) {
// coords are transformed into non-negative 15-bit integer range
x = 32767 * (x - minX) / size;
y = 32767 * (y - minY) / size;
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
// find the leftmost node of a polygon ring
function getLeftmost(start) {
var p = start,
leftmost = start;
do {
if (p.x < leftmost.x) leftmost = p;
p = p.next;
} while (p !== start);
return leftmost;
}
// check if a point lies within a convex triangle
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
(ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
(bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
}
// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
function isValidDiagonal(a, b) {
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&
locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);
}
// signed area of a triangle
function area(p, q, r) {
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}
// check if two points are equal
function equals(p1, p2) {
return p1.x === p2.x && p1.y === p2.y;
}
// check if two segments intersect
function intersects(p1, q1, p2, q2) {
if ((equals(p1, q1) && equals(p2, q2)) ||
(equals(p1, q2) && equals(p2, q1))) return true;
return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&
area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;
}
// check if a polygon diagonal intersects any polygon segments
function intersectsPolygon(a, b) {
var p = a;
do {
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
intersects(p, p.next, a, b)) return true;
p = p.next;
} while (p !== a);
return false;
}
// check if a polygon diagonal is locally inside the polygon
function locallyInside(a, b) {
return area(a.prev, a, a.next) < 0 ?
area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}
// check if the middle point of a polygon diagonal is inside the polygon
function middleInside(a, b) {
var p = a,
inside = false,
px = (a.x + b.x) / 2,
py = (a.y + b.y) / 2;
do {
if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
(px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
inside = !inside;
p = p.next;
} while (p !== a);
return inside;
}
// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
// if one belongs to the outer ring and another to a hole, it merges it into a single ring
function splitPolygon(a, b) {
var a2 = new Node(a.i, a.x, a.y),
b2 = new Node(b.i, b.x, b.y),
an = a.next,
bp = b.prev;
a.next = b;
b.prev = a;
a2.next = an;
an.prev = a2;
b2.next = a2;
a2.prev = b2;
bp.next = b2;
b2.prev = bp;
return b2;
}
// create a node and optionally link it with previous one (in a circular doubly linked list)
function insertNode(i, x, y, last) {
var p = new Node(i, x, y);
if (!last) {
p.prev = p;
p.next = p;
} else {
p.next = last.next;
p.prev = last;
last.next.prev = p;
last.next = p;
}
return p;
}
function removeNode(p) {
p.next.prev = p.prev;
p.prev.next = p.next;
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
}
function Node(i, x, y) {
// vertice index in coordinates array
this.i = i;
// vertex coordinates
this.x = x;
this.y = y;
// previous and next vertice nodes in a polygon ring
this.prev = null;
this.next = null;
// z-order curve value
this.z = null;
// previous and next nodes in z-order
this.prevZ = null;
this.nextZ = null;
// indicates whether this is a steiner point
this.steiner = false;
}
// return a percentage difference between the polygon area and its triangulation area;
// used to verify correctness of triangulation
earcut.deviation = function (data, holeIndices, dim, triangles) {
var hasHoles = holeIndices && holeIndices.length;
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
if (hasHoles) {
for (var i = 0, len = holeIndices.length; i < len; i++) {
var start = holeIndices[i] * dim;
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
polygonArea -= Math.abs(signedArea(data, start, end, dim));
}
}
var trianglesArea = 0;
for (i = 0; i < triangles.length; i += 3) {
var a = triangles[i] * dim;
var b = triangles[i + 1] * dim;
var c = triangles[i + 2] * dim;
trianglesArea += Math.abs(
(data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
(data[a] - data[b]) * (data[c + 1] - data[a + 1]));
}
return polygonArea === 0 && trianglesArea === 0 ? 0 :
Math.abs((trianglesArea - polygonArea) / polygonArea);
};
function signedArea(data, start, end, dim) {
var sum = 0;
for (var i = start, j = end - dim; i < end; i += dim) {
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
j = i;
}
return sum;
}
// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
earcut.flatten = function (data) {
var dim = data[0][0].length,
result = {vertices: [], holes: [], dimensions: dim},
holeIndex = 0;
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
}
if (i > 0) {
holeIndex += data[i - 1].length;
result.holes.push(holeIndex);
}
}
return result;
};

View file

@ -1,67 +1,68 @@
var BlitImage = require('./utils/BlitImage');
var CanvasSnapshot = require('../snapshot/CanvasSnapshot');
var Class = require('../../utils/Class');
var CONST = require('../../const');
var DrawImage = require('./utils/DrawImage');
var BlitImage = require('./utils/BlitImage');
var GetBlendModes = require('./utils/GetBlendModes');
var GetContext = require('../../canvas/GetContext');
var CanvasSnapshot = require('../snapshot/CanvasSnapshot');
var Smoothing = require('../../dom/Smoothing');
var ScaleModes = require('../ScaleModes');
var Smoothing = require('../../dom/Smoothing');
var CanvasRenderer = function (game)
{
/**
* @property {Phaser.Game} game - A reference to the currently running Game.
*/
this.game = game;
var CanvasRenderer = new Class({
// Needed?
this.type = CONST.CANVAS;
initialize:
this.drawCount = 0;
function CanvasRenderer (game)
{
/**
* @property {Phaser.Game} game - A reference to the currently running Game.
*/
this.game = game;
// Read all the following from game config (or State config?)
// this.clearBeforeRender = true;
// this.transparent = false;
// this.autoResize = false;
// this.roundPixels = false;
// Needed?
this.type = CONST.CANVAS;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.resolution = game.config.resolution;
this.drawCount = 0;
this.scaleMode = (game.config.pixelArt) ? ScaleModes.NEAREST : ScaleModes.LINEAR;
// Read all the following from game config (or State config?)
// this.clearBeforeRender = true;
// this.transparent = false;
// this.autoResize = false;
// this.roundPixels = false;
this.gameCanvas = game.canvas;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.resolution = game.config.resolution;
/**
* The canvas 2d context that everything is drawn with
* @property context
* @type CanvasRenderingContext2D
*/
this.gameContext = GetContext(this.gameCanvas);
this.scaleMode = (game.config.pixelArt) ? ScaleModes.NEAREST : ScaleModes.LINEAR;
this.gameConfig = game.config;
this.gameCanvas = game.canvas;
this.currentContext = this.gameContext;
/**
* The canvas 2d context that everything is drawn with
* @property context
* @type CanvasRenderingContext2D
*/
this.gameContext = GetContext(this.gameCanvas);
// Map to the required function
this.drawImage = DrawImage;
this.blitImage = BlitImage;
this.gameConfig = game.config;
this.blendModes = GetBlendModes();
this.currentContext = this.gameContext;
this.currentAlpha = 1;
this.currentBlendMode = 0;
this.currentScaleMode = 0;
// Map to the required function
this.drawImage = DrawImage;
this.blitImage = BlitImage;
// this.tintMethod = this.tintWithPerPixel;
this.blendModes = GetBlendModes();
this.init();
};
this.currentAlpha = 1;
this.currentBlendMode = 0;
this.currentScaleMode = 0;
CanvasRenderer.prototype.constructor = CanvasRenderer;
// this.tintMethod = this.tintWithPerPixel;
CanvasRenderer.prototype = {
this.init();
},
init: function ()
{
@ -283,6 +284,6 @@ CanvasRenderer.prototype = {
this.gameContext = null;
}
};
});
module.exports = CanvasRenderer;

View file

@ -1,18 +1,20 @@
var Class = require('../../utils/Class');
var Resources = require('./resources');
var ResourceManager = function (gl)
{
this.gl = gl;
/* Maybe add pooling here */
this.shaderCache = {};
this.shaderCount = 0;
};
var ResourceManager = new Class({
ResourceManager.prototype.constructor = ResourceManager;
initialize:
ResourceManager.prototype = {
function ResourceManager (gl)
{
this.gl = gl;
createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer)
// Maybe add pooling here?
this.shaderCache = {};
this.shaderCount = 0;
},
createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer)
{
var gl = this.gl;
var framebufferObject = gl.createFramebuffer();
@ -20,9 +22,9 @@ ResourceManager.prototype = {
var colorRenderbufferObject = null;
var complete = 0;
gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferObject)
gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferObject);
if (depthStencilBuffer !== undefined && depthStencilBuffer !== null)
if (depthStencilBuffer !== undefined && depthStencilBuffer !== null)
{
depthStencilBuffer.isRenderTexture = true;
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilBuffer.texture, depthStencilBuffer.mipLevel);
@ -35,11 +37,11 @@ ResourceManager.prototype = {
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRenderbufferObject);
}
if (colorBuffer !== undefined && colorBuffer !== null)
if (colorBuffer !== undefined && colorBuffer !== null)
{
colorBuffer.isRenderTexture = true;
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorBuffer.texture, colorBuffer.mipLevel);
}
}
else
{
colorRenderbufferObject = gl.createRenderbuffer();
@ -50,7 +52,7 @@ ResourceManager.prototype = {
complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (complete !== gl.FRAMEBUFFER_COMPLETE)
if (complete !== gl.FRAMEBUFFER_COMPLETE)
{
var errors = {
36054: 'Incomplete Attachment',
@ -71,27 +73,27 @@ ResourceManager.prototype = {
);
},
createBuffer: function (target, initialDataOrSize, bufferUsage)
createBuffer: function (target, initialDataOrSize, bufferUsage)
{
var gl = this.gl;
var bufferObject = gl.createBuffer();
gl.bindBuffer(target, bufferObject);
gl.bufferData(target, initialDataOrSize, bufferUsage);
switch (target)
switch (target)
{
case gl.ARRAY_BUFFER:
return new Resources.VertexBuffer(gl, bufferObject);
case gl.ELEMENT_ARRAY_BUFFER:
return new Resources.IndexBuffer(gl, bufferObject);
default:
throw new Error('Invalid Buffer Target');
}
return null;
},
createTexture: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height)
createTexture: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height)
{
var gl = this.gl;
var texture = gl.createTexture();
@ -102,28 +104,30 @@ ResourceManager.prototype = {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
if (pixels === null || pixels === undefined)
if (pixels === null || pixels === undefined)
{
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null);
}
else
}
else
{
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels);
width = pixels.width;
height = pixels.height;
}
gl.bindTexture(gl.TEXTURE_2D, null);
return new Resources.Texture(texture, width, height);
},
createShader: function (shaderName, shaderSources)
createShader: function (shaderName, shaderSources)
{
if (shaderName === null || shaderName === undefined)
{
shaderName += 'Shader' + this.shaderCount;
this.shaderCount += 1;
}
if (!(shaderName in this.shaderCache))
{
var gl = this.gl;
@ -141,7 +145,7 @@ ResourceManager.prototype = {
error = gl.getShaderInfoLog(vertShader);
status = gl.getShaderParameter(vertShader, gl.COMPILE_STATUS);
if (!status && error && error.length > 0)
if (!status && error && error.length > 0)
{
throw new Error('Vertex Shader Compilation Error. Shader name: ' + shaderName + '.\n' + error + '\n\n Shader source:\n' + shaderSources.vert);
}
@ -157,7 +161,7 @@ ResourceManager.prototype = {
error = gl.getShaderInfoLog(fragShader);
status = gl.getShaderParameter(fragShader, gl.COMPILE_STATUS);
if (!status && error && error.length > 0)
if (!status && error && error.length > 0)
{
throw new Error('Fragment Shader Compilation Error. Shader name: ' + shaderName + '.\n' + error + '\n\n Shader source:\n' + shaderSources.frag);
}
@ -182,6 +186,7 @@ ResourceManager.prototype = {
}
error = gl.getProgramParameter(program, gl.VALIDATE_STATUS);
if (error === 0)
{
error = gl.getProgramInfoLog(program);
@ -189,26 +194,32 @@ ResourceManager.prototype = {
}
shader = new Resources.Shader(shaderName, gl, program, vertShader, fragShader);
this.shaderCache[shaderName] = shader;
return shader;
return shader;
}
else
{
return this.shaderCache[shaderName];
return this.shaderCache[shaderName];
}
},
deleteShader: function (shader)
{
var storedShader = this.shaderCache[shader.name]
var storedShader = this.shaderCache[shader.name];
var gl = this.gl;
if (storedShader !== undefined)
{
delete this.shaderCache;
}
gl.deleteShader(shader.vertexShader);
gl.deleteShader(shader.fragmentShader);
gl.deleteProgram(shader.program);
shader.vertexShader = null;
shader.fragmentShader = null;
shader.program = null;
@ -222,6 +233,6 @@ ResourceManager.prototype = {
gl.deleteBuffer(buffer.bufferObject);
}
};
});
module.exports = ResourceManager;

View file

@ -5,84 +5,84 @@
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
var CONST = require('../../const');
var BlitterBatch = require('./renderers/blitterbatch/BlitterBatch');
var QuadBatch = require('./renderers/quadbatch/QuadBatch');
var SpriteBatch = require('./renderers/spritebatch/SpriteBatch');
var TileBatch = require('./renderers/tilebatch/TileBatch');
var ShapeBatch = require('./renderers/shapebatch/ShapeBatch');
var EffectRenderer = require('./renderers/effectrenderer/EffectRenderer');
var TilemapRenderer = require('./renderers/tilemaprenderer/TilemapRenderer');
var BlendModes = require('../BlendModes');
var ScaleModes = require('../ScaleModes');
var BlitterBatch = require('./renderers/blitterbatch/BlitterBatch');
var Class = require('../../utils/Class');
var CONST = require('../../const');
var EffectRenderer = require('./renderers/effectrenderer/EffectRenderer');
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
var QuadBatch = require('./renderers/quadbatch/QuadBatch');
var ResourceManager = require('./ResourceManager');
var Resources = require('./resources');
var ScaleModes = require('../ScaleModes');
var ShapeBatch = require('./renderers/shapebatch/ShapeBatch');
var SpriteBatch = require('./renderers/spritebatch/SpriteBatch');
var TileBatch = require('./renderers/tilebatch/TileBatch');
var TilemapRenderer = require('./renderers/tilemaprenderer/TilemapRenderer');
var WebGLSnapshot = require('../snapshot/WebGLSnapshot');
var WebGLRenderer = function (game)
{
this.game = game;
this.type = CONST.WEBGL;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.resolution = game.config.resolution;
this.view = game.canvas;
var WebGLRenderer = new Class({
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
initialize:
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
function WebGLRenderer (game)
{
this.game = game;
this.type = CONST.WEBGL;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.resolution = game.config.resolution;
this.view = game.canvas;
this.contextLost = false;
this.maxTextures = 1;
this.multiTexture = false;
this.blendModes = [];
this.gl = null;
this.extensions = null;
this.rendererArray = [];
this.blitterBatch = null;
this.aaQuadBatch = null;
this.spriteBatch = null;
this.shapeBatch = null;
this.effectRenderer = null;
this.currentRenderer = null;
this.currentTexture = null;
this.shaderCache = {};
this.currentShader = null;
this.resourceManager = null;
this.currentRenderTarget = null;
this.snapshotCallback = null;
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
this.scissor = {
enabled: false,
x: 0,
y: 0,
width: 0,
height: 0
};
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
this.init();
};
this.contextLost = false;
this.maxTextures = 1;
this.multiTexture = false;
this.blendModes = [];
this.gl = null;
this.extensions = null;
this.rendererArray = [];
this.blitterBatch = null;
this.aaQuadBatch = null;
this.spriteBatch = null;
this.shapeBatch = null;
this.effectRenderer = null;
this.currentRenderer = null;
this.currentTexture = null;
this.shaderCache = {};
this.currentShader = null;
this.resourceManager = null;
this.currentRenderTarget = null;
this.snapshotCallback = null;
WebGLRenderer.prototype.constructor = WebGLRenderer;
this.scissor = {
enabled: false,
x: 0,
y: 0,
width: 0,
height: 0
};
WebGLRenderer.prototype = {
this.init();
},
init: function ()
{
// console.log('WebGLRenderer.init');
this.gl = this.view.getContext('webgl', this.config.WebGLContextOptions) || this.view.getContext('experimental-webgl', this.config.WebGLContextOptions);
if (!this.gl)
@ -133,10 +133,10 @@ WebGLRenderer.prototype = {
{
width = source ? source.width : width;
height = source ? source.height : height;
var pot = ((width & (width - 1)) == 0 && (height & (height - 1)) == 0);
var gl = this.gl;
var filter = gl.NEAREST;
var wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE;
var wrap = IsSizePowerOfTwo(width, height) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
if (!source.glTexture)
{
@ -225,6 +225,7 @@ WebGLRenderer.prototype = {
if (renderTarget !== null)
{
gl.bindFramebuffer(gl.FRAMEBUFFER, renderTarget.framebufferObject);
if (renderTarget.shouldClear)
{
gl.clearColor(0, 0, 0, renderTarget.clearAlpha);
@ -237,6 +238,7 @@ WebGLRenderer.prototype = {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, this.width, this.height);
}
this.currentRenderTarget = renderTarget;
}
},
@ -258,11 +260,13 @@ WebGLRenderer.prototype = {
}
this.gl.viewport(0, 0, this.width, this.height);
for (var i = 0, l = this.rendererArray.length; i < l; ++i)
{
this.rendererArray[i].bind();
this.rendererArray[i].resize(width, height, resolution);
}
this.currentRenderer.bind();
},
@ -301,8 +305,8 @@ WebGLRenderer.prototype = {
*/
render: function (state, children, interpolationPercentage, camera)
{
// Could move to the State Systems or MainLoop
var gl = this.gl;
var quadBatch = this.quadBatch;
this.scissor.enabled = (camera.x !== 0 || camera.y !== 0 || camera.width !== gl.canvas.width || camera.height !== gl.canvas.height);
@ -323,13 +327,16 @@ WebGLRenderer.prototype = {
if (camera.backgroundColor.alphaGL > 0)
{
var color = camera.backgroundColor;
var quadBatch = this.quadBatch;
quadBatch.bind();
quadBatch.add(
camera.x, camera.y, camera.width, camera.height,
camera.x, camera.y, camera.width, camera.height,
color.redGL, color.greenGL, color.blueGL, color.alphaGL
);
quadBatch.flush();
this.currentRenderer.bind();
}
@ -340,7 +347,7 @@ WebGLRenderer.prototype = {
{
var child = list[index];
// Setting blend mode if needed
// Setting blend mode if needed
var renderer = this.currentRenderer;
var newBlendMode = child.blendMode;
@ -350,22 +357,28 @@ WebGLRenderer.prototype = {
{
renderer.flush();
}
var blend = this.blendModes[newBlendMode];
gl.enable(gl.BLEND);
if (blend.length > 2)
{
gl.blendFuncSeparate(blend[0], blend[1], blend[2], blend[3]);
}
else
{
gl.blendFunc(blend[0], blend[1]);
gl.blendFunc(blend[0], blend[1]);
}
this.blendMode = newBlendMode;
}
// drawing child
child.renderWebGL(this, child, interpolationPercentage, camera);
renderer = this.currentRenderer;
if (renderer.isFull() || renderer.shouldFlush())
{
renderer.flush();
@ -377,27 +390,29 @@ WebGLRenderer.prototype = {
if (camera._fadeAlpha > 0 || camera._flashAlpha > 0)
{
this.setRenderTarget(null);
var quadBatch = this.quadBatch;
quadBatch.bind();
// fade rendering
quadBatch.add(
camera.x, camera.y, camera.width, camera.height,
camera._fadeRed,
camera._fadeGreen,
camera._fadeBlue,
camera.x, camera.y, camera.width, camera.height,
camera._fadeRed,
camera._fadeGreen,
camera._fadeBlue,
camera._fadeAlpha
);
// flash rendering
quadBatch.add(
camera.x, camera.y, camera.width, camera.height,
camera._flashRed,
camera._flashGreen,
camera._flashBlue,
camera.x, camera.y, camera.width, camera.height,
camera._flashRed,
camera._flashGreen,
camera._flashBlue,
camera._flashAlpha
);
quadBatch.flush();
this.currentRenderer.bind();
}
@ -428,11 +443,6 @@ WebGLRenderer.prototype = {
this.snapshotCallback = callback;
},
destroy: function ()
{
this.gl = null;
},
createFBO: function () {},
setBlendMode: function (newBlendMode)
@ -449,6 +459,7 @@ WebGLRenderer.prototype = {
}
blend = this.blendModes[newBlendMode];
gl.enable(gl.BLEND);
if (blend.length > 2)
@ -457,7 +468,7 @@ WebGLRenderer.prototype = {
}
else
{
gl.blendFunc(blend[0], blend[1]);
gl.blendFunc(blend[0], blend[1]);
}
this.blendMode = newBlendMode;
@ -505,18 +516,20 @@ WebGLRenderer.prototype = {
if (!dstTexture)
{
dstTexture = new Resources.Texture(null, 0, 0);
/* only call this once */
// Only call this once
dstTexture.texture = gl.createTexture();
}
if (shouldUpdateResource)
{
/* Update resource */
// Update resource
gl.bindTexture(gl.TEXTURE_2D, dstTexture.texture);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
}
else
{
/* Allocate or Reallocate resource */
// Allocate or Reallocate resource
gl.bindTexture(gl.TEXTURE_2D, dstTexture.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
@ -528,11 +541,17 @@ WebGLRenderer.prototype = {
dstTexture.width = srcCanvas.width;
dstTexture.height = srcCanvas.height;
/* we must rebind old texture */
// We must rebind old texture
this.currentTexture = null;
return dstTexture;
},
destroy: function ()
{
this.gl = null;
}
};
});
module.exports = WebGLRenderer;

View file

@ -1,54 +1,54 @@
var DataBuffer32 = require('../../utils/DataBuffer32');
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer16 = require('../../utils/DataBuffer16');
var DataBuffer32 = require('../../utils/DataBuffer32');
var PHASER_CONST = require('../../../../const');
var TexturedAndAlphaShader = require('../../shaders/TexturedAndAlphaShader');
var PHASER_CONST = require('../../../../const');
var CONST = require('./const');
var BlitterBatch = new Class({
var BlitterBatch = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxParticles = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
initialize:
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
function BlitterBatch (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxParticles = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
this.manager = manager;
this.dirty = false;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
this.init(this.glContext);
};
this.manager = manager;
this.dirty = false;
BlitterBatch.prototype.constructor = BlitterBatch;
BlitterBatch.prototype = {
this.init(this.glContext);
},
init: function (gl)
{
@ -110,6 +110,7 @@ BlitterBatch.prototype = {
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
@ -126,8 +127,11 @@ BlitterBatch.prototype = {
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
},
@ -159,6 +163,7 @@ BlitterBatch.prototype = {
this.indexBufferObject = null;
this.vertexBufferObject = null;
}
};
});
module.exports = BlitterBatch;

View file

@ -1,59 +1,59 @@
var DataBuffer32 = require('../../utils/DataBuffer32');
var DataBuffer16 = require('../../utils/DataBuffer16');
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
var PHASER_CONST = require('../../../../const');
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer16 = require('../../utils/DataBuffer16');
var DataBuffer32 = require('../../utils/DataBuffer32');
var PHASER_CONST = require('../../../../const');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
var EffectRenderer = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
this.tempMatrix = new TransformMatrix();
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
var EffectRenderer = new Class({
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
initialize:
this.manager = manager;
this.dirty = false;
function EffectRenderer (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
this.tempMatrix = new TransformMatrix();
this.init(this.glContext);
};
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
EffectRenderer.prototype.constructor = EffectRenderer;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
EffectRenderer.prototype = {
this.manager = manager;
this.dirty = false;
this.init(this.glContext);
},
init: function (gl)
{
var vertexDataBuffer = new DataBuffer32(CONST.VERTEX_SIZE * CONST.QUAD_VERTEX_COUNT * CONST.MAX_QUADS);
var indexDataBuffer = new DataBuffer16(CONST.INDEX_SIZE * CONST.QUAD_INDEX_COUNT * CONST.MAX_QUADS);
var shader = this.manager.resourceManager.createShader('TexturedAndNormalizedTintedShader', TexturedAndNormalizedTintedShader);
@ -112,6 +112,7 @@ EffectRenderer.prototype = {
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
@ -130,13 +131,14 @@ EffectRenderer.prototype = {
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
},
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
@ -153,17 +155,6 @@ EffectRenderer.prototype = {
);
},
destroy: function ()
{
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.indexBufferObject);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
this.shader = null;
this.indexBufferObject = null;
this.vertexBufferObject = null;
},
renderEffect: function (gameObject, camera, texture, textureWidth, textureHeight)
{
var tempMatrix = this.tempMatrix;
@ -187,6 +178,7 @@ EffectRenderer.prototype = {
var mva, mvb, mvc, mvd, mve, mvf, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3;
var sra, srb, src, srd, sre, srf, cma, cmb, cmc, cmd, cme, cmf;
var alpha = gameObject.alpha;
var tint = gameObject._tint;
tempMatrix.applyITRS(translateX, translateY, rotation, scaleX, scaleY);
@ -209,7 +201,7 @@ EffectRenderer.prototype = {
mvc = src * cma + srd * cmc;
mvd = src * cmb + srd * cmd;
mve = sre * cma + srf * cmc + cme;
mvf = sre * cmb + srf * cmd + cmf;
mvf = sre * cmb + srf * cmd + cmf;
tx0 = x * mva + y * mvc + mve;
ty0 = x * mvb + y * mvd + mvf;
@ -224,39 +216,54 @@ EffectRenderer.prototype = {
vertexOffset = vertexDataBuffer.allocate(24);
this.elementCount += 6;
// Top Left
vertexBufferObjectF32[vertexOffset++] = tx0;
vertexBufferObjectF32[vertexOffset++] = ty0;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF;
vertexBufferObjectU32[vertexOffset++] = tint[0];
vertexBufferObjectF32[vertexOffset++] = alpha;
// Bottom Left
vertexBufferObjectF32[vertexOffset++] = tx1;
vertexBufferObjectF32[vertexOffset++] = ty1;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF;
vertexBufferObjectU32[vertexOffset++] = tint[2];
vertexBufferObjectF32[vertexOffset++] = alpha;
// Bottom Right
vertexBufferObjectF32[vertexOffset++] = tx2;
vertexBufferObjectF32[vertexOffset++] = ty2;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF;
vertexBufferObjectU32[vertexOffset++] = tint[3];
vertexBufferObjectF32[vertexOffset++] = alpha;
// Top Right
vertexBufferObjectF32[vertexOffset++] = tx3;
vertexBufferObjectF32[vertexOffset++] = ty3;
vertexBufferObjectF32[vertexOffset++] = 1;
vertexBufferObjectF32[vertexOffset++] = 0;
vertexBufferObjectU32[vertexOffset++] = 0xFFFFFF;
vertexBufferObjectU32[vertexOffset++] = tint[1];
vertexBufferObjectF32[vertexOffset++] = alpha;
this.flush(gameObject.dstShader);
gameObject.dstRenderTarget.shouldClear = true;
gameObject.dstRenderTarget.shouldClear = true;
},
destroy: function ()
{
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.indexBufferObject);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
this.shader = null;
this.indexBufferObject = null;
this.vertexBufferObject = null;
}
};
});
module.exports = EffectRenderer;

View file

@ -1,57 +1,56 @@
var DataBuffer32 = require('../../utils/DataBuffer32');
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer16 = require('../../utils/DataBuffer16');
var DataBuffer32 = require('../../utils/DataBuffer32');
var PHASER_CONST = require('../../../../const');
var UntexturedAndTintedShader = require('../../shaders/UntexturedAndTintedShader');
var PHASER_CONST = require('../../../../const');
var CONST = require('./const');
var QuadBatch = new Class({
var QuadBatch = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxQuads = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.viewMatrixLocation = null;
initialize:
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
function QuadBatch (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxQuads = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.viewMatrixLocation = null;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
this.manager = manager;
this.dirty = false;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
this.init(this.glContext);
};
this.manager = manager;
this.dirty = false;
QuadBatch.prototype.constructor = QuadBatch;
QuadBatch.prototype = {
this.init(this.glContext);
},
init: function (gl)
{
var vertexDataBuffer = new DataBuffer32(CONST.VERTEX_SIZE * CONST.AAQUAD_VERTEX_COUNT * CONST.MAX_AAQUAD);
var indexDataBuffer = new DataBuffer16(CONST.INDEX_SIZE * CONST.AAQUAD_INDEX_COUNT * CONST.MAX_AAQUAD);
var shader = this.manager.resourceManager.createShader('UntexturedAndTintedShader', UntexturedAndTintedShader);
@ -147,6 +146,7 @@ QuadBatch.prototype = {
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
@ -163,14 +163,15 @@ QuadBatch.prototype = {
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
},
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
@ -197,6 +198,7 @@ QuadBatch.prototype = {
this.indexBufferObject = null;
this.vertexBufferObject = null;
}
};
});
module.exports = QuadBatch;

View file

@ -1,58 +1,57 @@
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer32 = require('../../utils/DataBuffer32');
var Earcut = require('./earcut');
var Earcut = require('../../../../geom/earcut/Earcut');
var PHASER_CONST = require('../../../../const');
var UntexturedAndNormalizedTintedShader = require('../../shaders/UntexturedAndNormalizedTintedShader');
var PHASER_CONST = require('../../../../const');
var CONST = require('./const');
var ShapeBatch = new Class({
var ShapeBatch = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxVertices = null;
this.shader = null;
this.vertexBufferObject = null;
this.vertexDataBuffer = null;
this.vertexCount = 0;
this.viewMatrixLocation = null;
this.tempTriangle = [
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0},
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0},
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0},
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0}
];
initialize:
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
function ShapeBatch (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxVertices = null;
this.shader = null;
this.vertexBufferObject = null;
this.vertexDataBuffer = null;
this.vertexCount = 0;
this.viewMatrixLocation = null;
this.tempTriangle = [
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0},
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0},
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0},
{x: 0, y: 0, width: 0, rgb: 0xFFFFFF, alpha: 1.0}
];
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
this.manager = manager;
this.dirty = false;
this.context = null;
this.init(this.glContext);
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
};
ShapeBatch.prototype.constructor = ShapeBatch;
ShapeBatch.prototype = {
this.manager = manager;
this.dirty = false;
this.context = null;
this.init(this.glContext);
},
init: function (gl)
{
@ -97,6 +96,7 @@ ShapeBatch.prototype = {
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.vertexBufferObject.bind();
},
@ -112,14 +112,16 @@ ShapeBatch.prototype = {
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawArrays(gl.TRIANGLES, 0, this.vertexCount);
vertexDataBuffer.clear();
this.vertexCount = 0;
},
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
@ -136,24 +138,17 @@ ShapeBatch.prototype = {
);
},
destroy: function ()
// Graphics Game Object properties
// srcX, srcY, srcScaleX, srcScaleY, srcRotation,
// line properties
// ax, ay, bx, by, aLineWidth, bLineWidth, aLineColor, bLineColor, lineAlpha,
// transform
// a1, b1, c1, d1, e1, f1,
// currentMatrix
addLine: function (srcX, srcY, srcScaleX, srcScaleY, srcRotation, ax, ay, bx, by, aLineWidth, bLineWidth, aLineColor, bLineColor, lineAlpha, a1, b1, c1, d1, e1, f1, currentMatrix)
{
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
this.shader = null;
this.vertexBufferObject = null;
},
addLine: function (
/* Graphics Game Object properties */
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
/* line properties */
ax, ay, bx, by, aLineWidth, bLineWidth, aLineColor, bLineColor, lineAlpha,
/* transform */
a1, b1, c1, d1, e1, f1,
currentMatrix
) {
if (this.vertexCount + 6 > this.maxVertices)
{
this.flush();
@ -205,22 +200,27 @@ ShapeBatch.prototype = {
vertexBufferF32[vertexOffset++] = y0;
vertexBufferU32[vertexOffset++] = bLineColor;
vertexBufferF32[vertexOffset++] = lineAlpha;
vertexBufferF32[vertexOffset++] = x1;
vertexBufferF32[vertexOffset++] = y1;
vertexBufferU32[vertexOffset++] = aLineColor;
vertexBufferF32[vertexOffset++] = lineAlpha;
vertexBufferF32[vertexOffset++] = x2;
vertexBufferF32[vertexOffset++] = y2;
vertexBufferU32[vertexOffset++] = bLineColor;
vertexBufferF32[vertexOffset++] = lineAlpha;
vertexBufferF32[vertexOffset++] = x1;
vertexBufferF32[vertexOffset++] = y1;
vertexBufferU32[vertexOffset++] = aLineColor;
vertexBufferF32[vertexOffset++] = lineAlpha;
vertexBufferF32[vertexOffset++] = x3;
vertexBufferF32[vertexOffset++] = y3;
vertexBufferU32[vertexOffset++] = aLineColor;
vertexBufferF32[vertexOffset++] = lineAlpha;
vertexBufferF32[vertexOffset++] = x2;
vertexBufferF32[vertexOffset++] = y2;
vertexBufferU32[vertexOffset++] = bLineColor;
@ -232,53 +232,53 @@ ShapeBatch.prototype = {
x2, y2, bLineColor,
x3, y3, aLineColor
];
},
addStrokePath: function (
/* Graphics Game Object properties */
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
/* Path properties */
path, lineWidth, lineColor, lineAlpha,
/* transform */
a, b, c, d, e, f,
/* is last connection */
isLastPath,
currentMatrix
) {
// Graphics Game Object properties
// srcX, srcY, srcScaleX, srcScaleY, srcRotation,
// Path properties
// path, lineWidth, lineColor, lineAlpha,
// transform
// a, b, c, d, e, f,
// is last connection
// isLastPath,
// currentMatrix
addStrokePath: function (srcX, srcY, srcScaleX, srcScaleY, srcRotation, path, lineWidth, lineColor, lineAlpha, a, b, c, d, e, f, isLastPath, currentMatrix)
{
var point0, point1;
var pathLength = path.length;
var polylines = this.polygonCache;
var halfLineWidth = lineWidth * 0.5;
var last, curr;
var vertexDataBuffer = this.vertexDataBuffer;
var vertexBufferF32 = vertexDataBuffer.floatView;
var vertexBufferU32 = vertexDataBuffer.uintView;
var vertexOffset;
var x0, y0, x1, y1, x2, y2;
var line;
for (var pathIndex = 0; pathIndex + 1 < pathLength; pathIndex += 1)
{
point0 = path[pathIndex];
point1 = path[pathIndex + 1];
line = this.addLine(
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
point0.x, point0.y,
point1.x, point1.y,
point0.width / 2, point1.width / 2,
point0.x, point0.y,
point1.x, point1.y,
point0.width / 2, point1.width / 2,
point0.rgb, point1.rgb, lineAlpha,
a, b, c, d, e, f,
currentMatrix
);
polylines.push(line);
}
/* Render joints */
for (var index = 1, polylinesLength = polylines.length;
index < polylinesLength; ++index)
for (var index = 1, polylinesLength = polylines.length; index < polylinesLength; ++index)
{
if (this.vertexCount + 6 > this.maxVertices)
{
this.flush();
@ -286,7 +286,7 @@ ShapeBatch.prototype = {
last = polylines[index - 1] || polylines[polylinesLength - 1];
curr = polylines[index];
vertexOffset = vertexDataBuffer.allocate(24)
vertexOffset = vertexDataBuffer.allocate(24);
vertexBufferF32[vertexOffset++] = last[3 * 2 + 0];
vertexBufferF32[vertexOffset++] = last[3 * 2 + 1];
@ -320,18 +320,21 @@ ShapeBatch.prototype = {
this.vertexCount += 6;
}
polylines.length = 0;
},
addFillPath: function (
/* Graphics Game Object properties */
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
/* Path properties */
path, fillColor, fillAlpha,
/* transform */
a1, b1, c1, d1, e1, f1,
currentMatrix
) {
// Graphics Game Object properties
// srcX, srcY, srcScaleX, srcScaleY, srcRotation,
// Path properties
// path, fillColor, fillAlpha,
// transform
// a1, b1, c1, d1, e1, f1,
// currentMatrix
addFillPath: function (srcX, srcY, srcScaleX, srcScaleY, srcRotation, path, fillColor, fillAlpha, a1, b1, c1, d1, e1, f1, currentMatrix)
{
var length = path.length;
var polygonCache = this.polygonCache;
var polygonIndexArray;
@ -363,6 +366,7 @@ ShapeBatch.prototype = {
point = path[pathIndex];
polygonCache.push(point.x, point.y);
}
polygonIndexArray = Earcut(polygonCache);
length = polygonIndexArray.length;
@ -378,6 +382,7 @@ ShapeBatch.prototype = {
this.flush();
vertexCount = 0;
}
vertexOffset = vertexDataBuffer.allocate(12);
vertexCount += 3;
@ -411,23 +416,28 @@ ShapeBatch.prototype = {
vertexBufferF32[vertexOffset++] = fillAlpha;
}
this.vertexCount = vertexCount;
polygonCache.length = 0;
},
addFillRect: function (
/* Graphics Game Object properties */
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
/* Rectangle properties */
x, y, width, height, fillColor, fillAlpha,
/* transform */
a1, b1, c1, d1, e1, f1,
currentMatrix
) {
// Graphics Game Object properties
// srcX, srcY, srcScaleX, srcScaleY, srcRotation,
// Rectangle properties
// x, y, width, height, fillColor, fillAlpha,
// transform
// a1, b1, c1, d1, e1, f1,
// currentMatrix
addFillRect: function (srcX, srcY, srcScaleX, srcScaleY, srcRotation, x, y, width, height, fillColor, fillAlpha, a1, b1, c1, d1, e1, f1, currentMatrix)
{
if (this.vertexCount + 6 > this.maxVertices)
{
this.flush();
}
var vertexDataBuffer = this.vertexDataBuffer;
var vertexBufferF32 = vertexDataBuffer.floatView;
var vertexBufferU32 = vertexDataBuffer.uintView;
@ -488,19 +498,22 @@ ShapeBatch.prototype = {
this.vertexCount += 6;
},
addFillTriangle: function (
/* Graphics Game Object properties */
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
/* Triangle properties */
x0, y0, x1, y1, x2, y2, fillColor, fillAlpha,
/* transform */
a1, b1, c1, d1, e1, f1,
currentMatrix
) {
// Graphics Game Object properties
// srcX, srcY, srcScaleX, srcScaleY, srcRotation,
// Triangle properties
// x0, y0, x1, y1, x2, y2, fillColor, fillAlpha,
// transform
// a1, b1, c1, d1, e1, f1,
// currentMatrix
addFillTriangle: function (srcX, srcY, srcScaleX, srcScaleY, srcRotation, x0, y0, x1, y1, x2, y2, fillColor, fillAlpha, a1, b1, c1, d1, e1, f1, currentMatrix)
{
if (this.vertexCount + 3 > this.maxVertices)
{
this.flush();
}
var a0 = currentMatrix.matrix[0];
var b0 = currentMatrix.matrix[1];
var c0 = currentMatrix.matrix[2];
@ -542,15 +555,17 @@ ShapeBatch.prototype = {
this.vertexCount += 3;
},
addStrokeTriangle: function (
/* Graphics Game Object properties */
srcX, srcY, srcScaleX, srcScaleY, srcRotation,
/* Triangle properties */
x0, y0, x1, y1, x2, y2, lineWidth, lineColor, lineAlpha,
/* transform */
a, b, c, d, e, f,
currentMatrix
) {
// Graphics Game Object properties
// srcX, srcY, srcScaleX, srcScaleY, srcRotation,
// Triangle properties
// x0, y0, x1, y1, x2, y2, lineWidth, lineColor, lineAlpha,
// transform
// a, b, c, d, e, f,
// currentMatrix
addStrokeTriangle: function (srcX, srcY, srcScaleX, srcScaleY, srcRotation, x0, y0, x1, y1, x2, y2, lineWidth, lineColor, lineAlpha, a, b, c, d, e, f, currentMatrix)
{
var tempTriangle = this.tempTriangle;
tempTriangle[0].x = x0;
@ -581,7 +596,17 @@ ShapeBatch.prototype = {
false,
currentMatrix
);
},
destroy: function ()
{
this.manager.resourceManager.deleteShader(this.shader);
this.manager.resourceManager.deleteBuffer(this.vertexBufferObject);
this.shader = null;
this.vertexBufferObject = null;
}
};
});
module.exports = ShapeBatch;

File diff suppressed because one or more lines are too long

View file

@ -1,62 +1,62 @@
var DataBuffer32 = require('../../utils/DataBuffer32');
var DataBuffer16 = require('../../utils/DataBuffer16');
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
var PHASER_CONST = require('../../../../const');
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer16 = require('../../utils/DataBuffer16');
var DataBuffer32 = require('../../utils/DataBuffer32');
var PHASER_CONST = require('../../../../const');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
var SpriteBatch = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.indexBufferObjectForMesh = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
this.tempMatrix = new TransformMatrix();
var SpriteBatch = new Class({
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
initialize:
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
function SpriteBatch (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.indexBufferObjectForMesh = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
this.tempMatrix = new TransformMatrix();
this.manager = manager;
this.dirty = false;
this.drawIndexed = true;
this.lastDrawIndexed = true;
this.lastDrawingMesh = false;
this.drawingMesh = false;
this.vertexCount = 0;
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
this.init(this.glContext);
};
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
SpriteBatch.prototype.constructor = SpriteBatch;
this.manager = manager;
this.dirty = false;
this.drawIndexed = true;
this.lastDrawIndexed = true;
this.lastDrawingMesh = false;
this.drawingMesh = false;
this.vertexCount = 0;
SpriteBatch.prototype = {
this.init(this.glContext);
},
init: function (gl)
{
@ -154,7 +154,7 @@ SpriteBatch.prototype = {
if (this.drawingMesh)
{
this.indexBufferObjectForMesh.bind();
this.indexBufferObjectForMesh.updateResource(this.indexDataBuffer.buffer, 0)
this.indexBufferObjectForMesh.updateResource(this.indexDataBuffer.buffer, 0);
}
else
{
@ -271,7 +271,10 @@ SpriteBatch.prototype = {
vertexOffset = vertexDataBuffer.allocate(totalVertices * 6);
for (var index = 0, index0 = 0; index < length; index += 2)
var index;
var index0;
for (index = 0, index0 = 0; index < length; index += 2)
{
var x = vertices[index + 0];
var y = vertices[index + 1];
@ -288,7 +291,7 @@ SpriteBatch.prototype = {
var elementCount = this.elementCount;
for (var index = 0; index < indexLength; ++index)
for (index = 0; index < indexLength; ++index)
{
indexBuffer[elementCount + index] = indexOffset + indices[index];
}
@ -633,6 +636,6 @@ SpriteBatch.prototype = {
vertexBufferObjectF32[vertexOffset++] = alpha;
}
};
});
module.exports = SpriteBatch;

View file

@ -1,55 +1,56 @@
var DataBuffer32 = require('../../utils/DataBuffer32');
var DataBuffer16 = require('../../utils/DataBuffer16');
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
var PHASER_CONST = require('../../../../const');
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer16 = require('../../utils/DataBuffer16');
var DataBuffer32 = require('../../utils/DataBuffer32');
var PHASER_CONST = require('../../../../const');
var TexturedAndNormalizedTintedShader = require('../../shaders/TexturedAndNormalizedTintedShader');
var TransformMatrix = require('../../../../gameobjects/components/TransformMatrix');
var TileBatch = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
this.tempMatrix = new TransformMatrix();
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
var TileBatch = new Class({
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
initialize:
this.manager = manager;
this.dirty = false;
function TileBatch (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.maxSprites = null;
this.shader = null;
this.vertexBufferObject = null;
this.indexBufferObject = null;
this.vertexDataBuffer = null;
this.indexDataBuffer = null;
this.elementCount = 0;
this.currentTexture2D = null;
this.viewMatrixLocation = null;
this.tempMatrix = new TransformMatrix();
this.init(this.glContext);
};
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
TileBatch.prototype.constructor = TileBatch;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
TileBatch.prototype = {
this.manager = manager;
this.dirty = false;
this.init(this.glContext);
},
init: function (gl)
{
@ -111,6 +112,7 @@ TileBatch.prototype = {
shader.bind();
this.resize(this.width, this.height, this.game.config.resolution, shader);
}
this.indexBufferObject.bind();
this.vertexBufferObject.bind();
},
@ -132,8 +134,11 @@ TileBatch.prototype = {
this.bind(shader);
this.vertexBufferObject.updateResource(vertexDataBuffer.getUsedBufferAsFloat(), 0);
gl.drawElements(gl.TRIANGLES, this.elementCount, gl.UNSIGNED_SHORT, 0);
vertexDataBuffer.clear();
this.elementCount = 0;
if (renderTarget)
@ -144,9 +149,9 @@ TileBatch.prototype = {
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
var location = activeShader == this.shader ? this.viewMatrixLocation : activeShader.getUniformLocation('u_view_matrix');
this.width = width * resolution;
this.height = height * resolution;
this.setProjectionMatrix(activeShader, location);
@ -279,6 +284,6 @@ TileBatch.prototype = {
vertexBufferObjectF32[vertexOffset++] = alpha;
}
};
});
module.exports = TileBatch;

View file

@ -1,47 +1,47 @@
var DataBuffer32 = require('../../utils/DataBuffer32');
var Class = require('../../../../utils/Class');
var CONST = require('./const');
var DataBuffer16 = require('../../utils/DataBuffer16');
var DataBuffer32 = require('../../utils/DataBuffer32');
var PHASER_CONST = require('../../../../const');
var TilemapShader = require('../../shaders/TilemapShader');
var PHASER_CONST = require('../../../../const');
var CONST = require('./const');
var TilemapRenderer = new Class({
var TilemapRenderer = function (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.shader = null;
this.viewMatrixLocation = null;
initialize:
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
function TilemapRenderer (game, gl, manager)
{
this.game = game;
this.type = PHASER_CONST.WEBGL;
this.view = game.canvas;
this.resolution = game.config.resolution;
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.glContext = gl;
this.shader = null;
this.viewMatrixLocation = null;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
this.manager = manager;
this.dirty = false;
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
};
this.init(this.glContext);
};
this.manager = manager;
this.dirty = false;
TilemapRenderer.prototype.constructor = TilemapRenderer;
TilemapRenderer.prototype = {
this.init(this.glContext);
},
init: function (gl)
{
@ -94,7 +94,6 @@ TilemapRenderer.prototype = {
resize: function (width, height, resolution, shader)
{
var gl = this.glContext;
var activeShader = shader !== undefined ? shader : this.shader;
this.width = width * resolution;
@ -117,6 +116,7 @@ TilemapRenderer.prototype = {
this.shader = null;
}
};
});
module.exports = TilemapRenderer;

View file

@ -1,30 +1,35 @@
var Class = require('../../../utils/Class');
var IndexBuffer = function (gl, bufferObject)
{
this.gl = gl;
this.bufferTarget = gl.ELEMENT_ARRAY_BUFFER;
this.bufferObject = bufferObject;
};
var IndexBuffer = new Class({
IndexBuffer.prototype.constructor = IndexBuffer;
initialize:
IndexBuffer.prototype = {
function IndexBuffer (gl, bufferObject)
{
this.gl = gl;
this.bufferTarget = gl.ELEMENT_ARRAY_BUFFER;
this.bufferObject = bufferObject;
},
bind: function ()
{
var gl = this.gl;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufferObject);
return this;
},
updateResource: function (bufferData, offset)
{
var gl = this.gl;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufferObject);
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, offset, bufferData);
return this;
}
};
});
module.exports = IndexBuffer;

View file

@ -1,18 +1,19 @@
var Shader = function(name, gl, program, vertexShader, fragmentShader)
{
this.gl = gl;
this.program = program;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.name = name;
};
var Class = require('../../../utils/Class');
Shader.prototype.constructor = Shader;
var Shader = new Class({
/* For WebGL2 this won't be necessary */
Shader.prototype = {
initialize:
getUniformLocation: function(name)
function Shader (name, gl, program, vertexShader, fragmentShader)
{
this.gl = gl;
this.program = program;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.name = name;
},
getUniformLocation: function (name)
{
return this.gl.getUniformLocation(this.program, name);
},
@ -20,82 +21,103 @@ Shader.prototype = {
getAttribLocation: function (name)
{
return this.gl.getAttribLocation(this.program, name);
},
},
setConstantFloat1: function(location, x)
setConstantFloat1: function (location, x)
{
this.gl.useProgram(this.program);
this.gl.uniform1f(location, x);
return this;
},
setConstantFloat2: function(location, x, y)
setConstantFloat2: function (location, x, y)
{
this.gl.useProgram(this.program);
this.gl.uniform2f(location, x, y);
return this;
},
setConstantFloat3: function(location, x, y, z) {
setConstantFloat3: function (location, x, y, z)
{
this.gl.useProgram(this.program);
this.gl.uniform3f(location, x, y, z);
return this;
},
setConstantFloat4: function(location, x, y, z, w) {
setConstantFloat4: function (location, x, y, z, w)
{
this.gl.useProgram(this.program);
this.gl.uniform4f(location, x, y, z, w);
return this;
},
setConstantInt1: function(location, x) {
setConstantInt1: function (location, x)
{
this.gl.useProgram(this.program);
this.gl.uniform1i(location, x);
return this;
},
setConstantInt2: function(location, x, y) {
setConstantInt2: function (location, x, y)
{
this.gl.useProgram(this.program);
this.gl.uniform2i(location, x, y);
return this;
},
setConstantInt3: function(location, x, y, z) {
setConstantInt3: function (location, x, y, z)
{
this.gl.useProgram(this.program);
this.gl.uniform3i(location, x, y, z);
return this;
},
setConstantInt4: function(location, x, y, z, w) {
setConstantInt4: function (location, x, y, z, w)
{
this.gl.useProgram(this.program);
this.gl.uniform4i(location, x, y, z, w);
return this;
},
setConstantMatrix2x2: function(location, floatArray) {
setConstantMatrix2x2: function (location, floatArray)
{
this.gl.useProgram(this.program);
this.gl.uniformMatrix2fv(location, false, floatArray);
return this;
},
setConstantMatrix3x3: function(location, floatArray) {
setConstantMatrix3x3: function (location, floatArray)
{
this.gl.useProgram(this.program);
this.gl.uniformMatrix3fv(location, false, floatArray);
return this;
},
setConstantMatrix4x4: function(location, floatArray) {
setConstantMatrix4x4: function (location, floatArray)
{
this.gl.useProgram(this.program);
this.gl.uniformMatrix4fv(location, false, floatArray);
return this;
},
bind: function ()
{
this.gl.useProgram(this.program);
return this;
}
};
});
module.exports = Shader;

View file

@ -1,11 +1,17 @@
var Texture = function (texture, width, height)
{
this.texture = texture;
this.width = width;
this.height = height;
this.isRenderTexture = false;
};
var Class = require('../../../utils/Class');
Texture.prototype.constructor = Texture;
var Texture = new Class({
initialize:
function Texture (texture, width, height)
{
this.texture = texture;
this.width = width;
this.height = height;
this.isRenderTexture = false;
}
});
module.exports = Texture;

View file

@ -1,14 +1,16 @@
var VertexBuffer = function (gl, bufferObject)
{
this.gl = gl;
this.bufferTarget = gl.ARRAY_BUFFER;
this.bufferObject = bufferObject;
this.attributes = [];
};
var Class = require('../../../utils/Class');
VertexBuffer.prototype.constructor = VertexBuffer;
var VertexBuffer = new Class({
VertexBuffer.prototype = {
initialize:
function VertexBuffer (gl, bufferObject)
{
this.gl = gl;
this.bufferTarget = gl.ARRAY_BUFFER;
this.bufferObject = bufferObject;
this.attributes = [];
},
addAttribute: function (index, size, type, normalized, stride, offset)
{
@ -20,14 +22,17 @@ VertexBuffer.prototype = {
stride: stride,
offset: offset
});
return this;
},
updateResource: function (bufferData, offset)
{
var gl = this.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, this.bufferObject);
gl.bufferSubData(gl.ARRAY_BUFFER, offset, bufferData);
return this;
},
@ -39,25 +44,28 @@ VertexBuffer.prototype = {
var attributesLength = attributes.length;
gl.bindBuffer(gl.ARRAY_BUFFER, bufferObject);
for (var index = 0; index < attributesLength; ++index)
{
var element = attributes[index];
if (element !== undefined && element !== null)
if (element !== undefined && element !== null)
{
gl.enableVertexAttribArray(element.index);
gl.vertexAttribPointer(
element.index,
element.size,
element.type,
element.normalized,
element.stride,
element.index,
element.size,
element.type,
element.normalized,
element.stride,
element.offset
);
}
}
return this;
}
};
});
module.exports = VertexBuffer;

View file

@ -8,7 +8,7 @@ module.exports = {
frag: [
'precision mediump float;',
'uniform float time;',
'// Oldskool plasm shader. (c) Victor Korsun, bitekas@gmail.com; 1996-2013.',
'// Oldskool plasma shader. (c) Victor Korsun, bitekas@gmail.com; 1996-2013.',
'//',
'// Attribution-ShareAlike CC License.',
'//----------------',

View file

@ -1,42 +1,50 @@
var DataBuffer16 = function (byteSize)
{
this.wordLength = 0;
this.wordCapacity = byteSize / 2;
this.buffer = new ArrayBuffer(byteSize);
this.intView = new Int16Array(this.buffer);
this.uintView = new Uint16Array(this.buffer);
};
var Class = require('../../../utils/Class');
DataBuffer16.prototype.clear = function ()
{
this.wordLength = 0;
};
var DataBuffer16 = new Class({
DataBuffer16.prototype.getByteLength = function ()
{
return this.wordLength * 2;
};
initialize:
DataBuffer16.prototype.getByteCapacity = function ()
{
return this.buffer.byteLength;
};
function DataBuffer16 (byteSize)
{
this.wordLength = 0;
this.wordCapacity = byteSize / 2;
this.buffer = new ArrayBuffer(byteSize);
this.intView = new Int16Array(this.buffer);
this.uintView = new Uint16Array(this.buffer);
},
DataBuffer16.prototype.allocate = function (wordSize)
{
var currentLength = this.wordLength;
this.wordLength += wordSize;
return currentLength;
};
clear: function ()
{
this.wordLength = 0;
},
DataBuffer16.prototype.getUsedBufferAsShort = function ()
{
return this.intView.subarray(0, this.wordLength);
};
getByteLength: function ()
{
return this.wordLength * 2;
},
DataBuffer16.prototype.getUsedBufferAsWord = function ()
{
return this.uintView.subarray(0, this.wordLength);
};
getByteCapacity: function ()
{
return this.buffer.byteLength;
},
allocate: function (wordSize)
{
var currentLength = this.wordLength;
this.wordLength += wordSize;
return currentLength;
},
getUsedBufferAsShort: function ()
{
return this.intView.subarray(0, this.wordLength);
},
getUsedBufferAsWord: function ()
{
return this.uintView.subarray(0, this.wordLength);
}
});
module.exports = DataBuffer16;

View file

@ -1,48 +1,56 @@
var DataBuffer32 = function (byteSize)
{
this.dwordLength = 0;
this.dwordCapacity = byteSize / 4;
this.buffer = new ArrayBuffer(byteSize);
this.floatView = new Float32Array(this.buffer);
this.intView = new Int32Array(this.buffer);
this.uintView = new Uint32Array(this.buffer);
};
var Class = require('../../../utils/Class');
DataBuffer32.prototype.clear = function ()
{
this.dwordLength = 0;
};
var DataBuffer32 = new Class({
DataBuffer32.prototype.getByteLength = function ()
{
return this.dwordLength * 4;
};
initialize:
DataBuffer32.prototype.getByteCapacity = function ()
{
return this.buffer.byteLength;
};
function DataBuffer32 (byteSize)
{
this.dwordLength = 0;
this.dwordCapacity = byteSize / 4;
this.buffer = new ArrayBuffer(byteSize);
this.floatView = new Float32Array(this.buffer);
this.intView = new Int32Array(this.buffer);
this.uintView = new Uint32Array(this.buffer);
},
DataBuffer32.prototype.allocate = function (dwordSize)
{
var currentLength = this.dwordLength;
this.dwordLength += dwordSize;
return currentLength;
};
clear: function ()
{
this.dwordLength = 0;
},
DataBuffer32.prototype.getUsedBufferAsFloat = function ()
{
return this.floatView.subarray(0, this.dwordLength);
};
getByteLength: function ()
{
return this.dwordLength * 4;
},
DataBuffer32.prototype.getUsedBufferAsInt = function ()
{
return this.intView.subarray(0, this.dwordLength);
};
getByteCapacity: function ()
{
return this.buffer.byteLength;
},
DataBuffer32.prototype.getUsedBufferAsUint = function ()
{
return this.uintView.subarray(0, this.dwordLength);
};
allocate: function (dwordSize)
{
var currentLength = this.dwordLength;
this.dwordLength += dwordSize;
return currentLength;
},
getUsedBufferAsFloat: function ()
{
return this.floatView.subarray(0, this.dwordLength);
},
getUsedBufferAsInt: function ()
{
return this.intView.subarray(0, this.dwordLength);
},
getUsedBufferAsUint: function ()
{
return this.uintView.subarray(0, this.dwordLength);
}
});
module.exports = DataBuffer32;

View file

@ -1,5 +1,6 @@
var Between = require('../../math/Between');
var Class = require('../../utils/Class');
var GetValue = require('../../utils/object/GetValue');
// Phaser.Sound.Dynamic.FX
@ -22,116 +23,116 @@ var GetValue = require('../../utils/object/GetValue');
// reverb, //An array: [durationInSeconds, decayRateInSeconds, reverse]
// timeout //A number, in seconds, which is the maximum duration for sound effects
var FX = function (ctx, config)
{
this.audioContext = ctx;
var FX = new Class({
this.frequencyValue = GetValue(config, 'frequency', 200);
this.attack = GetValue(config, 'attack', 0);
this.decay = GetValue(config, 'decay', 1);
this.type = GetValue(config, 'type', 'sine');
this.volumeValue = GetValue(config, 'volume', 1);
this.panValue = GetValue(config, 'pan', 0);
this.wait = GetValue(config, 'wait', 0);
this.pitchBendAmount = GetValue(config, 'pitchBend', 0);
this.reverse = GetValue(config, 'reverse', false);
this.randomValue = GetValue(config, 'random', 0);
this.dissonance = GetValue(config, 'dissonance', 0);
this.echo = GetValue(config, 'echo', false);
this.echoDelay = GetValue(config, 'echo.delay', 0);
this.echoFeedback = GetValue(config, 'echo.feedback', 0);
this.echoFilter = GetValue(config, 'echo.filter', 0);
this.reverb = GetValue(config, 'reverb', false);
this.reverbDuration = GetValue(config, 'reverb.duration', 0);
this.reverbDecay = GetValue(config, 'reverb.decay', 0);
this.reverbReverse = GetValue(config, 'reverb.reverse', false);
this.timeout = GetValue(config, 'timeout', false);
initialize:
this.volume = ctx.createGain();
this.pan = (!ctx.createStereoPanner) ? ctx.createPanner() : ctx.createStereoPanner();
this.volume.connect(this.pan);
this.pan.connect(ctx.destination);
// Set the values
this.volume.gain.value = this.volumeValue;
if (!ctx.createStereoPanner)
function FX (ctx, config)
{
this.pan.setPosition(this.panValue, 0, 1 - Math.abs(this.panValue));
}
else
{
this.pan.pan.value = this.panValue;
}
this.audioContext = ctx;
// Create an oscillator, gain and pan nodes, and connect them together to the destination
this.frequencyValue = GetValue(config, 'frequency', 200);
this.attack = GetValue(config, 'attack', 0);
this.decay = GetValue(config, 'decay', 1);
this.type = GetValue(config, 'type', 'sine');
this.volumeValue = GetValue(config, 'volume', 1);
this.panValue = GetValue(config, 'pan', 0);
this.wait = GetValue(config, 'wait', 0);
this.pitchBendAmount = GetValue(config, 'pitchBend', 0);
this.reverse = GetValue(config, 'reverse', false);
this.randomValue = GetValue(config, 'random', 0);
this.dissonance = GetValue(config, 'dissonance', 0);
this.echo = GetValue(config, 'echo', false);
this.echoDelay = GetValue(config, 'echo.delay', 0);
this.echoFeedback = GetValue(config, 'echo.feedback', 0);
this.echoFilter = GetValue(config, 'echo.filter', 0);
this.reverb = GetValue(config, 'reverb', false);
this.reverbDuration = GetValue(config, 'reverb.duration', 0);
this.reverbDecay = GetValue(config, 'reverb.decay', 0);
this.reverbReverse = GetValue(config, 'reverb.reverse', false);
this.timeout = GetValue(config, 'timeout', false);
var oscillator = ctx.createOscillator();
this.volume = ctx.createGain();
this.pan = (!ctx.createStereoPanner) ? ctx.createPanner() : ctx.createStereoPanner();
oscillator.connect(this.volume);
oscillator.type = this.type;
this.volume.connect(this.pan);
this.pan.connect(ctx.destination);
// Optionally randomize the pitch if `randomValue` > 0.
// A random pitch is selected that's within the range specified by `frequencyValue`.
// The random pitch will be either above or below the target frequency.
// Set the values
if (this.randomValue > 0)
{
oscillator.frequency.value = Between(
this.frequencyValue - this.randomValue / 2,
this.frequencyValue + this.randomValue / 2
);
}
else
{
oscillator.frequency.value = this.frequencyValue;
}
this.volume.gain.value = this.volumeValue;
// Apply effects
if (!ctx.createStereoPanner)
{
this.pan.setPosition(this.panValue, 0, 1 - Math.abs(this.panValue));
}
else
{
this.pan.pan.value = this.panValue;
}
if (this.attack > 0)
{
this.fadeIn(this.volume);
}
// Create an oscillator, gain and pan nodes, and connect them together to the destination
this.fadeOut(this.volume);
var oscillator = ctx.createOscillator();
if (this.pitchBendAmount > 0)
{
this.pitchBend(oscillator);
}
oscillator.connect(this.volume);
oscillator.type = this.type;
if (this.echo)
{
this.addEcho(this.volume);
}
// Optionally randomize the pitch if `randomValue` > 0.
// A random pitch is selected that's within the range specified by `frequencyValue`.
// The random pitch will be either above or below the target frequency.
if (this.reverb)
{
this.addReverb(this.volume);
}
if (this.randomValue > 0)
{
oscillator.frequency.value = Between(
this.frequencyValue - this.randomValue / 2,
this.frequencyValue + this.randomValue / 2
);
}
else
{
oscillator.frequency.value = this.frequencyValue;
}
if (this.dissonance > 0)
{
this.addDissonance();
}
// Apply effects
this.play(oscillator);
if (this.attack > 0)
{
this.fadeIn(this.volume);
}
var _this = this;
this.fadeOut(this.volume);
oscillator.onended = function ()
{
_this.pan.disconnect();
_this.volume.disconnect();
};
};
if (this.pitchBendAmount > 0)
{
this.pitchBend(oscillator);
}
FX.prototype.constructor = FX;
if (this.echo)
{
this.addEcho(this.volume);
}
FX.prototype = {
if (this.reverb)
{
this.addReverb(this.volume);
}
if (this.dissonance > 0)
{
this.addDissonance();
}
this.play(oscillator);
var _this = this;
oscillator.onended = function ()
{
_this.pan.disconnect();
_this.volume.disconnect();
};
},
play: function (oscillator)
{
@ -325,6 +326,6 @@ FX.prototype = {
return impulse;
}
};
});
module.exports = FX;