2017-07-04 13:48:18 +00:00
|
|
|
var Class = require('../../utils/Class');
|
|
|
|
var CONST = require('../../const');
|
2018-01-20 04:05:56 +00:00
|
|
|
var WebGLSnapshot = require('../snapshot/WebGLSnapshot');
|
|
|
|
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
|
2018-01-24 03:57:33 +00:00
|
|
|
var Utils = require('./Utils');
|
2018-01-17 21:25:43 +00:00
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
// Default Pipelines
|
2018-01-22 22:51:15 +00:00
|
|
|
var TextureTintPipeline = require('./pipelines/TextureTintPipeline');
|
|
|
|
var FlatTintPipeline = require('./pipelines/FlatTintPipeline');
|
2018-01-25 18:43:19 +00:00
|
|
|
var BitmapMaskPipeline = require('./pipelines/BitmapMaskPipeline');
|
2018-01-29 21:46:48 +00:00
|
|
|
var ForwardDiffuseLightPipeline = require('./pipelines/ForwardDiffuseLightPipeline');
|
2018-01-22 21:21:47 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
var WebGLRenderer = new Class({
|
2016-12-07 02:28:22 +00:00
|
|
|
|
2017-07-04 13:48:18 +00:00
|
|
|
initialize:
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
function WebGLRenderer (game)
|
2016-12-07 02:28:22 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
var renderer = this;
|
|
|
|
var config = {
|
|
|
|
backgroundColor: game.config.backgroundColor,
|
|
|
|
contextCreation: {
|
|
|
|
alpha: false,
|
|
|
|
depth: false, // enable when 3D is added in the future
|
|
|
|
antialias: true,
|
|
|
|
premultipliedAlpha: true,
|
|
|
|
stencil: true,
|
|
|
|
preserveDrawingBuffer: false,
|
|
|
|
failIfMajorPerformanceCaveat: false
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-07-04 13:48:18 +00:00
|
|
|
this.game = game;
|
|
|
|
this.type = CONST.WEBGL;
|
|
|
|
this.width = game.config.width * game.config.resolution;
|
|
|
|
this.height = game.config.height * game.config.resolution;
|
2018-01-17 21:25:43 +00:00
|
|
|
this.canvas = game.canvas;
|
2018-01-24 00:40:20 +00:00
|
|
|
this.lostContextCallbacks = [];
|
|
|
|
this.restoredContextCallbacks = [];
|
2018-01-17 21:25:43 +00:00
|
|
|
this.blendModes = [];
|
|
|
|
this.contextLost = false;
|
|
|
|
this.autoResize = false;
|
|
|
|
this.pipelines = null;
|
2018-01-20 04:05:56 +00:00
|
|
|
this.snapshotState = {
|
|
|
|
callback: null,
|
|
|
|
type: null,
|
|
|
|
encoder: null
|
|
|
|
};
|
2017-09-13 19:11:40 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
for (var i = 0; i <= 16; i++)
|
|
|
|
{
|
|
|
|
this.blendModes.push({ func: [ WebGLRenderingContext.ONE, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA ], equation: WebGLRenderingContext.FUNC_ADD });
|
|
|
|
}
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.blendModes[1].func = [ WebGLRenderingContext.ONE, WebGLRenderingContext.DST_ALPHA ];
|
|
|
|
this.blendModes[2].func = [ WebGLRenderingContext.DST_COLOR, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA ];
|
|
|
|
this.blendModes[3].func = [ WebGLRenderingContext.ONE, WebGLRenderingContext.ONE_MINUS_SRC_COLOR ];
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
// Intenal Renderer State (Textures, Framebuffers, Pipelines, Buffers, etc)
|
|
|
|
this.currentTextures = new Array(16);
|
|
|
|
this.currentFramebuffer = null;
|
|
|
|
this.currentPipeline = null;
|
2018-01-22 21:21:47 +00:00
|
|
|
this.currentProgram = null;
|
2018-01-17 21:25:43 +00:00
|
|
|
this.currentVertexBuffer = null;
|
|
|
|
this.currentIndexBuffer = null;
|
2018-01-22 21:21:47 +00:00
|
|
|
this.currentBlendMode = Infinity;
|
2018-01-24 18:55:23 +00:00
|
|
|
this.currentScissorEnabled = false;
|
|
|
|
this.currentScissor = new Uint32Array([0, 0, this.width, this.height]);
|
|
|
|
this.currentScissorIdx = 0;
|
|
|
|
this.scissorStack = new Uint32Array(4 * 1000);
|
2018-01-17 21:25:43 +00:00
|
|
|
|
|
|
|
// Setup context lost and restore event listeners
|
|
|
|
this.canvas.addEventListener('webglcontextlost', function (event) {
|
|
|
|
renderer.contextLost = true;
|
|
|
|
event.preventDefault();
|
2018-01-24 00:40:20 +00:00
|
|
|
for (var index = 0; index < renderer.lostContextCallbacks.length; ++index)
|
|
|
|
{
|
|
|
|
var callback = renderer.lostContextCallbacks[index];
|
|
|
|
callback[0].call(callback[1], renderer);
|
|
|
|
}
|
2018-01-17 21:25:43 +00:00
|
|
|
}, false);
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.canvas.addEventListener('webglcontextrestored', function (event) {
|
|
|
|
renderer.contextLost = false;
|
|
|
|
renderer.init(config);
|
2018-01-24 00:40:20 +00:00
|
|
|
for (var index = 0; index < renderer.restoredContextCallbacks.length; ++index)
|
|
|
|
{
|
|
|
|
var callback = renderer.restoredContextCallbacks[index];
|
|
|
|
callback[0].call(callback[1], renderer);
|
|
|
|
}
|
2018-01-17 21:25:43 +00:00
|
|
|
}, false);
|
|
|
|
|
|
|
|
// This are initialized post context creation
|
2017-07-04 13:48:18 +00:00
|
|
|
this.gl = null;
|
2018-01-17 21:25:43 +00:00
|
|
|
this.supportedExtensions = null;
|
|
|
|
this.extensions = {};
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.init(config);
|
2017-07-04 13:48:18 +00:00
|
|
|
},
|
2017-01-25 12:02:18 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
init: function (config)
|
2017-07-04 13:48:18 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
var canvas = this.canvas;
|
|
|
|
var clearColor = config.backgroundColor;
|
|
|
|
var gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation);
|
|
|
|
|
|
|
|
if (!gl)
|
2016-12-07 02:28:22 +00:00
|
|
|
{
|
|
|
|
this.contextLost = true;
|
2018-01-10 20:03:01 +00:00
|
|
|
throw new Error('This browser does not support WebGL. Try using the Canvas pipeline.');
|
2016-12-07 02:28:22 +00:00
|
|
|
}
|
2017-09-13 19:11:40 +00:00
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
this.gl = gl;
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
// Load supported extensions
|
|
|
|
this.supportedExtensions = gl.getSupportedExtensions();
|
2017-09-13 19:11:40 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
// Setup initial WebGL state
|
2016-12-07 02:28:22 +00:00
|
|
|
gl.disable(gl.DEPTH_TEST);
|
|
|
|
gl.disable(gl.CULL_FACE);
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.disable(gl.SCISSOR_TEST);
|
2016-12-07 02:28:22 +00:00
|
|
|
gl.enable(gl.BLEND);
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, 1.0);
|
2017-08-03 01:09:59 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
// Initialize all textures to null
|
|
|
|
for (var index = 0; index < this.currentTextures.length; ++index)
|
2017-08-03 01:09:59 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
this.currentTextures[index] = null;
|
2017-08-03 01:09:59 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
// Clear previous pipelines and reload default ones
|
|
|
|
this.pipelines = {};
|
2017-08-03 01:09:59 +00:00
|
|
|
|
2018-01-22 22:51:15 +00:00
|
|
|
this.addPipeline('TextureTintPipeline', new TextureTintPipeline(this.game, gl, this));
|
|
|
|
this.addPipeline('FlatTintPipeline', new FlatTintPipeline(this.game, gl, this));
|
2018-01-25 18:43:19 +00:00
|
|
|
this.addPipeline('BitmapMaskPipeline', new BitmapMaskPipeline(this.game, gl, this));
|
2018-01-30 03:38:31 +00:00
|
|
|
this.addPipeline('Light2D', new ForwardDiffuseLightPipeline(this.game, gl, this));
|
2018-01-25 18:43:19 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.setBlendMode(CONST.BlendModes.NORMAL);
|
|
|
|
this.resize(this.width, this.height, this.game.config.resolution);
|
|
|
|
|
|
|
|
return this;
|
2017-08-03 01:09:59 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
resize: function (width, height, resolution)
|
2017-08-03 01:09:59 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
var gl = this.gl;
|
2018-01-22 21:21:47 +00:00
|
|
|
var pipelines = this.pipelines;
|
2017-08-03 01:09:59 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.width = width * resolution;
|
|
|
|
this.height = height * resolution;
|
|
|
|
|
|
|
|
this.canvas.width = this.width;
|
|
|
|
this.canvas.height = this.height;
|
2017-08-03 01:09:59 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (this.autoResize)
|
2017-08-03 01:09:59 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
this.canvas.style.width = (this.width / resolution) + 'px';
|
|
|
|
this.canvas.style.height = (this.height / resolution) + 'px';
|
2017-08-03 01:09:59 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.viewport(0, 0, this.width, this.height);
|
2017-08-03 01:09:59 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
// Update all registered pipelines
|
2018-01-20 04:05:56 +00:00
|
|
|
for (var pipelineName in pipelines)
|
|
|
|
{
|
2018-01-22 21:21:47 +00:00
|
|
|
pipelines[pipelineName].resize(width, height, resolution);
|
2018-01-20 04:05:56 +00:00
|
|
|
}
|
2017-08-10 04:17:58 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-09-13 19:43:34 +00:00
|
|
|
},
|
|
|
|
|
2018-01-24 00:40:20 +00:00
|
|
|
onContextRestored: function (callback, target)
|
|
|
|
{
|
|
|
|
this.restoredContextCallbacks.push([callback, target]);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
onContextLost: function (callback, target)
|
|
|
|
{
|
|
|
|
this.lostContextCallbacks.push([callback, target]);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
hasExtension: function (extensionName)
|
2017-09-13 19:43:34 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
return this.supportedExtensions ? this.supportedExtensions.indexOf(extensionName) : false;
|
2017-09-13 19:43:34 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
getExtension: function (extensionName)
|
2017-01-19 23:20:36 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
if (!this.hasExtension(extensionName)) return null;
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (!(extensionName in this.extensions))
|
2017-01-19 23:20:36 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
this.extensions[extensionName] = this.gl.getExtension(extensionName);
|
2017-01-19 23:20:36 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this.extensions[extensionName];
|
2017-01-19 23:20:36 +00:00
|
|
|
},
|
|
|
|
|
2018-01-20 04:05:56 +00:00
|
|
|
flush: function ()
|
|
|
|
{
|
|
|
|
if (this.currentPipeline)
|
|
|
|
{
|
|
|
|
this.currentPipeline.flush();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
/* Renderer State Manipulation Functions */
|
2017-01-19 17:53:20 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
hasPipeline: function (pipelineName)
|
2017-01-19 22:43:41 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
return (pipelineName in this.pipelines);
|
2017-04-07 01:49:15 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
getPipeline: function (pipelineName)
|
2017-04-07 01:49:15 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
if (this.hasPipeline(pipelineName)) return this.pipelines[pipelineName];
|
|
|
|
return null;
|
2017-01-19 22:43:41 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
removePipeline: function (pipelineName)
|
2016-12-07 02:28:22 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
delete this.pipelines[pipelineName];
|
|
|
|
return this;
|
2016-12-07 02:28:22 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
addPipeline: function (pipelineName, pipelineInstance)
|
2016-12-07 02:28:22 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
if (!this.hasPipeline(pipelineName)) this.pipelines[pipelineName] = pipelineInstance;
|
|
|
|
else console.warn('Pipeline', pipelineName, ' already exists.');
|
2017-06-08 16:15:02 +00:00
|
|
|
|
2018-01-30 22:46:43 +00:00
|
|
|
pipelineInstance.name = pipelineName;
|
2018-01-17 21:25:43 +00:00
|
|
|
this.pipelines[pipelineName].resize(this.width, this.height, this.game.config.resolution);
|
2016-12-07 02:28:22 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-01-25 17:10:19 +00:00
|
|
|
},
|
|
|
|
|
2018-01-24 18:55:23 +00:00
|
|
|
setScissor: function (x, y, w, h)
|
2018-01-23 23:36:49 +00:00
|
|
|
{
|
|
|
|
var gl = this.gl;
|
2018-01-24 18:55:23 +00:00
|
|
|
var currentScissor = this.currentScissor;
|
|
|
|
var enabled = (x == 0 && y == 0 && w == gl.canvas.width && h == gl.canvas.height && w >= 0 && h >= 0);
|
|
|
|
|
|
|
|
if (currentScissor[0] !== x ||
|
|
|
|
currentScissor[1] !== y ||
|
|
|
|
currentScissor[2] !== w ||
|
|
|
|
currentScissor[3] !== h)
|
2018-01-23 23:36:49 +00:00
|
|
|
{
|
2018-01-24 03:57:33 +00:00
|
|
|
this.flush();
|
2018-01-23 23:36:49 +00:00
|
|
|
}
|
|
|
|
|
2018-01-24 18:55:23 +00:00
|
|
|
currentScissor[0] = x;
|
|
|
|
currentScissor[1] = y;
|
|
|
|
currentScissor[2] = w;
|
|
|
|
currentScissor[3] = h;
|
2018-01-23 23:36:49 +00:00
|
|
|
|
2018-01-24 18:55:23 +00:00
|
|
|
this.currentScissorEnabled = enabled;
|
2018-01-23 23:36:49 +00:00
|
|
|
|
2018-01-24 18:55:23 +00:00
|
|
|
if (enabled)
|
2018-01-23 23:36:49 +00:00
|
|
|
{
|
|
|
|
gl.disable(gl.SCISSOR_TEST);
|
2018-01-24 18:55:23 +00:00
|
|
|
return;
|
2018-01-23 23:36:49 +00:00
|
|
|
}
|
2018-01-24 18:55:23 +00:00
|
|
|
|
|
|
|
gl.enable(gl.SCISSOR_TEST);
|
|
|
|
gl.scissor(x, (gl.drawingBufferHeight - y - h), w, h);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
pushScissor: function (x, y, w, h)
|
|
|
|
{
|
|
|
|
var scissorStack = this.scissorStack;
|
|
|
|
var stackIndex = this.currentScissorIdx;
|
|
|
|
var currentScissor = this.currentScissor;
|
|
|
|
|
|
|
|
scissorStack[stackIndex + 0] = currentScissor[0];
|
|
|
|
scissorStack[stackIndex + 1] = currentScissor[1];
|
|
|
|
scissorStack[stackIndex + 2] = currentScissor[2];
|
|
|
|
scissorStack[stackIndex + 3] = currentScissor[3];
|
|
|
|
|
|
|
|
this.currentScissorIdx += 4;
|
|
|
|
this.setScissor(x, y, w, h);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
popScissor: function ()
|
|
|
|
{
|
|
|
|
var scissorStack = this.scissorStack;
|
|
|
|
var stackIndex = this.currentScissorIdx - 4;
|
|
|
|
|
|
|
|
var x = scissorStack[stackIndex + 0];
|
|
|
|
var y = scissorStack[stackIndex + 1];
|
|
|
|
var w = scissorStack[stackIndex + 2];
|
|
|
|
var h = scissorStack[stackIndex + 3];
|
|
|
|
|
|
|
|
this.currentScissorIdx = stackIndex;
|
|
|
|
this.setScissor(x, y, w, h);
|
|
|
|
|
|
|
|
return this;
|
2018-01-23 23:36:49 +00:00
|
|
|
},
|
|
|
|
|
2018-01-30 03:38:31 +00:00
|
|
|
setPipeline: function (pipelineInstance)
|
2018-01-20 04:05:56 +00:00
|
|
|
{
|
2018-01-25 05:26:14 +00:00
|
|
|
if (this.currentPipeline !== pipelineInstance ||
|
2018-01-30 03:38:31 +00:00
|
|
|
this.currentPipeline.vertexBuffer !== this.currentVertexBuffer ||
|
|
|
|
this.currentPipeline.program !== this.currentProgram)
|
2018-01-20 04:05:56 +00:00
|
|
|
{
|
2018-01-24 03:08:14 +00:00
|
|
|
this.flush();
|
2018-01-23 16:38:58 +00:00
|
|
|
this.currentPipeline = pipelineInstance;
|
2018-01-30 03:38:31 +00:00
|
|
|
this.currentPipeline.bind();
|
2018-01-20 04:05:56 +00:00
|
|
|
}
|
|
|
|
|
2018-01-25 05:26:14 +00:00
|
|
|
this.currentPipeline.onBind();
|
|
|
|
|
2018-01-23 19:29:47 +00:00
|
|
|
return this.currentPipeline;
|
2018-01-20 04:05:56 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
setBlendMode: function (blendModeId)
|
2017-01-25 17:10:19 +00:00
|
|
|
{
|
2017-01-31 23:06:13 +00:00
|
|
|
var gl = this.gl;
|
2018-01-17 21:25:43 +00:00
|
|
|
var blendMode = this.blendModes[blendModeId];
|
2017-02-07 16:12:20 +00:00
|
|
|
|
2018-01-25 01:10:30 +00:00
|
|
|
if (blendModeId !== CONST.BlendModes.SKIP_CHECK &&
|
|
|
|
this.currentBlendMode !== blendModeId)
|
2017-01-19 17:53:20 +00:00
|
|
|
{
|
2018-01-20 04:05:56 +00:00
|
|
|
this.flush();
|
2017-12-15 04:07:16 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.enable(gl.BLEND);
|
|
|
|
gl.blendEquation(blendMode.equation);
|
2017-06-08 16:15:02 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (blendMode.func.length > 2)
|
2017-11-06 22:12:19 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.blendFuncSeparate(blendMode.func[0], blendMode.func[1], blendMode.func[2], blendMode.func[3]);
|
2017-11-06 22:12:19 +00:00
|
|
|
}
|
2018-01-17 21:25:43 +00:00
|
|
|
else
|
2017-11-06 22:12:19 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.blendFunc(blendMode.func[0], blendMode.func[1]);
|
2017-11-06 22:12:19 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.currentBlendMode = blendModeId;
|
2017-02-10 00:48:32 +00:00
|
|
|
}
|
2017-06-08 16:15:02 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-02-07 19:30:50 +00:00
|
|
|
},
|
2016-12-07 02:28:22 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
setTexture2D: function (texture, textureUnit)
|
2017-02-07 19:30:50 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
var gl = this.gl;
|
2017-05-16 19:15:01 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (texture !== this.currentTextures[textureUnit])
|
2017-05-16 19:15:01 +00:00
|
|
|
{
|
2018-01-23 19:29:47 +00:00
|
|
|
this.flush();
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.activeTexture(gl.TEXTURE0 + textureUnit);
|
|
|
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
2017-05-16 19:15:01 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
this.currentTextures[textureUnit] = texture;
|
|
|
|
}
|
2016-12-07 02:28:22 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-05-16 19:15:01 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
setFramebuffer: function (framebuffer)
|
2017-01-23 21:42:47 +00:00
|
|
|
{
|
2017-12-01 21:55:27 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (framebuffer !== this.currentFramebuffer)
|
2017-10-17 03:17:28 +00:00
|
|
|
{
|
2018-01-23 19:29:47 +00:00
|
|
|
this.flush();
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
2018-01-25 05:26:14 +00:00
|
|
|
this.currentFramebuffer = framebuffer;
|
2017-10-17 03:17:28 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-02-13 15:27:32 +00:00
|
|
|
},
|
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
setProgram: function (program)
|
|
|
|
{
|
|
|
|
var gl = this.gl;
|
|
|
|
|
|
|
|
if (program !== this.currentProgram)
|
|
|
|
{
|
2018-01-23 19:29:47 +00:00
|
|
|
this.flush();
|
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
gl.useProgram(program);
|
2018-01-25 05:26:14 +00:00
|
|
|
this.currentProgram = program;
|
2018-01-22 21:21:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
setVertexBuffer: function (vertexBuffer)
|
2017-02-13 15:27:32 +00:00
|
|
|
{
|
2018-01-17 21:25:43 +00:00
|
|
|
var gl = this.gl;
|
2017-06-08 16:15:02 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (vertexBuffer !== this.currentVertexBuffer)
|
2017-02-13 15:27:32 +00:00
|
|
|
{
|
2018-01-23 19:29:47 +00:00
|
|
|
this.flush();
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
2018-01-25 05:26:14 +00:00
|
|
|
this.currentVertexBuffer = vertexBuffer;
|
2017-02-13 15:27:32 +00:00
|
|
|
}
|
2017-06-08 16:15:02 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-03-21 20:45:57 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
setIndexBuffer: function (indexBuffer)
|
2017-05-20 01:16:45 +00:00
|
|
|
{
|
|
|
|
var gl = this.gl;
|
2017-06-08 16:15:02 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
if (indexBuffer !== this.currentIndexBuffer)
|
2017-06-08 16:15:02 +00:00
|
|
|
{
|
2018-01-23 19:29:47 +00:00
|
|
|
this.flush();
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
2018-01-25 05:26:14 +00:00
|
|
|
this.currentIndexBuffer = indexBuffer;
|
2017-06-08 16:15:02 +00:00
|
|
|
}
|
2017-05-20 01:16:45 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
return this;
|
2017-05-20 01:16:45 +00:00
|
|
|
},
|
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
/* Renderer Resource Creation Functions */
|
2018-01-24 00:40:20 +00:00
|
|
|
createTextureFromSource: function (source, width, height, scaleMode)
|
2018-01-20 04:05:56 +00:00
|
|
|
{
|
|
|
|
var gl = this.gl;
|
|
|
|
var filter = gl.NEAREST;
|
|
|
|
var wrap = gl.CLAMP_TO_EDGE;
|
2018-01-24 00:40:20 +00:00
|
|
|
var texture = null;
|
2018-01-20 04:05:56 +00:00
|
|
|
|
|
|
|
width = source ? source.width : width;
|
|
|
|
height = source ? source.height : height;
|
|
|
|
|
|
|
|
if (IsSizePowerOfTwo(width, height))
|
|
|
|
{
|
|
|
|
wrap = gl.REPEAT;
|
|
|
|
}
|
|
|
|
|
2018-01-24 00:40:20 +00:00
|
|
|
if (scaleMode === CONST.ScaleModes.LINEAR)
|
2018-01-20 04:05:56 +00:00
|
|
|
{
|
2018-01-24 00:40:20 +00:00
|
|
|
filter = gl.LINEAR;
|
|
|
|
}
|
|
|
|
else if (scaleMode === CONST.ScaleModes.NEAREST || this.game.config.pixelArt)
|
|
|
|
{
|
|
|
|
filter = gl.NEAREST;
|
|
|
|
}
|
2018-01-20 04:05:56 +00:00
|
|
|
|
2018-01-24 00:40:20 +00:00
|
|
|
if (!source && typeof width === 'number' && typeof height === 'number')
|
|
|
|
{
|
|
|
|
texture = this.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
texture = this.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, source);
|
2018-01-20 04:05:56 +00:00
|
|
|
}
|
|
|
|
|
2018-01-24 00:40:20 +00:00
|
|
|
return texture;
|
2018-01-20 04:05:56 +00:00
|
|
|
},
|
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
createTexture2D: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma)
|
2018-01-17 21:25:43 +00:00
|
|
|
{
|
2018-01-20 00:37:52 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var texture = gl.createTexture();
|
|
|
|
|
|
|
|
pma = (pma === undefined || pma === null) ? true : pma;
|
|
|
|
|
|
|
|
this.setTexture2D(texture, 0);
|
2018-01-17 21:25:43 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
|
|
|
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, pma);
|
|
|
|
|
|
|
|
if (pixels === null || pixels === undefined)
|
|
|
|
{
|
|
|
|
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels);
|
|
|
|
width = pixels.width;
|
|
|
|
height = pixels.height;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setTexture2D(null, 0);
|
|
|
|
|
|
|
|
texture.isAlphaPremultiplied = pma;
|
|
|
|
texture.isRenderTexture = false;
|
|
|
|
texture.width = width;
|
|
|
|
texture.height = height;
|
|
|
|
|
|
|
|
return texture;
|
2018-01-17 21:25:43 +00:00
|
|
|
},
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
createFramebuffer: function (width, height, renderTexture, addDepthStencilBuffer)
|
2018-01-17 21:25:43 +00:00
|
|
|
{
|
2018-01-20 00:37:52 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var framebuffer = gl.createFramebuffer();
|
|
|
|
var complete = 0;
|
|
|
|
|
|
|
|
this.setFramebuffer(framebuffer);
|
|
|
|
|
|
|
|
if (addDepthStencilBuffer)
|
|
|
|
{
|
|
|
|
var depthStencilBuffer = gl.createRenderbuffer();
|
|
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
|
|
|
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
|
|
|
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderTexture.isRenderTexture = true;
|
|
|
|
renderTexture.isAlphaPremultiplied = false;
|
|
|
|
|
|
|
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture, 0);
|
|
|
|
|
|
|
|
complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
|
|
|
|
|
|
if (complete !== gl.FRAMEBUFFER_COMPLETE)
|
|
|
|
{
|
|
|
|
var errors = {
|
|
|
|
36054: 'Incomplete Attachment',
|
|
|
|
36055: 'Missing Attachment',
|
|
|
|
36057: 'Incomplete Dimensions',
|
|
|
|
36061: 'Framebuffer Unsupported'
|
|
|
|
};
|
|
|
|
throw new Error('Framebuffer incomplete. Framebuffer status: ' + errors[complete]);
|
|
|
|
}
|
|
|
|
|
|
|
|
framebuffer.renderTexture = renderTexture;
|
2017-07-04 13:48:18 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
this.setFramebuffer(null);
|
|
|
|
|
|
|
|
return framebuffer;
|
2018-01-17 21:25:43 +00:00
|
|
|
},
|
2017-07-12 20:55:57 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
createProgram: function (vertexShader, fragmentShader)
|
2018-01-17 21:25:43 +00:00
|
|
|
{
|
2018-01-20 00:37:52 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var program = gl.createProgram();
|
|
|
|
var vs = gl.createShader(gl.VERTEX_SHADER);
|
|
|
|
var fs = gl.createShader(gl.FRAGMENT_SHADER);
|
|
|
|
|
|
|
|
gl.shaderSource(vs, vertexShader);
|
|
|
|
gl.shaderSource(fs, fragmentShader);
|
|
|
|
gl.compileShader(vs);
|
|
|
|
gl.compileShader(fs);
|
|
|
|
|
|
|
|
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
|
|
|
|
{
|
2018-01-25 18:43:19 +00:00
|
|
|
throw new Error('Failed to compile Vertex Shader:\n' + gl.getShaderInfoLog(vs));
|
2018-01-20 00:37:52 +00:00
|
|
|
}
|
|
|
|
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
|
|
|
|
{
|
2018-01-25 18:43:19 +00:00
|
|
|
throw new Error('Failed to compile Fragment Shader:\n' + gl.getShaderInfoLog(fs));
|
2018-01-20 00:37:52 +00:00
|
|
|
}
|
2017-08-03 20:02:57 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
gl.attachShader(program, vs);
|
|
|
|
gl.attachShader(program, fs);
|
|
|
|
gl.linkProgram(program);
|
|
|
|
|
|
|
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
|
|
|
|
{
|
2018-01-25 18:43:19 +00:00
|
|
|
throw new Error('Failed to link program:\n' + gl.getProgramInfoLog(program));
|
2018-01-20 00:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return program;
|
2018-01-17 21:25:43 +00:00
|
|
|
},
|
2017-03-21 20:45:57 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
createVertexBuffer: function (initialDataOrSize, bufferUsage)
|
2018-01-17 21:25:43 +00:00
|
|
|
{
|
2018-01-20 00:37:52 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var vertexBuffer = gl.createBuffer();
|
2017-03-21 20:45:57 +00:00
|
|
|
|
2018-01-20 00:37:52 +00:00
|
|
|
this.setVertexBuffer(vertexBuffer);
|
|
|
|
gl.bufferData(gl.ARRAY_BUFFER, initialDataOrSize, bufferUsage);
|
|
|
|
this.setVertexBuffer(null);
|
|
|
|
|
|
|
|
return vertexBuffer;
|
2017-07-04 13:48:18 +00:00
|
|
|
},
|
|
|
|
|
2018-01-25 00:15:51 +00:00
|
|
|
createIndexBuffer: function (initialDataOrSize, bufferUsage)
|
2017-07-04 13:48:18 +00:00
|
|
|
{
|
2018-01-20 00:37:52 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var indexBuffer = gl.createBuffer();
|
|
|
|
|
|
|
|
this.setIndexBuffer(indexBuffer);
|
|
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, initialDataOrSize, bufferUsage);
|
|
|
|
this.setIndexBuffer(null);
|
|
|
|
|
|
|
|
return indexBuffer;
|
2018-01-20 04:05:56 +00:00
|
|
|
},
|
|
|
|
|
2018-01-25 00:15:51 +00:00
|
|
|
deleteTexture: function (texture)
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
deleteFramebuffer: function (framebuffer)
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
deleteProgram: function (program)
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
deleteBuffer: function (vertexBuffer)
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-20 04:05:56 +00:00
|
|
|
/* Rendering Functions */
|
2018-01-24 03:57:33 +00:00
|
|
|
preRenderCamera: function (camera)
|
|
|
|
{
|
2018-01-24 18:55:23 +00:00
|
|
|
this.pushScissor(camera.x, camera.y, camera.width, camera.height);
|
2018-01-24 03:57:33 +00:00
|
|
|
|
|
|
|
if (camera.backgroundColor.alphaGL > 0)
|
|
|
|
{
|
|
|
|
var color = camera.backgroundColor;
|
|
|
|
var FlatTintPipeline = this.pipelines.FlatTintPipeline;
|
|
|
|
|
|
|
|
FlatTintPipeline.batchFillRect(
|
|
|
|
0, 0, 1, 1, 0,
|
|
|
|
camera.x, camera.y, camera.width, camera.height,
|
|
|
|
Utils.getTintFromFloats(color.redGL, color.greenGL, color.blueGL, 1.0),
|
|
|
|
color.alphaGL,
|
|
|
|
1, 0, 0, 1, 0, 0,
|
|
|
|
[1, 0, 0, 1, 0, 0]
|
|
|
|
);
|
|
|
|
|
|
|
|
FlatTintPipeline.flush();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
postRenderCamera: function (camera)
|
|
|
|
{
|
|
|
|
if (camera._fadeAlpha > 0 || camera._flashAlpha > 0)
|
|
|
|
{
|
|
|
|
var FlatTintPipeline = this.pipelines.FlatTintPipeline;
|
|
|
|
|
|
|
|
// Fade
|
|
|
|
FlatTintPipeline.batchFillRect(
|
|
|
|
0, 0, 1, 1, 0,
|
|
|
|
camera.x, camera.y, camera.width, camera.height,
|
|
|
|
Utils.getTintFromFloats(camera._fadeRed, camera._fadeGreen, camera._fadeBlue, 1.0),
|
|
|
|
camera._fadeAlpha,
|
|
|
|
1, 0, 0, 1, 0, 0,
|
|
|
|
[1, 0, 0, 1, 0, 0]
|
|
|
|
);
|
|
|
|
|
|
|
|
// Flash
|
|
|
|
FlatTintPipeline.batchFillRect(
|
|
|
|
0, 0, 1, 1, 0,
|
|
|
|
camera.x, camera.y, camera.width, camera.height,
|
|
|
|
Utils.getTintFromFloats(camera._flashRed, camera._flashGreen, camera._flashBlue, 1.0),
|
|
|
|
camera._flashAlpha,
|
|
|
|
1, 0, 0, 1, 0, 0,
|
|
|
|
[1, 0, 0, 1, 0, 0]
|
|
|
|
);
|
|
|
|
|
|
|
|
FlatTintPipeline.flush();
|
|
|
|
}
|
|
|
|
|
2018-01-24 18:55:23 +00:00
|
|
|
this.popScissor();
|
2018-01-24 03:57:33 +00:00
|
|
|
},
|
|
|
|
|
2018-01-20 04:05:56 +00:00
|
|
|
preRender: function ()
|
|
|
|
{
|
|
|
|
if (this.contextLost) return;
|
|
|
|
|
2018-01-22 22:51:15 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var color = this.game.config.backgroundColor;
|
2018-01-26 23:17:11 +00:00
|
|
|
var pipelines = this.pipelines;
|
2018-01-22 22:51:15 +00:00
|
|
|
|
|
|
|
// Bind custom framebuffer here
|
|
|
|
gl.clearColor(color.redGL, color.greenGL, color.blueGL, color.alphaGL);
|
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
2018-01-26 23:17:11 +00:00
|
|
|
|
|
|
|
for (var key in pipelines)
|
|
|
|
{
|
|
|
|
pipelines[key].onPreRender();
|
|
|
|
}
|
2018-01-20 04:05:56 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
render: function (scene, children, interpolationPercentage, camera)
|
|
|
|
{
|
|
|
|
if (this.contextLost) return;
|
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
var gl = this.gl;
|
|
|
|
var list = children.list;
|
|
|
|
var childCount = list.length;
|
2018-01-29 21:46:48 +00:00
|
|
|
var pipelines = this.pipelines;
|
|
|
|
|
|
|
|
for (var key in pipelines)
|
|
|
|
{
|
|
|
|
pipelines[key].onRender(scene, camera);
|
|
|
|
}
|
2018-01-22 21:37:47 +00:00
|
|
|
|
2018-01-24 03:57:33 +00:00
|
|
|
this.preRenderCamera(camera);
|
2018-01-22 21:37:47 +00:00
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
for (var index = 0; index < childCount; ++index)
|
|
|
|
{
|
|
|
|
var child = list[index];
|
|
|
|
|
|
|
|
if (!child.willRender())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-01-22 21:37:47 +00:00
|
|
|
if (child.blendMode !== this.currentBlendMode)
|
|
|
|
{
|
|
|
|
this.setBlendMode(child.blendMode);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child.mask)
|
|
|
|
{
|
|
|
|
child.mask.preRenderWebGL(this, child, camera);
|
|
|
|
}
|
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
child.renderWebGL(this, child, interpolationPercentage, camera);
|
|
|
|
|
2018-01-22 21:37:47 +00:00
|
|
|
if (child.mask)
|
|
|
|
{
|
|
|
|
child.mask.postRenderWebGL(this, child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-23 23:36:49 +00:00
|
|
|
this.flush();
|
2018-01-24 03:57:33 +00:00
|
|
|
this.setBlendMode(CONST.BlendModes.NORMAL);
|
|
|
|
this.postRenderCamera(camera);
|
2018-01-20 04:05:56 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
postRender: function ()
|
|
|
|
{
|
|
|
|
if (this.contextLost) return;
|
|
|
|
|
2018-01-22 22:51:15 +00:00
|
|
|
// Unbind custom framebuffer here
|
|
|
|
|
2018-01-20 04:05:56 +00:00
|
|
|
if (this.snapshotState.callback)
|
|
|
|
{
|
|
|
|
this.snapshotState.callback(WebGLSnapshot(this.canvas, this.snapshotState.type, this.snapshotState.encoder));
|
|
|
|
this.snapshotState.callback = null;
|
|
|
|
}
|
2018-01-26 23:17:11 +00:00
|
|
|
|
|
|
|
var pipelines = this.pipelines;
|
|
|
|
|
|
|
|
for (var key in pipelines)
|
|
|
|
{
|
|
|
|
pipelines[key].onPostRender();
|
|
|
|
}
|
2018-01-20 04:05:56 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
snapshot: function (callback, type, encoderOptions)
|
|
|
|
{
|
|
|
|
this.snapshotState.callback = callback;
|
|
|
|
this.snapshotState.type = type;
|
|
|
|
this.snapshotState.encoder = encoderOptions;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-24 00:40:20 +00:00
|
|
|
canvasToTexture: function (srcCanvas, dstTexture, shouldReallocate, scaleMode)
|
2018-01-20 04:05:56 +00:00
|
|
|
{
|
|
|
|
var gl = this.gl;
|
|
|
|
|
|
|
|
if (!dstTexture)
|
|
|
|
{
|
2018-01-26 15:21:05 +00:00
|
|
|
dstTexture = this.createTexture2D(0, gl.NEAREST, gl.NEAREST, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.RGBA, srcCanvas, srcCanvas.width, srcCanvas.height, true);
|
2018-01-20 04:05:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-01-24 03:03:43 +00:00
|
|
|
this.setTexture2D(dstTexture, 0);
|
2018-01-20 04:05:56 +00:00
|
|
|
|
|
|
|
if (!shouldReallocate)
|
|
|
|
{
|
|
|
|
gl.texSubImage2D(0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
|
|
|
dstTexture.width = srcCanvas.width;
|
|
|
|
dstTexture.height = srcCanvas.height;
|
|
|
|
}
|
|
|
|
|
2018-01-24 03:03:43 +00:00
|
|
|
this.setTexture2D(null, 0);
|
2018-01-20 04:05:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return dstTexture;
|
|
|
|
},
|
|
|
|
|
|
|
|
setTextureFilter: function (texture, filter)
|
|
|
|
{
|
|
|
|
var gl = this.gl;
|
|
|
|
var glFilter = [ gl.LINEAR, gl.NEAREST ][filter];
|
|
|
|
|
|
|
|
this.setTexture2D(texture, 0);
|
|
|
|
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
|
|
|
|
|
|
|
|
this.setTexture2D(null, 0);
|
|
|
|
|
2018-01-22 21:21:47 +00:00
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setFloat1: function (program, name, x)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform1f(this.gl.getUniformLocation(program, name), x);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setFloat2: function (program, name, x, y)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform2f(this.gl.getUniformLocation(program, name), x, y);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setFloat3: function (program, name, x, y, z)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform3f(this.gl.getUniformLocation(program, name), x, y, z);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setFloat4: function (program, name, x, y, z, w)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform4f(this.gl.getUniformLocation(program, name), x, y, z, w);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setInt1: function (program, name, x)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform1i(this.gl.getUniformLocation(program, name), x);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setInt2: function (program, name, x, y)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform2i(this.gl.getUniformLocation(program, name), x, y);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setInt3: function (program, name, x, y, z)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform3i(this.gl.getUniformLocation(program, name), x, y, z);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setInt4: function (program, name, x, y, z, w)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniform4i(this.gl.getUniformLocation(program, name), x, y, z, w);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setMatrix2: function (program, name, transpose, matrix)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(program, name), transpose, matrix);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setMatrix3: function (program, name, transpose, matrix)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniformMatrix3fv(this.gl.getUniformLocation(program, name), transpose, matrix);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setMatrix4: function (program, name, transpose, matrix)
|
|
|
|
{
|
|
|
|
this.setProgram(program);
|
|
|
|
this.gl.uniformMatrix4fv(this.gl.getUniformLocation(program, name), transpose, matrix);
|
2018-01-20 04:05:56 +00:00
|
|
|
return this;
|
2018-01-31 03:38:10 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
destroy: function ()
|
|
|
|
{
|
|
|
|
// Clear-up anything that should be cleared :)
|
|
|
|
this.contextLost = true;
|
|
|
|
|
|
|
|
this.game = null;
|
2017-01-23 21:42:47 +00:00
|
|
|
}
|
2017-07-04 13:48:18 +00:00
|
|
|
|
|
|
|
});
|
2016-12-07 02:28:22 +00:00
|
|
|
|
2018-01-17 21:25:43 +00:00
|
|
|
module.exports = WebGLRenderer;
|