Text rendering via canvas/texture upload

This commit is contained in:
Felipe Alfonso 2017-03-21 17:08:43 -03:00
parent 29ec16fd33
commit 0cdb150357
4 changed files with 135 additions and 8 deletions

View file

@ -119,12 +119,12 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
if (iteration === 0) if (iteration === 0)
{ {
lastPath = new Path(tx, ty, lineWidth); lastPath = new Path(tx, ty, lineWidth, lineColor, lineAlpha);
pathArray.push(lastPath); pathArray.push(lastPath);
} }
else else
{ {
lastPath.points.push(new Point(tx, ty, lineWidth)); lastPath.points.push(new Point(tx, ty, lineWidth, lineColor, lineAlpha));
} }
iteration += iterStep; iteration += iterStep;
@ -155,7 +155,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
var firstPoint = lastPath.points[0]; var firstPoint = lastPath.points[0];
var lastPoint = lastPath.points[lastPath.points.length - 1]; var lastPoint = lastPath.points[lastPath.points.length - 1];
lastPath.points.push(firstPoint); lastPath.points.push(firstPoint);
lastPath = new Path(lastPoint.x, lastPoint.y, lineWidth); lastPath = new Path(lastPoint.x, lastPoint.y, lastPoint.width, lastPoint.rgb, lastPoint.alpha);
pathArray.push(lastPath); pathArray.push(lastPath);
} }
break; break;
@ -261,18 +261,18 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
case Commands.LINE_TO: case Commands.LINE_TO:
if (lastPath !== null) if (lastPath !== null)
{ {
lastPath.points.push(new Point(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth)); lastPath.points.push(new Point(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth, lineColor, lineAlpha));
} }
else else
{ {
lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth); lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth, lineColor, lineAlpha);
pathArray.push(lastPath); pathArray.push(lastPath);
} }
cmdIndex += 2; cmdIndex += 2;
break; break;
case Commands.MOVE_TO: case Commands.MOVE_TO:
lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth); lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth, lineColor, lineAlpha);
pathArray.push(lastPath); pathArray.push(lastPath);
cmdIndex += 2; cmdIndex += 2;
break; break;

View file

@ -65,6 +65,10 @@ var Text = new Class({
this.width = 1; this.width = 1;
this.height = 1; this.height = 1;
this.gpuBuffer = null;
this.prevWidth = this.canvas.width;
this.prevHeight = this.canvas.height;
if (text !== '') if (text !== '')
{ {
this.updateText(); this.updateText();
@ -254,7 +258,46 @@ var Text = new Class({
} }
} }
if (this.state.game.config.renderType === Phaser.WEBGL)
{
this.uploadToGPU();
}
return this; return this;
},
uploadToGPU: function ()
{
var gl = this.state.game.renderer.gl;
var currentTexture2D = this.state.game.renderer.currentTexture2D;
var canvas = this.canvas;
if (this.gpuBuffer === null)
{
this.gpuBuffer = gl.createTexture();
}
if (this.prevWidth < canvas.width || this.prevHeight < canvas.height)
{
/* New canvas is too big. We need to reallocate the texture */
gl.bindTexture(gl.TEXTURE_2D, this.gpuBuffer);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
this.prevWidth = canvas.width;
this.prevHeight = canvas.height;
}
else
{
/* if the canvas is smaller we just update the resource */
gl.bindTexture(gl.TEXTURE_2D, this.gpuBuffer);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
}
/* we must rebind old texture */
gl.bindTexture(gl.TEXTURE_2D, currentTexture2D);
} }
}); });

View file

@ -5,8 +5,7 @@ var TextWebGLRenderer = function (renderer, src, interpolationPercentage, camera
return; return;
} }
var cameraScrollX = camera.scrollX; renderer.spriteBatch.addSpriteTexture(src, camera, src.gpuBuffer, src.prevWidth, src.prevHeight);
var cameraScrollY = camera.scrollY;
}; };
module.exports = TextWebGLRenderer; module.exports = TextWebGLRenderer;

View file

@ -179,6 +179,91 @@ SpriteBatch.prototype = {
} }
}, },
addSpriteTexture: function (src, camera, texture, textureWidth, textureHeight)
{
var tempMatrix = this.tempMatrix;
var alpha = 16777216;
var vertexDataBuffer = this.vertexDataBuffer;
var vertexBufferF32 = vertexDataBuffer.floatView;
var vertexBufferU32 = vertexDataBuffer.uintView;
var vertexOffset = 0;
var width = textureWidth * (src.flipX ? -1 : 1);
var height = textureHeight * (src.flipY ? -1 : 1);
var translateX = src.x - camera.scrollX;
var translateY = src.y - camera.scrollY;
var scaleX = src.scaleX;
var scaleY = src.scaleY;
var rotation = -src.rotation;
var tempMatrixMatrix = tempMatrix.matrix;
var x = -src.displayOriginX + ((textureWidth) * (src.flipX ? 1 : 0.0));
var y = -src.displayOriginY + ((textureHeight) * (src.flipY ? 1 : 0.0));
var xw = x + width;
var yh = y + height;
var cameraMatrix = camera.matrix.matrix;
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;
tempMatrix.applyITRS(translateX, translateY, rotation, scaleX, scaleY);
sra = tempMatrixMatrix[0];
srb = tempMatrixMatrix[1];
src = tempMatrixMatrix[2];
srd = tempMatrixMatrix[3];
sre = tempMatrixMatrix[4];
srf = tempMatrixMatrix[5];
cma = cameraMatrix[0];
cmb = cameraMatrix[1];
cmc = cameraMatrix[2];
cmd = cameraMatrix[3];
cme = cameraMatrix[4];
cmf = cameraMatrix[5];
mva = sra * cma + srb * cmc;
mvb = sra * cmb + srb * cmd;
mvc = src * cma + srd * cmc;
mvd = src * cmb + srd * cmd;
mve = sre * cma + srf * cmc + cme;
mvf = sre * cmb + srf * cmd + cmf;
tx0 = x * mva + y * mvc + mve;
ty0 = x * mvb + y * mvd + mvf;
tx1 = x * mva + yh * mvc + mve;
ty1 = x * mvb + yh * mvd + mvf;
tx2 = xw * mva + yh * mvc + mve;
ty2 = xw * mvb + yh * mvd + mvf;
tx3 = xw * mva + y * mvc + mve;
ty3 = xw * mvb + y * mvd + mvf;
this.manager.setBatch(this, texture, camera);
vertexOffset = vertexDataBuffer.allocate(20);
this.elementCount += 6;
vertexBufferF32[vertexOffset++] = tx0;
vertexBufferF32[vertexOffset++] = ty0;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topLeft;
vertexBufferF32[vertexOffset++] = tx1;
vertexBufferF32[vertexOffset++] = ty1;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomLeft;
vertexBufferF32[vertexOffset++] = tx2;
vertexBufferF32[vertexOffset++] = ty2;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.bottomRight;
vertexBufferF32[vertexOffset++] = tx3;
vertexBufferF32[vertexOffset++] = ty3;
vertexBufferF32[vertexOffset++] = 1;
vertexBufferF32[vertexOffset++] = 0;
vertexBufferU32[vertexOffset++] = 0xFFFFFF; //vertexColor.topRight;
},
addSprite: function (src, camera) addSprite: function (src, camera)
{ {
var tempMatrix = this.tempMatrix; var tempMatrix = this.tempMatrix;