phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
508 lines (439 loc) • 17.3 kB
JavaScript
var SubmitterSpriteGPULayer = require('../../../../../src/renderer/webgl/renderNodes/submitter/SubmitterSpriteGPULayer');
describe('SubmitterSpriteGPULayer', function ()
{
it('should be importable', function ()
{
expect(SubmitterSpriteGPULayer).toBeDefined();
});
describe('_completeLayout', function ()
{
var completeLayout;
beforeEach(function ()
{
completeLayout = SubmitterSpriteGPULayer.prototype._completeLayout;
});
it('should populate vertexBufferLayout from layoutSource', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex', type: 'UNSIGNED_BYTE' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
completeLayout.call({}, config);
expect(config.vertexBufferLayout.usage).toBe('STATIC_DRAW');
expect(config.vertexBufferLayout.count).toBe(4);
expect(Array.isArray(config.vertexBufferLayout.layout)).toBe(true);
});
it('should set default size to 1 when not provided', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex', type: 'UNSIGNED_BYTE' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
completeLayout.call({}, config);
expect(config.vertexBufferLayout.layout[0].size).toBe(1);
});
it('should set default type to FLOAT when not provided', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
completeLayout.call({}, config);
expect(config.vertexBufferLayout.layout[0].type).toBe('FLOAT');
});
it('should preserve explicit type in vertex layout', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex', type: 'UNSIGNED_BYTE' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
completeLayout.call({}, config);
expect(config.vertexBufferLayout.layout[0].type).toBe('UNSIGNED_BYTE');
});
it('should set default normalized to false when not provided', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
completeLayout.call({}, config);
expect(config.vertexBufferLayout.layout[0].normalized).toBe(false);
});
it('should preserve explicit normalized flag in vertex layout', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inColor', type: 'UNSIGNED_BYTE', normalized: true }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
completeLayout.call({}, config);
expect(config.vertexBufferLayout.layout[0].normalized).toBe(true);
});
it('should skip vertex layout attributes listed in vertexBufferLayoutRemove', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex' },
{ name: 'inRemoved' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
},
vertexBufferLayoutRemove: [ 'inRemoved' ]
};
completeLayout.call({}, config);
var names = config.vertexBufferLayout.layout
.filter(function (attr) { return attr !== undefined; })
.map(function (attr) { return attr.name; });
expect(names.indexOf('inRemoved')).toBe(-1);
expect(names.indexOf('inVertex')).not.toBe(-1);
});
it('should append extra vertex layout attributes from vertexBufferLayoutAdd', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
},
vertexBufferLayoutAdd: [
{ name: 'inExtra', size: 2, type: 'FLOAT' }
]
};
completeLayout.call({}, config);
var extraAttr = config.vertexBufferLayout.layout.find(function (attr)
{
return attr && attr.name === 'inExtra';
});
expect(extraAttr).toBeDefined();
expect(extraAttr.size).toBe(2);
expect(extraAttr.type).toBe('FLOAT');
});
it('should populate instanceBufferLayout from layoutSource', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: [
{ name: 'inPositionX', size: 4 },
{ name: 'inPositionY', size: 4 }
]
}
};
completeLayout.call({}, config);
expect(config.instanceBufferLayout.usage).toBe('DYNAMIC_DRAW');
expect(config.instanceBufferLayout.instanceDivisor).toBe(1);
expect(Array.isArray(config.instanceBufferLayout.layout)).toBe(true);
expect(config.instanceBufferLayout.layout.length).toBe(2);
});
it('should set defaults for instance layout attributes', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: [
{ name: 'inPositionX' }
]
}
};
completeLayout.call({}, config);
var attr = config.instanceBufferLayout.layout[0];
expect(attr.name).toBe('inPositionX');
expect(attr.size).toBe(1);
expect(attr.type).toBe('FLOAT');
expect(attr.normalized).toBe(false);
});
it('should preserve explicit size, type, and normalized in instance layout', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: [
{ name: 'inTintBL', size: 4, type: 'UNSIGNED_BYTE', normalized: true }
]
}
};
completeLayout.call({}, config);
var attr = config.instanceBufferLayout.layout[0];
expect(attr.size).toBe(4);
expect(attr.type).toBe('UNSIGNED_BYTE');
expect(attr.normalized).toBe(true);
});
it('should skip instance layout attributes listed in instanceBufferLayoutRemove', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: [
{ name: 'inPositionX', size: 4 },
{ name: 'inRemovable', size: 4 }
]
},
instanceBufferLayoutRemove: [ 'inRemovable' ]
};
completeLayout.call({}, config);
var names = config.instanceBufferLayout.layout
.filter(function (attr) { return attr !== undefined; })
.map(function (attr) { return attr.name; });
expect(names.indexOf('inRemovable')).toBe(-1);
expect(names.indexOf('inPositionX')).not.toBe(-1);
});
it('should append extra instance layout attributes from instanceBufferLayoutAdd', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: [
{ name: 'inPositionX', size: 4 }
]
},
instanceBufferLayoutAdd: [
{ name: 'inCustomData', size: 2, type: 'FLOAT', normalized: false }
]
};
completeLayout.call({}, config);
var extraAttr = config.instanceBufferLayout.layout.find(function (attr)
{
return attr && attr.name === 'inCustomData';
});
expect(extraAttr).toBeDefined();
expect(extraAttr.size).toBe(2);
expect(extraAttr.type).toBe('FLOAT');
expect(extraAttr.normalized).toBe(false);
});
it('should handle empty layout arrays without error', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 0,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
expect(function ()
{
completeLayout.call({}, config);
}).not.toThrow();
expect(config.vertexBufferLayout.layout.length).toBe(0);
expect(config.instanceBufferLayout.layout.length).toBe(0);
});
it('should handle missing vertexBufferLayoutRemove gracefully', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: [
{ name: 'inVertex' }
]
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
}
};
expect(function ()
{
completeLayout.call({}, config);
}).not.toThrow();
expect(config.vertexBufferLayout.layout[0].name).toBe('inVertex');
});
it('should use default size of 1 for instanceBufferLayoutAdd entries without size', function ()
{
var config = {
vertexBufferLayout: {
usage: 'STATIC_DRAW',
count: 4,
layout: []
},
instanceBufferLayout: {
usage: 'DYNAMIC_DRAW',
instanceDivisor: 1,
layout: []
},
instanceBufferLayoutAdd: [
{ name: 'inExtra' }
]
};
completeLayout.call({}, config);
var extraAttr = config.instanceBufferLayout.layout.find(function (attr)
{
return attr && attr.name === 'inExtra';
});
expect(extraAttr.size).toBe(1);
expect(extraAttr.type).toBe('FLOAT');
expect(extraAttr.normalized).toBe(false);
});
});
describe('defaultConfig', function ()
{
it('should have a default name', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.name).toBe('SubmitterSpriteGPULayer');
});
it('should have a default shaderName', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.shaderName).toBe('SpriteGPULayer');
});
it('should have default shader sources defined', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.vertexSource).toBeDefined();
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.fragmentSource).toBeDefined();
});
it('should have shaderAdditions as an array', function ()
{
expect(Array.isArray(SubmitterSpriteGPULayer.prototype.defaultConfig.shaderAdditions)).toBe(true);
});
it('should have a non-empty shaderAdditions list', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.shaderAdditions.length).toBeGreaterThan(0);
});
it('should have default count of 0', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.count).toBe(0);
});
it('should define instanceBufferLayout with instanceDivisor of 1', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.instanceBufferLayout.instanceDivisor).toBe(1);
});
it('should define vertexBufferLayout with count of 4', function ()
{
expect(SubmitterSpriteGPULayer.prototype.defaultConfig.vertexBufferLayout.count).toBe(4);
});
it('should include inVertex attribute in vertexBufferLayout', function ()
{
var layout = SubmitterSpriteGPULayer.prototype.defaultConfig.vertexBufferLayout.layout;
var inVertex = layout.find(function (attr) { return attr.name === 'inVertex'; });
expect(inVertex).toBeDefined();
expect(inVertex.type).toBe('UNSIGNED_BYTE');
});
it('should include expected attributes in instanceBufferLayout', function ()
{
var layout = SubmitterSpriteGPULayer.prototype.defaultConfig.instanceBufferLayout.layout;
var names = layout.map(function (attr) { return attr.name; });
expect(names).toContain('inPositionX');
expect(names).toContain('inPositionY');
expect(names).toContain('inRotation');
expect(names).toContain('inScaleX');
expect(names).toContain('inScaleY');
expect(names).toContain('inAlpha');
expect(names).toContain('inFrame');
});
it('should have tint attributes with UNSIGNED_BYTE type and normalized true', function ()
{
var layout = SubmitterSpriteGPULayer.prototype.defaultConfig.instanceBufferLayout.layout;
var tintBL = layout.find(function (attr) { return attr.name === 'inTintBL'; });
expect(tintBL).toBeDefined();
expect(tintBL.type).toBe('UNSIGNED_BYTE');
expect(tintBL.normalized).toBe(true);
});
});
});