mirror of
https://github.com/photonstorm/phaser
synced 2024-11-30 08:31:01 +00:00
Dynamic Bitmap Text webgl rendering
This commit is contained in:
parent
69c56fc920
commit
06fa0afcc8
4 changed files with 381 additions and 328 deletions
|
@ -4,285 +4,17 @@ var Utils = require('../../../renderer/webgl/Utils');
|
|||
var tempMatrix = new TransformMatrix();
|
||||
var tempMatrixChar = new TransformMatrix();
|
||||
|
||||
var DynamicBitmapTextWebGLRenderer = function (renderer, gameObject, interpolationPercentage, camera)
|
||||
var DynamicBitmapTextWebGLRenderer = function (renderer, bitmapText, interpolationPercentage, camera)
|
||||
{
|
||||
var text = gameObject.text;
|
||||
var text = bitmapText.text;
|
||||
var textLength = text.length;
|
||||
|
||||
if (GameObject.RENDER_MASK !== gameObject.renderFlags || textLength === 0 || (gameObject.cameraFilter > 0 && (gameObject.cameraFilter & camera._id)))
|
||||
if (GameObject.RENDER_MASK !== bitmapText.renderFlags || textLength === 0 || (bitmapText.cameraFilter > 0 && (bitmapText.cameraFilter & camera._id)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var spriteRenderer = renderer.spriteRenderer;
|
||||
var displayCallback = gameObject.displayCallback;
|
||||
var textureFrame = gameObject.frame;
|
||||
var cameraScrollX = camera.scrollX * gameObject.scrollFactorX;
|
||||
var cameraScrollY = camera.scrollY * gameObject.scrollFactorY;
|
||||
var chars = gameObject.fontData.chars;
|
||||
var lineHeight = gameObject.fontData.lineHeight;
|
||||
var getTint = Utils.getTintAppendFloatAlpha;
|
||||
var alpha = gameObject.alpha;
|
||||
var tintTL = getTint(gameObject._tintTL, alpha);
|
||||
var tintTR = getTint(gameObject._tintTR, alpha);
|
||||
var tintBL = getTint(gameObject._tintBL, alpha);
|
||||
var tintBR = getTint(gameObject._tintBR, alpha);
|
||||
var vertexViewF32 = spriteRenderer.vertexViewF32;
|
||||
var vertexViewU32 = spriteRenderer.vertexViewU32;
|
||||
var vertexOffset = 0;
|
||||
var textureData = gameObject.texture.source[textureFrame.sourceIndex];
|
||||
var textureX = textureFrame.cutX;
|
||||
var textureY = textureFrame.cutY;
|
||||
var textureWidth = textureData.width;
|
||||
var textureHeight = textureData.height;
|
||||
var texture = textureData.glTexture;
|
||||
var xAdvance = 0;
|
||||
var yAdvance = 0;
|
||||
var indexCount = 0;
|
||||
var charCode = 0;
|
||||
var glyph = null;
|
||||
var glyphX = 0;
|
||||
var glyphY = 0;
|
||||
var glyphW = 0;
|
||||
var glyphH = 0;
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var rotation = 0;
|
||||
var xw = 0;
|
||||
var yh = 0;
|
||||
var umin = 0;
|
||||
var umax = 0;
|
||||
var vmin = 0;
|
||||
var vmax = 0;
|
||||
var lastGlyph = null;
|
||||
var lastCharCode = 0;
|
||||
var tempMatrixMatrix = tempMatrix.matrix;
|
||||
var cameraMatrix = camera.matrix.matrix;
|
||||
var scale = (gameObject.fontSize / gameObject.fontData.size);
|
||||
var uta, utb, utc, utd, ute, utf;
|
||||
var tempMatrixCharMatrix = tempMatrixChar.matrix;
|
||||
var renderTarget = gameObject.renderTarget;
|
||||
var sr = Math.sin(-gameObject.rotation);
|
||||
var cr = Math.cos(-gameObject.rotation);
|
||||
var sra = cr * gameObject.scaleX;
|
||||
var srb = -sr * gameObject.scaleX;
|
||||
var src = sr * gameObject.scaleY;
|
||||
var srd = cr * gameObject.scaleY;
|
||||
var sre = gameObject.x - cameraScrollX;
|
||||
var srf = gameObject.y - cameraScrollY;
|
||||
var cma = cameraMatrix[0];
|
||||
var cmb = cameraMatrix[1];
|
||||
var cmc = cameraMatrix[2];
|
||||
var cmd = cameraMatrix[3];
|
||||
var cme = cameraMatrix[4];
|
||||
var cmf = cameraMatrix[5];
|
||||
var mva = sra * cma + srb * cmc;
|
||||
var mvb = sra * cmb + srb * cmd;
|
||||
var mvc = src * cma + srd * cmc;
|
||||
var mvd = src * cmb + srd * cmd;
|
||||
var mve = sre * cma + srf * cmc + cme;
|
||||
var mvf = sre * cmb + srf * cmd + cmf;
|
||||
var gl = renderer.gl;
|
||||
var shader = null;
|
||||
|
||||
renderer.setPipeline(spriteRenderer);
|
||||
spriteRenderer.beginPass(gameObject.shader, gameObject.renderTarget);
|
||||
renderer.setTexture(texture, 0);
|
||||
shader = spriteRenderer.currentProgram;
|
||||
|
||||
spriteRenderer.orthoViewMatrix[0] = +2.0 / spriteRenderer.width;
|
||||
spriteRenderer.orthoViewMatrix[5] = -2.0 / spriteRenderer.height;
|
||||
|
||||
shader.setConstantMatrix4x4(shader.getUniformLocation('uOrthoMatrix'), spriteRenderer.orthoViewMatrix);
|
||||
|
||||
if (gameObject.cropWidth > 0 && gameObject.cropHeight > 0)
|
||||
{
|
||||
spriteRenderer.flush();
|
||||
|
||||
if (!renderer.scissor.enabled)
|
||||
{
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
}
|
||||
|
||||
var sw = gameObject.cropWidth * gameObject.scaleX;
|
||||
var sh = gameObject.cropHeight * gameObject.scaleY;
|
||||
|
||||
gl.scissor(gameObject.x, gl.drawingBufferHeight - gameObject.y - sh, sw, sh);
|
||||
}
|
||||
|
||||
for (var index = 0; index < textLength; ++index)
|
||||
{
|
||||
charCode = text.charCodeAt(index);
|
||||
|
||||
if (charCode === 10)
|
||||
{
|
||||
xAdvance = 0;
|
||||
indexCount = 0;
|
||||
yAdvance += lineHeight;
|
||||
lastGlyph = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
glyph = chars[charCode];
|
||||
|
||||
if (!glyph)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
glyphX = textureX + glyph.x;
|
||||
glyphY = textureY + glyph.y;
|
||||
|
||||
glyphW = glyph.width;
|
||||
glyphH = glyph.height;
|
||||
|
||||
x = (indexCount + glyph.xOffset + xAdvance) * scale;
|
||||
y = (glyph.yOffset + yAdvance) * scale;
|
||||
|
||||
rotation = 0;
|
||||
|
||||
if (lastGlyph !== null)
|
||||
{
|
||||
var kerningOffset = glyph.kerning[lastCharCode];
|
||||
x += (kerningOffset !== undefined) ? kerningOffset : 0;
|
||||
}
|
||||
|
||||
if (displayCallback)
|
||||
{
|
||||
var output = displayCallback({ color: 0, tint: { topLeft: tintTL, topRight: tintTR, bottomLeft: tintBL, bottomRight: tintBR }, index: index, charCode: charCode, x: x, y: y, scale: scale, rotation: 0, data: glyph.data });
|
||||
|
||||
x = output.x;
|
||||
y = output.y;
|
||||
scale = output.scale;
|
||||
rotation = output.rotation;
|
||||
|
||||
if (output.color)
|
||||
{
|
||||
tintTL = output.color;
|
||||
tintTR = output.color;
|
||||
tintBL = output.color;
|
||||
tintBR = output.color;
|
||||
}
|
||||
else
|
||||
{
|
||||
tintTL = output.tint.topLeft;
|
||||
tintTR = output.tint.topRight;
|
||||
tintBL = output.tint.bottomLeft;
|
||||
tintBR = output.tint.bottomRight;
|
||||
}
|
||||
|
||||
tintTL = getTint(tintTL, alpha);
|
||||
tintTR = getTint(tintTR, alpha);
|
||||
tintBL = getTint(tintBL, alpha);
|
||||
tintBR = getTint(tintBR, alpha);
|
||||
}
|
||||
|
||||
x -= gameObject.scrollX | 0;
|
||||
y -= gameObject.scrollY | 0;
|
||||
|
||||
tempMatrixChar.applyITRS(
|
||||
x, y,
|
||||
-rotation,
|
||||
scale, scale
|
||||
);
|
||||
|
||||
uta = tempMatrixCharMatrix[0];
|
||||
utb = tempMatrixCharMatrix[1];
|
||||
utc = tempMatrixCharMatrix[2];
|
||||
utd = tempMatrixCharMatrix[3];
|
||||
ute = tempMatrixCharMatrix[4];
|
||||
utf = tempMatrixCharMatrix[5];
|
||||
|
||||
sra = uta * mva + utb * mvc;
|
||||
srb = uta * mvb + utb * mvd;
|
||||
src = utc * mva + utd * mvc;
|
||||
srd = utc * mvb + utd * mvd;
|
||||
sre = ute * mva + utf * mvc + mve;
|
||||
srf = ute * mvb + utf * mvd + mvf;
|
||||
|
||||
xw = glyphW;
|
||||
yh = glyphH;
|
||||
tx0 = sre;
|
||||
ty0 = srf;
|
||||
tx1 = yh * src + sre;
|
||||
ty1 = yh * srd + srf;
|
||||
tx2 = xw * sra + yh * src + sre;
|
||||
ty2 = xw * srb + yh * srd + srf;
|
||||
tx3 = xw * sra + sre;
|
||||
ty3 = xw * srb + srf;
|
||||
umin = glyphX / textureWidth;
|
||||
umax = (glyphX + glyphW) / textureWidth;
|
||||
vmin = glyphY / textureHeight;
|
||||
vmax = (glyphY + glyphH) / textureHeight;
|
||||
|
||||
if (spriteRenderer.vertexCount >= spriteRenderer.vertexCapacity)
|
||||
{
|
||||
spriteRenderer.flush();
|
||||
vertexOffset = 0;
|
||||
}
|
||||
|
||||
spriteRenderer.vertexCount += 6;
|
||||
|
||||
vertexViewF32[vertexOffset++] = tx0;
|
||||
vertexViewF32[vertexOffset++] = ty0;
|
||||
vertexViewF32[vertexOffset++] = umin;
|
||||
vertexViewF32[vertexOffset++] = vmin;
|
||||
vertexViewU32[vertexOffset++] = tintTL;
|
||||
|
||||
vertexViewF32[vertexOffset++] = tx1;
|
||||
vertexViewF32[vertexOffset++] = ty1;
|
||||
vertexViewF32[vertexOffset++] = umin;
|
||||
vertexViewF32[vertexOffset++] = vmax;
|
||||
vertexViewU32[vertexOffset++] = tintBL;
|
||||
|
||||
vertexViewF32[vertexOffset++] = tx2;
|
||||
vertexViewF32[vertexOffset++] = ty2;
|
||||
vertexViewF32[vertexOffset++] = umax;
|
||||
vertexViewF32[vertexOffset++] = vmax;
|
||||
vertexViewU32[vertexOffset++] = tintBR;
|
||||
|
||||
vertexViewF32[vertexOffset++] = tx0;
|
||||
vertexViewF32[vertexOffset++] = ty0;
|
||||
vertexViewF32[vertexOffset++] = umin;
|
||||
vertexViewF32[vertexOffset++] = vmin;
|
||||
vertexViewU32[vertexOffset++] = tintTL;
|
||||
|
||||
vertexViewF32[vertexOffset++] = tx2;
|
||||
vertexViewF32[vertexOffset++] = ty2;
|
||||
vertexViewF32[vertexOffset++] = umax;
|
||||
vertexViewF32[vertexOffset++] = vmax;
|
||||
vertexViewU32[vertexOffset++] = tintBR;
|
||||
|
||||
vertexViewF32[vertexOffset++] = tx3;
|
||||
vertexViewF32[vertexOffset++] = ty3;
|
||||
vertexViewF32[vertexOffset++] = umax;
|
||||
vertexViewF32[vertexOffset++] = vmin;
|
||||
vertexViewU32[vertexOffset++] = tintTR;
|
||||
|
||||
xAdvance += glyph.xAdvance;
|
||||
indexCount += 1;
|
||||
lastGlyph = glyph;
|
||||
lastCharCode = charCode;
|
||||
|
||||
}
|
||||
|
||||
if (gameObject.cropWidth > 0 && gameObject.cropHeight > 0)
|
||||
{
|
||||
spriteRenderer.flush();
|
||||
|
||||
if (renderer.scissor.enabled)
|
||||
{
|
||||
gl.scissor(renderer.scissor.x, renderer.scissor.y, renderer.scissor.width, renderer.scissor.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.scissor(camera.x, gl.drawingBufferHeight - camera.y - camera.height, camera.width, camera.height);
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
spriteRenderer.flush();
|
||||
spriteRenderer.endPass();
|
||||
renderer.pipelines.TextureTintPipeline.batchDynamicBitmapText(bitmapText, camera);
|
||||
};
|
||||
|
||||
module.exports = DynamicBitmapTextWebGLRenderer;
|
||||
|
|
|
@ -14,7 +14,7 @@ var GameObjects = {
|
|||
BitmapText: require('./bitmaptext/static/BitmapText'),
|
||||
Blitter: require('./blitter/Blitter'),
|
||||
//Container: require('./container/Container'),
|
||||
//DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapText'),
|
||||
DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapText'),
|
||||
//DynamicTilemapLayer: require('./tilemap/dynamiclayer/DynamicTilemapLayer'),
|
||||
Graphics: require('./graphics/Graphics.js'),
|
||||
//Group: require('./group/Group'),
|
||||
|
@ -36,7 +36,7 @@ var GameObjects = {
|
|||
Factories: {
|
||||
Blitter: require('./blitter/BlitterFactory'),
|
||||
//Container: require('./container/ContainerFactory'),
|
||||
//DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapTextFactory'),
|
||||
DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapTextFactory'),
|
||||
Graphics: require('./graphics/GraphicsFactory'),
|
||||
//Group: require('./group/GroupFactory'),
|
||||
Image: require('./image/ImageFactory'),
|
||||
|
@ -54,7 +54,7 @@ var GameObjects = {
|
|||
Creators: {
|
||||
Blitter: require('./blitter/BlitterCreator'),
|
||||
//Container: require('./container/ContainerCreator'),
|
||||
//DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapTextCreator'),
|
||||
DynamicBitmapText: require('./bitmaptext/dynamic/DynamicBitmapTextCreator'),
|
||||
Graphics: require('./graphics/GraphicsCreator'),
|
||||
//Group: require('./group/GroupCreator'),
|
||||
Image: require('./image/ImageCreator'),
|
||||
|
|
|
@ -62,7 +62,10 @@ var WebGLRenderer = new Class({
|
|||
this.currentVertexBuffer = null;
|
||||
this.currentIndexBuffer = null;
|
||||
this.currentBlendMode = Infinity;
|
||||
this.currentScissorState = { enabled: false, x: 0, y: 0, w: 0, h: 0 };
|
||||
this.currentScissorEnabled = false;
|
||||
this.currentScissor = new Uint32Array([0, 0, this.width, this.height]);
|
||||
this.currentScissorIdx = 0;
|
||||
this.scissorStack = new Uint32Array(4 * 1000);
|
||||
|
||||
// Setup context lost and restore event listeners
|
||||
this.canvas.addEventListener('webglcontextlost', function (event) {
|
||||
|
@ -229,45 +232,70 @@ var WebGLRenderer = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
beginScissor: function (x, y, width, height)
|
||||
setScissor: function (x, y, w, h)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var scissorState = this.currentScissorState;
|
||||
var currentScissor = this.currentScissor;
|
||||
var enabled = (x == 0 && y == 0 && w == gl.canvas.width && h == gl.canvas.height && w >= 0 && h >= 0);
|
||||
|
||||
if (x == 0 &&
|
||||
y == 0 &&
|
||||
width == gl.canvas.width &&
|
||||
height == gl.canvas.height &&
|
||||
width > 0 &&
|
||||
height > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scissorState.enabled)
|
||||
if (currentScissor[0] !== x ||
|
||||
currentScissor[1] !== y ||
|
||||
currentScissor[2] !== w ||
|
||||
currentScissor[3] !== h)
|
||||
{
|
||||
this.flush();
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
scissorState.enabled = true;
|
||||
}
|
||||
|
||||
scissorState.x = x;
|
||||
scissorState.y = gl.drawingBufferHeight - y - height;
|
||||
scissorState.width = width;
|
||||
scissorState.height = height;
|
||||
gl.scissor(scissorState.x, scissorState.y, scissorState.width, scissorState.height);
|
||||
},
|
||||
currentScissor[0] = x;
|
||||
currentScissor[1] = y;
|
||||
currentScissor[2] = w;
|
||||
currentScissor[3] = h;
|
||||
|
||||
endScissor: function ()
|
||||
{
|
||||
var gl = this.gl;
|
||||
var scissorState = this.currentScissorState;
|
||||
this.currentScissorEnabled = enabled;
|
||||
|
||||
if (scissorState.enabled)
|
||||
if (enabled)
|
||||
{
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
scissorState.enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
setPipeline: function (pipelineInstance, overrideProgram)
|
||||
|
@ -559,7 +587,7 @@ var WebGLRenderer = new Class({
|
|||
/* Rendering Functions */
|
||||
preRenderCamera: function (camera)
|
||||
{
|
||||
this.beginScissor(camera.x, camera.y, camera.width, camera.height);
|
||||
this.pushScissor(camera.x, camera.y, camera.width, camera.height);
|
||||
|
||||
if (camera.backgroundColor.alphaGL > 0)
|
||||
{
|
||||
|
@ -608,7 +636,7 @@ var WebGLRenderer = new Class({
|
|||
FlatTintPipeline.flush();
|
||||
}
|
||||
|
||||
this.endScissor();
|
||||
this.popScissor();
|
||||
},
|
||||
|
||||
preRender: function ()
|
||||
|
|
|
@ -531,7 +531,7 @@ var TextureTintPipeline = new Class({
|
|||
var cameraScrollY = camera.scrollY * bitmapText.scrollFactorY;
|
||||
var fontData = bitmapText.fontData;
|
||||
var lineHeight = fontData.lineHeight;
|
||||
var scale = (bitmapText.fontSize / fontData.size);
|
||||
var scale = (bitmapText.fontSize / bitmapText.fontData.size);
|
||||
var chars = fontData.chars;
|
||||
var alpha = bitmapText.alpha;
|
||||
var tint0 = getTint(bitmapText._tintTL, alpha);
|
||||
|
@ -589,6 +589,8 @@ var TextureTintPipeline = new Class({
|
|||
var mvd = src * cmb + srd * cmd;
|
||||
var mve = sre * cma + srf * cmc + cme;
|
||||
var mvf = sre * cmb + srf * cmd + cmf;
|
||||
var crop = (bitmapText.cropWidth > 0 || bitmapText.cropHeight > 0);
|
||||
var uta, utb, utc, utd, ute, utf;
|
||||
var vertexOffset = 0;
|
||||
|
||||
renderer.setTexture2D(texture, 0);
|
||||
|
@ -615,38 +617,44 @@ var TextureTintPipeline = new Class({
|
|||
|
||||
glyphX = textureX + glyph.x;
|
||||
glyphY = textureY + glyph.y;
|
||||
|
||||
glyphW = glyph.width;
|
||||
glyphH = glyph.height;
|
||||
x = (indexCount + glyph.xOffset + xAdvance) * scale;
|
||||
y = (glyph.yOffset + yAdvance) * scale;
|
||||
|
||||
x = (indexCount + glyph.xOffset + xAdvance) - scrollX;
|
||||
y = (glyph.yOffset + yAdvance) - scrollY;
|
||||
|
||||
if (lastGlyph !== null)
|
||||
{
|
||||
var kerningOffset = glyph.kerning[lastCharCode];
|
||||
x += (kerningOffset !== undefined) ? kerningOffset : 0;
|
||||
}
|
||||
}
|
||||
|
||||
xAdvance += glyph.xAdvance;
|
||||
indexCount += 1;
|
||||
lastGlyph = glyph;
|
||||
lastCharCode = charCode;
|
||||
uta = scale;
|
||||
utb = 0;
|
||||
utc = 0;
|
||||
utd = scale;
|
||||
ute = x * scale;
|
||||
utf = y * scale;
|
||||
|
||||
// Nothing to render or a space? Then skip to the next glyph
|
||||
if (glyphW === 0 || glyphH === 0 || charCode === 32)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sra = uta * mva + utb * mvc;
|
||||
srb = uta * mvb + utb * mvd;
|
||||
src = utc * mva + utd * mvc;
|
||||
srd = utc * mvb + utd * mvd;
|
||||
sre = ute * mva + utf * mvc + mve;
|
||||
srf = ute * mvb + utf * mvd + mvf;
|
||||
|
||||
xw = glyphW;
|
||||
yh = glyphH;
|
||||
tx0 = sre;
|
||||
ty0 = srf;
|
||||
tx1 = yh * src + sre;
|
||||
ty1 = yh * srd + srf;
|
||||
tx2 = xw * sra + yh * src + sre;
|
||||
ty2 = xw * srb + yh * srd + srf;
|
||||
tx3 = xw * sra + sre;
|
||||
ty3 = xw * srb + srf;
|
||||
|
||||
xw = x + glyphW * scale;
|
||||
yh = y + glyphH * scale;
|
||||
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;
|
||||
umin = glyphX / textureWidth;
|
||||
umax = (glyphX + glyphW) / textureWidth;
|
||||
vmin = glyphY / textureHeight;
|
||||
|
@ -689,9 +697,294 @@ var TextureTintPipeline = new Class({
|
|||
vertexViewF32[vertexOffset + 27] = umax;
|
||||
vertexViewF32[vertexOffset + 28] = vmin;
|
||||
vertexViewU32[vertexOffset + 29] = tint3;
|
||||
|
||||
xAdvance += glyph.xAdvance;
|
||||
indexCount += 1;
|
||||
lastGlyph = glyph;
|
||||
lastCharCode = charCode;
|
||||
|
||||
this.vertexCount += 6;
|
||||
}
|
||||
|
||||
if (crop)
|
||||
{
|
||||
renderer.popScissor();
|
||||
}
|
||||
},
|
||||
|
||||
batchDynamicBitmapText: function (bitmapText, camera)
|
||||
{
|
||||
this.renderer.setPipeline(this);
|
||||
|
||||
if (this.vertexCount + 6 > this.vertexCapacity)
|
||||
{
|
||||
this.flush();
|
||||
}
|
||||
|
||||
var displayCallback = bitmapText.displayCallback;
|
||||
var text = bitmapText.text;
|
||||
var textLength = text.length;
|
||||
var getTint = Utils.getTintAppendFloatAlpha;
|
||||
var vertexViewF32 = this.vertexViewF32;
|
||||
var vertexViewU32 = this.vertexViewU32;
|
||||
var renderer = this.renderer;
|
||||
var cameraMatrix = camera.matrix.matrix;
|
||||
var cameraWidth = camera.width + 50;
|
||||
var cameraHeight = camera.height + 50;
|
||||
var cameraX = -50;
|
||||
var cameraY = -50;
|
||||
var frame = bitmapText.frame;
|
||||
var textureSource = bitmapText.texture.source[frame.sourceIndex];
|
||||
var cameraScrollX = camera.scrollX * bitmapText.scrollFactorX;
|
||||
var cameraScrollY = camera.scrollY * bitmapText.scrollFactorY;
|
||||
var scrollX = bitmapText.scrollX;
|
||||
var scrollY = bitmapText.scrollY;
|
||||
var fontData = bitmapText.fontData;
|
||||
var lineHeight = fontData.lineHeight;
|
||||
var scale = (bitmapText.fontSize / fontData.size);
|
||||
var chars = fontData.chars;
|
||||
var alpha = bitmapText.alpha;
|
||||
var tint0 = getTint(bitmapText._tintTL, alpha);
|
||||
var tint1 = getTint(bitmapText._tintTR, alpha);
|
||||
var tint2 = getTint(bitmapText._tintBL, alpha);
|
||||
var tint3 = getTint(bitmapText._tintBR, alpha);
|
||||
var srcX = bitmapText.x;
|
||||
var srcY = bitmapText.y;
|
||||
var textureX = frame.cutX;
|
||||
var textureY = frame.cutY;
|
||||
var textureWidth = textureSource.width;
|
||||
var textureHeight = textureSource.height;
|
||||
var texture = textureSource.glTexture;
|
||||
var xAdvance = 0;
|
||||
var yAdvance = 0;
|
||||
var indexCount = 0;
|
||||
var charCode = 0;
|
||||
var glyph = null;
|
||||
var glyphX = 0;
|
||||
var glyphY = 0;
|
||||
var glyphW = 0;
|
||||
var glyphH = 0;
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var xw = 0;
|
||||
var yh = 0;
|
||||
var umin = 0;
|
||||
var umax = 0;
|
||||
var vmin = 0;
|
||||
var vmax = 0;
|
||||
var lastGlyph = null;
|
||||
var lastCharCode = 0;
|
||||
var translateX = srcX + frame.x;
|
||||
var translateY = srcY + frame.y;
|
||||
var rotation = -bitmapText.rotation;
|
||||
var scaleX = bitmapText.scaleX;
|
||||
var scaleY = bitmapText.scaleY;
|
||||
var sr = Math.sin(rotation);
|
||||
var cr = Math.cos(rotation);
|
||||
var sra = cr * scaleX;
|
||||
var srb = -sr * scaleX;
|
||||
var src = sr * scaleY;
|
||||
var srd = cr * scaleY;
|
||||
var sre = translateX;
|
||||
var srf = translateY;
|
||||
var cma = cameraMatrix[0];
|
||||
var cmb = cameraMatrix[1];
|
||||
var cmc = cameraMatrix[2];
|
||||
var cmd = cameraMatrix[3];
|
||||
var cme = cameraMatrix[4];
|
||||
var cmf = cameraMatrix[5];
|
||||
var mva = sra * cma + srb * cmc;
|
||||
var mvb = sra * cmb + srb * cmd;
|
||||
var mvc = src * cma + srd * cmc;
|
||||
var mvd = src * cmb + srd * cmd;
|
||||
var mve = sre * cma + srf * cmc + cme;
|
||||
var mvf = sre * cmb + srf * cmd + cmf;
|
||||
var crop = (bitmapText.cropWidth > 0 || bitmapText.cropHeight > 0);
|
||||
var uta, utb, utc, utd, ute, utf;
|
||||
var vertexOffset = 0;
|
||||
|
||||
renderer.setTexture2D(texture, 0);
|
||||
|
||||
if (crop)
|
||||
{
|
||||
renderer.pushScissor(
|
||||
bitmapText.x,
|
||||
bitmapText.y,
|
||||
bitmapText.cropWidth * bitmapText.scaleX,
|
||||
bitmapText.cropHeight * bitmapText.scaleY
|
||||
);
|
||||
}
|
||||
|
||||
for (var index = 0; index < textLength; ++index)
|
||||
{
|
||||
scale = (bitmapText.fontSize / bitmapText.fontData.size);
|
||||
rotation = 0;
|
||||
|
||||
charCode = text.charCodeAt(index);
|
||||
|
||||
if (charCode === 10)
|
||||
{
|
||||
xAdvance = 0;
|
||||
indexCount = 0;
|
||||
yAdvance += lineHeight;
|
||||
lastGlyph = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
glyph = chars[charCode];
|
||||
|
||||
if (!glyph)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
glyphX = textureX + glyph.x;
|
||||
glyphY = textureY + glyph.y;
|
||||
|
||||
glyphW = glyph.width;
|
||||
glyphH = glyph.height;
|
||||
|
||||
x = (indexCount + glyph.xOffset + xAdvance) - scrollX;
|
||||
y = (glyph.yOffset + yAdvance) - scrollY;
|
||||
|
||||
if (lastGlyph !== null)
|
||||
{
|
||||
var kerningOffset = glyph.kerning[lastCharCode];
|
||||
x += (kerningOffset !== undefined) ? kerningOffset : 0;
|
||||
}
|
||||
|
||||
if (displayCallback)
|
||||
{
|
||||
var output = displayCallback({
|
||||
color: 0,
|
||||
tint: {
|
||||
topLeft: tint0,
|
||||
topRight: tint1,
|
||||
bottomLeft: tint2,
|
||||
bottomRight: tint3
|
||||
},
|
||||
index: index,
|
||||
charCode: charCode,
|
||||
x: x,
|
||||
y: y,
|
||||
scale: scale,
|
||||
rotation: 0,
|
||||
data: glyph.data
|
||||
});
|
||||
|
||||
x = output.x;
|
||||
y = output.y;
|
||||
scale = output.scale;
|
||||
rotation = output.rotation;
|
||||
|
||||
if (output.color)
|
||||
{
|
||||
tint0 = output.color;
|
||||
tint1 = output.color;
|
||||
tint2 = output.color;
|
||||
tint3 = output.color;
|
||||
}
|
||||
else
|
||||
{
|
||||
tint0 = output.tint.topLeft;
|
||||
tint1 = output.tint.topRight;
|
||||
tint2 = output.tint.bottomLeft;
|
||||
tint3 = output.tint.bottomRight;
|
||||
}
|
||||
|
||||
tint0 = getTint(tint0, alpha);
|
||||
tint1 = getTint(tint1, alpha);
|
||||
tint2 = getTint(tint2, alpha);
|
||||
tint3 = getTint(tint3, alpha);
|
||||
}
|
||||
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
x -= cameraScrollX;
|
||||
y -= cameraScrollY;
|
||||
|
||||
sr = Math.sin(-rotation);
|
||||
cr = Math.cos(-rotation);
|
||||
uta = cr * scale;
|
||||
utb = -sr * scale;
|
||||
utc = sr * scale;
|
||||
utd = cr * scale;
|
||||
ute = x;
|
||||
utf = y;
|
||||
|
||||
sra = uta * mva + utb * mvc;
|
||||
srb = uta * mvb + utb * mvd;
|
||||
src = utc * mva + utd * mvc;
|
||||
srd = utc * mvb + utd * mvd;
|
||||
sre = ute * mva + utf * mvc + mve;
|
||||
srf = ute * mvb + utf * mvd + mvf;
|
||||
|
||||
xw = glyphW;
|
||||
yh = glyphH;
|
||||
tx0 = sre;
|
||||
ty0 = srf;
|
||||
tx1 = yh * src + sre;
|
||||
ty1 = yh * srd + srf;
|
||||
tx2 = xw * sra + yh * src + sre;
|
||||
ty2 = xw * srb + yh * srd + srf;
|
||||
tx3 = xw * sra + sre;
|
||||
ty3 = xw * srb + srf;
|
||||
|
||||
umin = glyphX / textureWidth;
|
||||
umax = (glyphX + glyphW) / textureWidth;
|
||||
vmin = glyphY / textureHeight;
|
||||
vmax = (glyphY + glyphH) / textureHeight;
|
||||
|
||||
if (this.vertexCount + 6 > this.vertexCapacity)
|
||||
{
|
||||
this.flush();
|
||||
}
|
||||
|
||||
vertexOffset = this.vertexCount * this.vertexComponentCount;
|
||||
|
||||
vertexViewF32[vertexOffset + 0] = tx0;
|
||||
vertexViewF32[vertexOffset + 1] = ty0;
|
||||
vertexViewF32[vertexOffset + 2] = umin;
|
||||
vertexViewF32[vertexOffset + 3] = vmin;
|
||||
vertexViewU32[vertexOffset + 4] = tint0;
|
||||
vertexViewF32[vertexOffset + 5] = tx1;
|
||||
vertexViewF32[vertexOffset + 6] = ty1;
|
||||
vertexViewF32[vertexOffset + 7] = umin;
|
||||
vertexViewF32[vertexOffset + 8] = vmax;
|
||||
vertexViewU32[vertexOffset + 9] = tint1;
|
||||
vertexViewF32[vertexOffset + 10] = tx2;
|
||||
vertexViewF32[vertexOffset + 11] = ty2;
|
||||
vertexViewF32[vertexOffset + 12] = umax;
|
||||
vertexViewF32[vertexOffset + 13] = vmax;
|
||||
vertexViewU32[vertexOffset + 14] = tint2;
|
||||
vertexViewF32[vertexOffset + 15] = tx0;
|
||||
vertexViewF32[vertexOffset + 16] = ty0;
|
||||
vertexViewF32[vertexOffset + 17] = umin;
|
||||
vertexViewF32[vertexOffset + 18] = vmin;
|
||||
vertexViewU32[vertexOffset + 19] = tint0;
|
||||
vertexViewF32[vertexOffset + 20] = tx2;
|
||||
vertexViewF32[vertexOffset + 21] = ty2;
|
||||
vertexViewF32[vertexOffset + 22] = umax;
|
||||
vertexViewF32[vertexOffset + 23] = vmax;
|
||||
vertexViewU32[vertexOffset + 24] = tint2;
|
||||
vertexViewF32[vertexOffset + 25] = tx3;
|
||||
vertexViewF32[vertexOffset + 26] = ty3;
|
||||
vertexViewF32[vertexOffset + 27] = umax;
|
||||
vertexViewF32[vertexOffset + 28] = vmin;
|
||||
vertexViewU32[vertexOffset + 29] = tint3;
|
||||
|
||||
xAdvance += glyph.xAdvance;
|
||||
indexCount += 1;
|
||||
lastGlyph = glyph;
|
||||
lastCharCode = charCode;
|
||||
|
||||
this.vertexCount += 6;
|
||||
}
|
||||
|
||||
if (crop)
|
||||
{
|
||||
renderer.popScissor();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue