From ffdb41057d6c0b4efd04288a4f0164f5147b9e76 Mon Sep 17 00:00:00 2001 From: Dave Evans Date: Wed, 29 Jun 2016 11:00:09 +0100 Subject: [PATCH] Support for 2D transformations in screen space text Support for Anchors in screen space text --- examples/text/index.html | 28 +++--- src/framework/components/text/component.js | 103 +++++++++++++++++++- src/framework/components/text/system.js | 2 + src/graphics/program-lib/chunks/msdf2d.vert | 12 +-- 4 files changed, 117 insertions(+), 28 deletions(-) diff --git a/examples/text/index.html b/examples/text/index.html index 08efb361e81..8d6a7428920 100644 --- a/examples/text/index.html +++ b/examples/text/index.html @@ -56,31 +56,31 @@ c.addComponent('camera', { clearColor: new pc.Color(44/255, 62/255, 80/255) }); - c.translate(-15,5,-15); - c.lookAt(-10,0,0); + c.translate(-15, 15, -15); + c.lookAt(0,0,0); app.root.addChild(c); var t = new pc.Entity(); t.addComponent('text', { - text: "On the other hand, we denounce with righteous indignation and dislike men \nwho are so beguiled and demoralized by the charms of pleasure of the moment.", + text: "Hello World!", asset: fontAsset, color: new pc.Color(243/255, 157/255, 18/255), - hAlign: pc.ALIGN_LEFT, - vAlign: pc.ALIGN_TOP, - // spacing: 1.05, - // lineHeight: 1, - // screenSpace: true + hAlign: pc.ALIGN_CENTER, + vAlign: pc.ALIGN_MIDDLE }); - // t.setPosition(0,0,0); - // t.setLocalScale(1,1,1); app.root.addChild(t); var keyboard = new pc.Keyboard(document.body) + var a = 0; app.on("update", function (dt) { - drawAxes(t.getLocalPosition(), 1); - if (keyboard.wasPressed(pc.KEY_A)) { - t.text.screenSpace = !t.text.screenSpace; - } + // draw origin + drawAxes(pc.Vec3.ZERO,1); + + a+= 45*dt; + + t.setEulerAngles(0,0,a); + t.setLocalScale(Math.sin(0.1*a)+1.4, Math.sin(0.2*a)+1.9, 1); + keyboard.update(); }); window.addEventListener("resize", function () { diff --git a/src/framework/components/text/component.js b/src/framework/components/text/component.js index e80cd0d0ea4..74a734e694a 100644 --- a/src/framework/components/text/component.js +++ b/src/framework/components/text/component.js @@ -20,6 +20,9 @@ pc.extend(pc, function () { this._hAlign = pc.ALIGN_LEFT; this._vAlign = pc.ALIGN_TOP; + this._hAnchor = pc.ALIGN_LEFT; + this._vAnchor = pc.ALIGN_TOP; + this._lineHeight = 1.2; this._spacing = 1; @@ -41,6 +44,22 @@ pc.extend(pc, function () { this._uvs = []; this._indices = []; + this._modelMat = new pc.Mat4(); + this._projMat = new pc.Mat4(); + this._modelProjMat = new pc.Mat4(); + + // update transform if it has changed + // this.entity.on('sync', function () { + // if (this._meshInstance) { + // this._updateModelProjection(); + // } + // }, this); + + this.system.app.graphicsDevice.on("resizecanvas", function (width, height) { + if (this._meshInstance) { + this._updateModelProjection(); + } + }, this); }; TextComponent = pc.inherits(TextComponent, pc.Component); @@ -62,10 +81,7 @@ pc.extend(pc, function () { this._meshInstance.setParameter("texture_atlas", this._font.texture); this._meshInstance.setParameter("material_foreground", this._color.data); - this._meshInstance.setParameter('uResolution', this.system.resolution); - this._meshInstance.setParameter('uOffset', this.entity.getPosition().data); - this._meshInstance.setParameter('uScale', this.entity.getLocalScale().data); - + this._updateModelProjection(); // add model to sceen this.system.app.scene.addModel(this._model); @@ -77,6 +93,57 @@ pc.extend(pc, function () { } }, + _updateModelProjection: function () { + this._modelMat.copy(this.entity.worldTransform); + + var w = this.system.resolution[0]/32; + var h = this.system.resolution[1]/32; + + var left; + var right; + var bottom; + var top; + var near = 2; + var far = 0; + var xscale = -1/32; + var yscale = -1/32; + + if (this._hAnchor === pc.ALIGN_LEFT) { + left = 0; + right = -w; + xscale = -1/32; + } else if (this._hAnchor === pc.ALIGN_RIGHT) { + left = w; + right = 0; + xscale = 1/32; + } else { + left = w/2; + right = -w/2; + xscale = -1/32; + } + + if (this._vAnchor === pc.ALIGN_TOP) { + bottom = -h; + top = 0; + yscale = -1/32; + } else if (this._vAnchor === pc.ALIGN_BOTTOM) { + bottom = 0; + top = h; + yscale = 1/32; + } else { + bottom = -h/2; + top = h/2; + yscale = -1/32; + } + this._projMat.setOrtho(left, right, bottom, top, near, far); + + this._modelMat.data[12] *= xscale; + this._modelMat.data[13] *= yscale; + + this._modelProjMat.copy(this._projMat).mul(this._modelMat); + this._meshInstance.setParameter('uProjection2d', this._modelProjMat.data); + }, + // build the mesh for the text _createMesh: function (text) { var l = text.length; @@ -372,6 +439,34 @@ pc.extend(pc, function () { } }); + Object.defineProperty(TextComponent.prototype, "hAnchor", { + get: function () { + return this._hAnchor + }, + + set: function (value) { + var _prev = this._hAnchor; + this._hAnchor = value; + if (_prev !== value && this._font) { + this._updateText(); + } + } + }); + + Object.defineProperty(TextComponent.prototype, "vAnchor", { + get: function () { + return this._vAnchor + }, + + set: function (value) { + var _prev = this._vAnchor; + this._vAnchor = value; + if (_prev !== value && this._font) { + this._updateText(); + } + } + }); + Object.defineProperty(TextComponent.prototype, "lineHeight", { get: function () { return this._lineHeight diff --git a/src/framework/components/text/system.js b/src/framework/components/text/system.js index bff5c3d49ea..d166c92f66a 100644 --- a/src/framework/components/text/system.js +++ b/src/framework/components/text/system.js @@ -35,6 +35,8 @@ pc.extend(pc, function () { if (data.color !== undefined) component.color = data.color; if (data.hAlign !== undefined) component.hAlign = data.hAlign; if (data.vAlign !== undefined) component.vAlign = data.vAlign; + if (data.hAnchor !== undefined) component.hAnchor = data.hAnchor; + if (data.vAnchor !== undefined) component.vAnchor = data.vAnchor; if (data.spacing !== undefined) component.spacing = data.spacing; if (data.lineHeight !== undefined) component.lineHeight = data.lineHeight; if (data.maxWidth !== undefined) component.maxWidth = data.maxWidth; diff --git a/src/graphics/program-lib/chunks/msdf2d.vert b/src/graphics/program-lib/chunks/msdf2d.vert index 5a30e92cd2c..dd9ac097311 100644 --- a/src/graphics/program-lib/chunks/msdf2d.vert +++ b/src/graphics/program-lib/chunks/msdf2d.vert @@ -3,18 +3,10 @@ attribute vec2 aUv0; varying vec2 vUv0; -uniform vec3 uResolution; -uniform vec3 uOffset; -uniform vec3 uScale; - -float PIXEL_SCALE = 32.0; // original texture is 32x32 +uniform mat4 uProjection2d; void main(void) { vUv0 = aUv0; - - gl_Position = vec4(-2.0 * ((PIXEL_SCALE * uScale.y * aPosition.x - uOffset.x) / uResolution.x) - 1.0, - 2.0 * ((PIXEL_SCALE * uScale.y * aPosition.y - uOffset.y) / uResolution.y) + 1.0, - 0.0, - 1.0); + gl_Position = vec4((uProjection2d * vec4(aPosition, 1.0)).xy, 0.0, 1.0); }