phaser/v3/src/renderer/webgl/WebGLRenderer.js

288 lines
7.6 KiB
JavaScript
Raw Normal View History

2016-12-07 02:28:22 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
* @author Mat Groves (@Doormat23)
* @copyright 2016 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
2016-12-07 03:42:41 +00:00
var CONST = require('../../const');
2016-12-07 02:28:22 +00:00
var CreateEmptyTexture = require('./utils/CreateEmptyTexture');
2017-01-19 23:20:36 +00:00
var CreateTexture2DImage = require('./utils/texture/CreateTexture2DImage');
2017-01-19 22:43:41 +00:00
var BlitterBatch = require('./batches/blitter/BlitterBatch');
var SpriteBatch = require('./batches/sprite/SpriteBatch');
2016-12-07 02:28:22 +00:00
var WebGLRenderer = function (game)
{
this.game = game;
2016-12-07 03:42:41 +00:00
this.type = CONST.WEBGL;
2016-12-07 02:28:22 +00:00
2016-12-07 03:42:41 +00:00
this.width = game.config.width * game.config.resolution;
this.height = game.config.height * game.config.resolution;
this.resolution = game.config.resolution;
2016-12-07 02:28:22 +00:00
this.view = game.canvas;
// All of these settings will be able to be controlled via the Game Config
this.config = {
clearBeforeRender: true,
transparent: false,
autoResize: false,
preserveDrawingBuffer: false,
2016-12-07 02:28:22 +00:00
WebGLContextOptions: {
alpha: true,
antialias: true,
premultipliedAlpha: true,
stencil: true,
preserveDrawingBuffer: false
}
2016-12-07 02:28:22 +00:00
};
this.contextLost = false;
this.maxTextures = 1;
this.multiTexture = false;
this.blendModes = [];
2016-12-07 02:28:22 +00:00
this.gl = null;
2016-12-07 02:28:22 +00:00
this.init();
2017-01-19 23:20:36 +00:00
2017-01-19 17:53:20 +00:00
this.blitterBatch = new BlitterBatch(game, this.gl, this);
2017-01-19 22:43:41 +00:00
this.spriteBatch = new SpriteBatch(game, this.gl, this);
2017-01-19 23:20:36 +00:00
2017-01-19 17:53:20 +00:00
this.batch = null;
this.currentTexture2D = null;
2016-12-07 02:28:22 +00:00
};
WebGLRenderer.prototype.constructor = WebGLRenderer;
WebGLRenderer.prototype = {
init: function ()
{
this.gl = this.view.getContext('webgl', this.config.WebGLContextOptions) || this.view.getContext('experimental-webgl', this.config.WebGLContextOptions);
2016-12-07 02:28:22 +00:00
if (!this.gl)
{
this.contextLost = true;
throw new Error('This browser does not support WebGL. Try using the Canvas renderer.');
}
var gl = this.gl;
/*
// Will need supporting
2016-12-07 02:28:22 +00:00
this.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
if (this.maxTextures === 1)
{
this.multiTexture = false;
}
else
{
this.createMultiEmptyTextures();
}
this.emptyTexture = CreateEmptyTexture(this.gl, 1, 1, 0, 0);
*/
2016-12-07 02:28:22 +00:00
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.enable(gl.BLEND);
2016-12-07 03:42:41 +00:00
gl.clearColor(1, 0, 0, 1);
2016-12-07 02:28:22 +00:00
this.resize(this.width, this.height);
/*
// Will need supporting
2016-12-07 02:28:22 +00:00
this.extensions.compression = {};
var etc1 = gl.getExtension('WEBGL_compressed_texture_etc1') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc1');
var pvrtc = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
var s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
if (etc1)
{
this.extensions.compression.ETC1 = etc1;
}
if (pvrtc)
{
this.extensions.compression.PVRTC = pvrtc;
}
if (s3tc)
{
this.extensions.compression.S3TC = s3tc;
}
*/
2016-12-07 02:28:22 +00:00
// Map Blend Modes
var add = [ gl.SRC_ALPHA, gl.DST_ALPHA ];
var normal = [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ];
var multiply = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ];
var screen = [ gl.SRC_ALPHA, gl.ONE ];
this.blendModes = [
normal, add, multiply, screen, normal,
normal, normal, normal, normal,
normal, normal, normal, normal,
normal, normal, normal, normal
];
},
2017-01-19 23:20:36 +00:00
createTexture2D: function (source)
{
var gl = this.gl;
if (!source.glTexture)
{
source.glTexture = CreateTexture2DImage(gl, source.image, gl.NEAREST, 0);
}
this.currentTexture2D = source.glTexture;
},
2017-01-19 22:43:41 +00:00
setTexture2D: function (texture2D)
2017-01-19 17:53:20 +00:00
{
2017-01-20 18:53:53 +00:00
if (this.currentTexture2D !== texture2D)
{
2017-01-20 18:53:53 +00:00
if (this.batch)
2017-01-20 18:51:00 +00:00
{
2017-01-20 18:53:53 +00:00
this.batch.flush();
2017-01-20 18:51:00 +00:00
}
2017-01-20 18:53:53 +00:00
var gl = this.gl;
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture2D);
2017-01-20 18:53:53 +00:00
this.currentTexture2D = texture2D;
}
2017-01-19 17:53:20 +00:00
},
setBatch: function (batch, texture2D)
2017-01-19 22:43:41 +00:00
{
this.setTexture2D(texture2D);
2017-01-20 18:53:53 +00:00
if (this.batch !== batch)
2017-01-19 22:43:41 +00:00
{
if (this.batch)
{
this.batch.flush();
}
2017-01-20 18:53:53 +00:00
2017-01-19 22:43:41 +00:00
batch.bind();
2017-01-20 18:53:53 +00:00
2017-01-19 22:43:41 +00:00
this.batch = batch;
}
},
2016-12-07 02:28:22 +00:00
resize: function (width, height)
{
2016-12-07 03:42:41 +00:00
var res = this.game.config.resolution;
this.width = width * res;
this.height = height * res;
2016-12-07 02:28:22 +00:00
this.view.width = this.width;
this.view.height = this.height;
if (this.autoResize)
{
2016-12-07 03:42:41 +00:00
this.view.style.width = (this.width / res) + 'px';
this.view.style.height = (this.height / res) + 'px';
2016-12-07 02:28:22 +00:00
}
this.gl.viewport(0, 0, this.width, this.height);
// Needed?
// this.clipUnitX = 2 / this.width;
// this.clipUnitY = 2 / this.height;
2016-12-07 02:28:22 +00:00
// Needed?
// this.projection.x = (this.width / 2) / res;
// this.projection.y = -(this.height / 2) / res;
2016-12-07 02:28:22 +00:00
},
/**
* Renders the State.
*
* @method render
* @param {Phaser.State} state - The State to be rendered.
* @param {number} interpolationPercentage - The cumulative amount of time that hasn't been simulated yet, divided
* by the amount of time that will be simulated the next time update()
* runs. Useful for interpolating frames.
*/
render: function (state, interpolationPercentage)
{
2016-12-07 03:42:41 +00:00
// console.log('%c render start ', 'color: #ffffff; background: #00ff00;');
2016-12-07 02:28:22 +00:00
// No point rendering if our context has been blown up!
if (this.contextLost)
{
return;
}
// Add Pre-render hook
var gl = this.gl;
2017-01-19 17:53:20 +00:00
// This is the old render loop - add what you need here to replace it,
// but please allow each State to render to its own Quad FBO
2017-01-19 17:53:20 +00:00
//var fbo = state.sys.fbo;
2016-12-07 02:28:22 +00:00
2017-01-19 17:53:20 +00:00
//fbo.activate();
2016-12-07 02:28:22 +00:00
// clear is needed for the FBO, otherwise corruption ...
gl.clear(gl.COLOR_BUFFER_BIT);
2017-01-19 17:53:20 +00:00
//this.setBlendMode(CONST.blendModes.NORMAL);
2016-12-07 02:28:22 +00:00
2017-01-19 17:53:20 +00:00
//this.batch.start();
2016-12-07 02:28:22 +00:00
// Could move to the State Systems or MainLoop
2017-01-19 17:53:20 +00:00
for (var c = 0; c < state.sys.children.list.length; c++)
{
var child = state.sys.children.list[c];
2016-12-07 02:28:22 +00:00
2017-01-19 17:53:20 +00:00
child.renderWebGL(this, child, interpolationPercentage);
}
this.batch.flush();
//this.batch.stop();
2016-12-07 02:28:22 +00:00
// Call state.render here, so we can do some extra shizzle on the top
// Maybe pass in the FBO texture too?
2017-01-19 17:53:20 +00:00
//fbo.render(null);
2016-12-07 02:28:22 +00:00
// Unbind the fbo texture and replace it with an empty texture.
// If we forget this we corrupt the main context texture!
// or get `RENDER WARNING: there is no texture bound to the unit 0` spam in the console
2017-01-19 17:53:20 +00:00
//gl.bindTexture(gl.TEXTURE_2D, this.emptyTexture);
2016-12-07 02:28:22 +00:00
2017-01-19 17:53:20 +00:00
2016-12-07 02:28:22 +00:00
// console.log('%c render end ', 'color: #ffffff; background: #ff0000;');
// Add Post-render hook
},
destroy: function ()
{
this.gl = null;
2017-01-19 17:53:20 +00:00
},
createFBO: function () {}
2016-12-07 02:28:22 +00:00
};
module.exports = WebGLRenderer;