Skip to content

Commit 7a4b298

Browse files
committed
Allow for custom canvas and context game config options. Game.context now set in WebGL mode. Allows WebGL2 contexts to be passed in. Fix phaserjs#3653
1 parent c9ea4dc commit 7a4b298

6 files changed

Lines changed: 48 additions & 29 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* WebGLRenderer.config has a new property `maxTextureSize` which is derived from `gl.MAX_TEXTURE_SIZE`, you can get it via the new method `getMaxTextureSize()`
1111
* WebGLRenderer has a new property `compression` which holds the browser / devices compressed texture support gl extensions, which is populated during `init`.
1212
* Optimized TextureTintPipeline.drawBlitter so it skips bobs that have alpha of zero and only calls `setTexture2D` if the bob sourceIndex has changed, previously it called it for every single bob.
13+
* You can pass in your own `canvas` and `context` elements in your Game Config and Phaser will use those to render with instead of creating its own. This also allows you to pass in a WebGL 2 context. Fix #3653 (thanks @tgrajewski)
14+
* Game.context used to be undefined if running in WebGL. It is now set to be the `WebGLRenderingContext` during WebGLRenderer.init. If you provided your own custom context, it is set to this instead.
1315

1416
### Bug Fixes
1517

@@ -21,7 +23,7 @@
2123

2224
My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:
2325

24-
26+
@samme @mzguimaraes @NaNdreas @Matthew-Herman @melissaelopez
2527

2628

2729
## Version 3.7.1 - Sinon - 8th May 2018

src/boot/Config.js

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ var ValueToColor = require('../display/color/ValueToColor');
5757
* @property {number} [resolution=1] - [description]
5858
* @property {number} [type=CONST.AUTO] - [description]
5959
* @property {*} [parent=null] - [description]
60-
* @property {HTMLCanvasElement} [canvas=null] - [description]
60+
* @property {HTMLCanvasElement} [canvas=null] - Provide your own Canvas element for Phaser to use instead of creating one.
6161
* @property {string} [canvasStyle=null] - [description]
62+
* @property {CanvasRenderingContext2D} [context] - Provide your own Canvas Context for Phaser to use, instead of creating one.
6263
* @property {object} [scene=null] - [description]
6364
* @property {string[]} [seed] - [description]
6465
* @property {string} [title=''] - [description]
@@ -145,49 +146,48 @@ var Config = new Class({
145146
*/
146147
this.zoom = GetValue(config, 'zoom', 1);
147148

148-
149149
/**
150150
* @const {number} Phaser.Boot.Config#resolution - [description]
151151
*/
152152
this.resolution = GetValue(config, 'resolution', 1);
153153

154-
155154
/**
156155
* @const {number} Phaser.Boot.Config#renderType - [description]
157156
*/
158157
this.renderType = GetValue(config, 'type', CONST.AUTO);
159158

160-
161159
/**
162160
* @const {?*} Phaser.Boot.Config#parent - [description]
163161
*/
164162
this.parent = GetValue(config, 'parent', null);
165163

166164
/**
167-
* @const {?HTMLCanvasElement} Phaser.Boot.Config#canvas - [description]
165+
* @const {?HTMLCanvasElement} Phaser.Boot.Config#canvas - Force Phaser to use your own Canvas element instead of creating one.
168166
*/
169167
this.canvas = GetValue(config, 'canvas', null);
170168

169+
/**
170+
* @const {?(CanvasRenderingContext2D|WebGLRenderingContext)} Phaser.Boot.Config#context - Force Phaser to use your own Canvas context instead of creating one.
171+
*/
172+
this.context = GetValue(renderConfig, 'context', null);
173+
171174
/**
172175
* @const {?string} Phaser.Boot.Config#canvasStyle - [description]
173176
*/
174177
this.canvasStyle = GetValue(config, 'canvasStyle', null);
175178

176-
177179
/**
178180
* @const {?object} Phaser.Boot.Config#sceneConfig - [description]
179181
*/
180182
this.sceneConfig = GetValue(config, 'scene', null);
181183

182-
183184
/**
184185
* @const {string[]} Phaser.Boot.Config#seed - [description]
185186
*/
186187
this.seed = GetValue(config, 'seed', [ (Date.now() * Math.random()).toString() ]);
187188

188189
MATH.RND.init(this.seed);
189190

190-
191191
/**
192192
* @const {string} Phaser.Boot.Config#gameTitle - [description]
193193
*/
@@ -203,8 +203,8 @@ var Config = new Class({
203203
*/
204204
this.gameVersion = GetValue(config, 'version', '');
205205

206-
207206
// Input
207+
208208
/**
209209
* @const {boolean} Phaser.Boot.Config#inputKeyboard - [description]
210210
*/
@@ -215,7 +215,6 @@ var Config = new Class({
215215
*/
216216
this.inputKeyboardEventTarget = GetValue(config, 'input.keyboard.target', window);
217217

218-
219218
/**
220219
* @const {(boolean|object)} Phaser.Boot.Config#inputMouse - [description]
221220
*/
@@ -231,7 +230,6 @@ var Config = new Class({
231230
*/
232231
this.inputMouseCapture = GetValue(config, 'input.mouse.capture', true);
233232

234-
235233
/**
236234
* @const {boolean} Phaser.Boot.Config#inputTouch - [description]
237235
*/
@@ -247,32 +245,28 @@ var Config = new Class({
247245
*/
248246
this.inputTouchCapture = GetValue(config, 'input.touch.capture', true);
249247

250-
251248
/**
252249
* @const {boolean} Phaser.Boot.Config#inputGamepad - [description]
253250
*/
254251
this.inputGamepad = GetValue(config, 'input.gamepad', false);
255252

256-
257253
/**
258254
* @const {boolean} Phaser.Boot.Config#disableContextMenu - [description]
259255
*/
260256
this.disableContextMenu = GetValue(config, 'disableContextMenu', false);
261257

262-
263258
/**
264259
* @const {any} Phaser.Boot.Config#audio - [description]
265260
*/
266261
this.audio = GetValue(config, 'audio');
267262

268-
269263
// If you do: { banner: false } it won't display any banner at all
264+
270265
/**
271266
* @const {boolean} Phaser.Boot.Config#hideBanner - [description]
272267
*/
273268
this.hideBanner = (GetValue(config, 'banner', null) === false);
274269

275-
276270
/**
277271
* @const {boolean} Phaser.Boot.Config#hidePhaser - [description]
278272
*/
@@ -361,7 +355,6 @@ var Config = new Class({
361355
*/
362356
this.powerPreference = GetValue(renderConfig, 'powerPreference', 'default');
363357

364-
365358
var bgc = GetValue(config, 'backgroundColor', 0);
366359

367360
/**
@@ -374,7 +367,6 @@ var Config = new Class({
374367
this.backgroundColor.alpha = 0;
375368
}
376369

377-
378370
// Callbacks
379371
/**
380372
* @const {BootCallback} Phaser.Boot.Config#preBoot - [description]
@@ -386,7 +378,6 @@ var Config = new Class({
386378
*/
387379
this.postBoot = GetValue(config, 'callbacks.postBoot', NOOP);
388380

389-
390381
// Physics
391382
// physics: {
392383
// system: 'impact',
@@ -405,8 +396,8 @@ var Config = new Class({
405396
*/
406397
this.defaultPhysicsSystem = GetValue(this.physics, 'default', false);
407398

408-
409399
// Loader Defaults
400+
410401
/**
411402
* @const {string} Phaser.Boot.Config#loaderBaseURL - [description]
412403
*/
@@ -452,14 +443,13 @@ var Config = new Class({
452443
*/
453444
this.loaderTimeout = GetValue(config, 'loader.timeout', 0);
454445

455-
456446
// Scene Plugins
447+
457448
/**
458449
* @const {any} Phaser.Boot.Config#defaultPlugins - [description]
459450
*/
460451
this.defaultPlugins = GetValue(config, 'plugins', Plugins.DefaultScene);
461452

462-
463453
// Default / Missing Images
464454
var pngPrefix = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg';
465455

src/boot/CreateRenderer.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ var CreateRenderer = function (game)
9696
CanvasRenderer = require('../renderer/canvas/CanvasRenderer');
9797
WebGLRenderer = require('../renderer/webgl/WebGLRenderer');
9898

99-
// Let the config pick the renderer type, both are included
99+
// Let the config pick the renderer type, as both are included
100100
if (config.renderType === CONST.WEBGL)
101101
{
102102
game.renderer = new WebGLRenderer(game);
103+
104+
// The WebGL Renderer sets this value during its init, not on construction
103105
game.context = null;
104106
}
105107
else
@@ -115,7 +117,10 @@ var CreateRenderer = function (game)
115117

116118
// Force the type to WebGL, regardless what was requested
117119
config.renderType = CONST.WEBGL;
120+
118121
game.renderer = new WebGLRenderer(game);
122+
123+
// The WebGL Renderer sets this value during its init, not on construction
119124
game.context = null;
120125
}
121126

@@ -125,7 +130,9 @@ var CreateRenderer = function (game)
125130

126131
// Force the type to Canvas, regardless what was requested
127132
config.renderType = CONST.CANVAS;
133+
128134
game.renderer = new CanvasRenderer(game);
135+
129136
game.context = game.renderer.gameContext;
130137
}
131138
};

src/boot/Game.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ var Game = new Class({
7474
this.renderer = null;
7575

7676
/**
77-
* A reference to the HTML Canvas Element on which the renderer is drawing.
77+
* A reference to the HTML Canvas Element that Phaser uses to render the game.
78+
* This is created automatically by Phaser unless you provide a `canvas` property
79+
* in your Game Config.
7880
*
7981
* @name Phaser.Game#canvas
8082
* @type {HTMLCanvasElement}
@@ -83,10 +85,14 @@ var Game = new Class({
8385
this.canvas = null;
8486

8587
/**
86-
* A reference to the Canvas Rendering Context belonging to the Canvas Element this game is rendering to.
88+
* A reference to the Rendering Context belonging to the Canvas Element this game is rendering to.
89+
* If the game is running under Canvas it will be a 2d Canvas Rendering Context.
90+
* If the game is running under WebGL it will be a WebGL Rendering Context.
91+
* This context is created automatically by Phaser unless you provide a `context` property
92+
* in your Game Config.
8793
*
8894
* @name Phaser.Game#context
89-
* @type {CanvasRenderingContext2D}
95+
* @type {(CanvasRenderingContext2D|WebGLRenderingContext)}
9096
* @since 3.0.0
9197
*/
9298
this.context = null;

src/renderer/canvas/CanvasRenderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ var CanvasRenderer = new Class({
118118
* @type {CanvasRenderingContext2D}
119119
* @since 3.0.0
120120
*/
121-
this.gameContext = this.gameCanvas.getContext('2d');
121+
this.gameContext = (this.game.config.context) ? this.game.config.context : this.gameCanvas.getContext('2d');
122122

123123
/**
124124
* [description]

src/renderer/webgl/WebGLRenderer.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,18 +419,32 @@ var WebGLRenderer = new Class({
419419
*/
420420
init: function (config)
421421
{
422+
var gl;
422423
var canvas = this.canvas;
423424
var clearColor = config.backgroundColor;
424-
var gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation);
425+
426+
// Did they provide their own context?
427+
if (this.game.config.context)
428+
{
429+
gl = this.game.config.context;
430+
}
431+
else
432+
{
433+
gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation);
434+
}
425435

426436
if (!gl || gl.isContextLost())
427437
{
428438
this.contextLost = true;
439+
429440
throw new Error('This browser does not support WebGL. Try using the Canvas pipeline.');
430441
}
431442

432443
this.gl = gl;
433444

445+
// Set it back into the Game, so devs can access it from there too
446+
this.game.context = gl;
447+
434448
for (var i = 0; i <= 16; i++)
435449
{
436450
this.blendModes.push({ func: [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_ADD });

0 commit comments

Comments
 (0)