diff --git a/demo/client/html/3d-demo.html.hbs b/demo/client/html/3d-demo.html.hbs
index 9d15d442..f0cda5fd 100644
--- a/demo/client/html/3d-demo.html.hbs
+++ b/demo/client/html/3d-demo.html.hbs
@@ -27,9 +27,9 @@
diff --git a/demo/client/src/3d-demo.ts b/demo/client/src/3d-demo.ts
index 89b786fb..c8077d80 100644
--- a/demo/client/src/3d-demo.ts
+++ b/demo/client/src/3d-demo.ts
@@ -25,7 +25,7 @@ import SSAAStrategy from "./ssaa-strategy";
import * as _ from "lodash";
import PathfinderBufferTexture from "./buffer-texture";
-const WIDTH: number = 150000;
+const TEXT_AVAILABLE_WIDTH: number = 150000;
const PADDING: number = 2000;
const TEXT_DATA_URI: string = "/data/mozmonument.json";
@@ -40,15 +40,19 @@ const FAR_CLIP_PLANE: number = 3000.0;
const SCALE: glmatrix.vec3 = glmatrix.vec3.fromValues(1.0 / 200.0, 1.0 / 200.0, 1.0 / 200.0);
-const TEXT_TRANSLATION: number[] = [-(WIDTH + PADDING) * 0.5, 0.0, (WIDTH + PADDING) * 0.5];
+const TEXT_TRANSLATION: number[] = [
+ -(TEXT_AVAILABLE_WIDTH + PADDING) * 0.5,
+ 0.0,
+ (TEXT_AVAILABLE_WIDTH + PADDING) * 0.5
+];
const TEXT_DECAL_OFFSET: number = 5.0;
const MONUMENT_TRANSLATION: glmatrix.vec3 = glmatrix.vec3.fromValues(0.0, -690.0, 0.0);
const MONUMENT_SCALE: glmatrix.vec3 =
- glmatrix.vec3.fromValues((WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET,
+ glmatrix.vec3.fromValues((TEXT_AVAILABLE_WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET,
700.0,
- (WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET);
+ (TEXT_AVAILABLE_WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET);
const TEXT_COLOR: Uint8Array = new Uint8Array([0xf2, 0xf8, 0xf8, 0xff]);
const MONUMENT_COLOR: number[] = [0x70 / 0xff, 0x80 / 0xff, 0x80 / 0xff];
@@ -147,7 +151,7 @@ class ThreeDController extends DemoAppController {
});
const usedSpace = _.sumBy(lineGlyphs, 'width');
- const emptySpace = Math.max(WIDTH - usedSpace, 0.0);
+ const emptySpace = Math.max(TEXT_AVAILABLE_WIDTH - usedSpace, 0.0);
const spacing = emptySpace / Math.max(lineGlyphs.length - 1, 1);
let currentX = 0.0;
diff --git a/demo/client/src/ecaa-strategy.ts b/demo/client/src/ecaa-strategy.ts
index 31b37643..60522bc5 100644
--- a/demo/client/src/ecaa-strategy.ts
+++ b/demo/client/src/ecaa-strategy.ts
@@ -301,13 +301,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
view.gl.useProgram(coverProgram.program);
view.vertexArrayObjectExt.bindVertexArrayOES(this.coverVAO);
const uniforms = coverProgram.uniforms;
+ view.setTransformSTUniform(uniforms, 0);
view.setFramebufferSizeUniform(uniforms);
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2);
if (view.pathHintsBufferTexture !== null)
view.pathHintsBufferTexture.bind(view.gl, uniforms, 3);
- view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]);
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
6,
view.gl.UNSIGNED_BYTE,
@@ -334,13 +334,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
}
private setAAUniforms(view: MonochromePathfinderView, uniforms: UniformMap) {
+ view.setTransformSTUniform(uniforms, 0);
view.setFramebufferSizeUniform(uniforms);
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2);
if (view.pathHintsBufferTexture !== null)
view.pathHintsBufferTexture.bind(view.gl, uniforms, 3);
- view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]);
}
private antialiasLines(view: MonochromePathfinderView) {
diff --git a/demo/client/src/svg-demo.ts b/demo/client/src/svg-demo.ts
index cd55310c..e38b9fd4 100644
--- a/demo/client/src/svg-demo.ts
+++ b/demo/client/src/svg-demo.ts
@@ -275,15 +275,20 @@ class SVGDemoView extends PathfinderDemoView {
// TODO(pcwalton)
}
- protected get usedSizeFactor(): glmatrix.vec2 {
- return glmatrix.vec2.fromValues(1.0, 1.0);
- }
+ protected usedSizeFactor: glmatrix.vec2 = glmatrix.vec2.fromValues(1.0, 1.0);
protected get worldTransform() {
const transform = glmatrix.mat4.create();
const translation = this.camera.translation;
- glmatrix.mat4.fromTranslation(transform, [translation[0], translation[1], 0]);
+ glmatrix.mat4.translate(transform, transform, [-1.0, -1.0, 0.0]);
+ glmatrix.mat4.scale(transform,
+ transform,
+ [2.0 / this.canvas.width, 2.0 / this.canvas.height, 1.0]);
+ glmatrix.mat4.translate(transform, transform, [translation[0], translation[1], 0]);
glmatrix.mat4.scale(transform, transform, [this.camera.scale, this.camera.scale, 1.0]);
+ if (this.antialiasingStrategy != null)
+ glmatrix.mat4.mul(transform, transform, this.antialiasingStrategy.transform);
+ console.log(transform);
return transform;
}
diff --git a/demo/client/src/text-demo.ts b/demo/client/src/text-demo.ts
index 427bd329..eff2e172 100644
--- a/demo/client/src/text-demo.ts
+++ b/demo/client/src/text-demo.ts
@@ -568,8 +568,11 @@ class TextDemoView extends MonochromePathfinderView {
this.appController.updateTimings(timings);
}
- protected get worldTransform() {
- return glmatrix.mat4.create();
+ protected get worldTransform(): glmatrix.mat4 {
+ const transform = glmatrix.mat4.create();
+ glmatrix.mat4.translate(transform, transform, [-1.0, -1.0, 0.0]);
+ glmatrix.mat4.scale(transform, transform, [2.0 / ATLAS_SIZE[0], 2.0 / ATLAS_SIZE[1], 1.0]);
+ return transform;
}
protected get directCurveProgramName(): keyof ShaderMap {
diff --git a/demo/client/src/view.ts b/demo/client/src/view.ts
index c553f6be..09ce8f65 100644
--- a/demo/client/src/view.ts
+++ b/demo/client/src/view.ts
@@ -295,10 +295,23 @@ export abstract class PathfinderDemoView extends PathfinderView {
protected renderingFinished(): void {}
+ setTransformSTUniform(uniforms: UniformMap, objectIndex: number) {
+ // FIXME(pcwalton): Lossy conversion from a 4x4 matrix to an ST matrix is ugly and fragile.
+ // Refactor.
+ const transform = glmatrix.mat4.clone(this.worldTransform);
+ glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex));
+
+ const translation = glmatrix.vec4.clone([transform[12], transform[13], 0.0, 1.0]);
+
+ this.gl.uniform4f(uniforms.uTransformST,
+ transform[0],
+ transform[5],
+ transform[12],
+ transform[13]);
+ }
+
private setTransformUniform(uniforms: UniformMap, objectIndex: number) {
- const transform = glmatrix.mat4.create();
- if (this.antialiasingStrategy != null)
- glmatrix.mat4.mul(transform, this.antialiasingStrategy.transform, this.worldTransform);
+ const transform = glmatrix.mat4.clone(this.worldTransform);
glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex));
this.gl.uniformMatrix4fv(uniforms.uTransform, false, transform);
}
diff --git a/shaders/gles2/common.inc.glsl b/shaders/gles2/common.inc.glsl
index 71ef2dd5..7186f206 100644
--- a/shaders/gles2/common.inc.glsl
+++ b/shaders/gles2/common.inc.glsl
@@ -48,6 +48,10 @@ vec2 hintPosition(vec2 position, vec4 pathHints) {
return vec2(position.x, position.y / pathHints.x * pathHints.y);
}
+vec2 convertClipToScreenSpace(vec2 position, ivec2 framebufferSize) {
+ return (position + 1.0) * 0.5 * vec2(framebufferSize);
+}
+
vec2 convertScreenToClipSpace(vec2 position, ivec2 framebufferSize) {
return position / vec2(framebufferSize) * 2.0 - 1.0;
}
@@ -65,13 +69,20 @@ bool computeQuadPosition(out vec2 outPosition,
inout vec2 rightPosition,
vec2 quadPosition,
ivec2 framebufferSize,
- vec4 transform,
+ vec4 localTransformST,
+ vec4 globalTransformST,
vec4 hints) {
leftPosition = hintPosition(leftPosition, hints);
rightPosition = hintPosition(rightPosition, hints);
- leftPosition = transformVertexPositionST(leftPosition, transform);
- rightPosition = transformVertexPositionST(rightPosition, transform);
+ leftPosition = transformVertexPositionST(leftPosition, localTransformST);
+ rightPosition = transformVertexPositionST(rightPosition, localTransformST);
+
+ leftPosition = transformVertexPositionST(leftPosition, globalTransformST);
+ rightPosition = transformVertexPositionST(rightPosition, globalTransformST);
+
+ leftPosition = convertClipToScreenSpace(leftPosition, framebufferSize);
+ rightPosition = convertClipToScreenSpace(rightPosition, framebufferSize);
if (abs(leftPosition.x - rightPosition.x) <= EPSILON) {
outPosition = vec2(0.0);
diff --git a/shaders/gles2/direct-curve.vs.glsl b/shaders/gles2/direct-curve.vs.glsl
index e61a626e..b70a1326 100644
--- a/shaders/gles2/direct-curve.vs.glsl
+++ b/shaders/gles2/direct-curve.vs.glsl
@@ -5,7 +5,6 @@
precision highp float;
uniform mat4 uTransform;
-uniform ivec2 uFramebufferSize;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform ivec2 uPathHintsDimensions;
@@ -32,7 +31,6 @@ void main() {
vec2 position = hintPosition(aPosition, pathHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPosition(position, uTransform);
- position = convertScreenToClipSpace(position, uFramebufferSize);
float depth = convertPathIndexToViewportDepthValue(pathID);
gl_Position = vec4(position, depth, 1.0);
diff --git a/shaders/gles2/direct-interior.vs.glsl b/shaders/gles2/direct-interior.vs.glsl
index e2e2466e..3b2d410d 100644
--- a/shaders/gles2/direct-interior.vs.glsl
+++ b/shaders/gles2/direct-interior.vs.glsl
@@ -5,7 +5,6 @@
precision highp float;
uniform mat4 uTransform;
-uniform ivec2 uFramebufferSize;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform ivec2 uPathHintsDimensions;
@@ -28,7 +27,6 @@ void main() {
vec2 position = hintPosition(aPosition, pathHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPosition(position, uTransform);
- position = convertScreenToClipSpace(position, uFramebufferSize);
float depth = convertPathIndexToViewportDepthValue(pathID);
gl_Position = vec4(position, depth, 1.0);
diff --git a/shaders/gles2/ecaa-cover.vs.glsl b/shaders/gles2/ecaa-cover.vs.glsl
index e1d2b49c..e229e3cc 100644
--- a/shaders/gles2/ecaa-cover.vs.glsl
+++ b/shaders/gles2/ecaa-cover.vs.glsl
@@ -4,8 +4,8 @@
precision highp float;
+uniform vec4 uTransformST;
uniform ivec2 uFramebufferSize;
-uniform float uScaleX;
uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexPathIDDimensions;
uniform ivec2 uPathTransformDimensions;
@@ -45,7 +45,6 @@ void main() {
vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
- transform.xz *= uScaleX;
upperLeftPosition = hintPosition(upperLeftPosition, hints);
upperRightPosition = hintPosition(upperRightPosition, hints);
@@ -57,6 +56,16 @@ void main() {
lowerLeftPosition = transformVertexPositionST(lowerLeftPosition, transform);
lowerRightPosition = transformVertexPositionST(lowerRightPosition, transform);
+ upperLeftPosition = transformVertexPositionST(upperLeftPosition, uTransformST);
+ upperRightPosition = transformVertexPositionST(upperRightPosition, uTransformST);
+ lowerLeftPosition = transformVertexPositionST(lowerLeftPosition, uTransformST);
+ lowerRightPosition = transformVertexPositionST(lowerRightPosition, uTransformST);
+
+ upperLeftPosition = convertClipToScreenSpace(upperLeftPosition, uFramebufferSize);
+ upperRightPosition = convertClipToScreenSpace(upperRightPosition, uFramebufferSize);
+ lowerLeftPosition = convertClipToScreenSpace(lowerLeftPosition, uFramebufferSize);
+ lowerRightPosition = convertClipToScreenSpace(lowerRightPosition, uFramebufferSize);
+
vec4 extents = vec4(min(upperLeftPosition.x, lowerLeftPosition.x),
min(min(upperLeftPosition.y, upperRightPosition.y),
min(lowerLeftPosition.y, lowerRightPosition.y)),
diff --git a/shaders/gles2/ecaa-curve.vs.glsl b/shaders/gles2/ecaa-curve.vs.glsl
index bfa4ac83..a4d6938b 100644
--- a/shaders/gles2/ecaa-curve.vs.glsl
+++ b/shaders/gles2/ecaa-curve.vs.glsl
@@ -4,8 +4,8 @@
precision highp float;
+uniform vec4 uTransformST;
uniform ivec2 uFramebufferSize;
-uniform float uScaleX;
uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexPathIDDimensions;
uniform ivec2 uPathTransformDimensions;
@@ -42,7 +42,6 @@ void main() {
vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
- transform.xz *= uScaleX;
// Transform the points, and compute the position of this vertex.
vec2 position;
@@ -52,9 +51,12 @@ void main() {
aQuadPosition,
uFramebufferSize,
transform,
+ uTransformST,
hints)) {
controlPointPosition = hintPosition(controlPointPosition, hints);
controlPointPosition = transformVertexPositionST(controlPointPosition, transform);
+ controlPointPosition = transformVertexPositionST(controlPointPosition, uTransformST);
+ controlPointPosition = convertClipToScreenSpace(controlPointPosition, uFramebufferSize);
}
float depth = convertPathIndexToViewportDepthValue(pathID);
diff --git a/shaders/gles2/ecaa-line.vs.glsl b/shaders/gles2/ecaa-line.vs.glsl
index c751334e..8e49c81c 100644
--- a/shaders/gles2/ecaa-line.vs.glsl
+++ b/shaders/gles2/ecaa-line.vs.glsl
@@ -4,8 +4,7 @@
precision highp float;
-uniform mat4 uTransform;
-uniform float uScaleX;
+uniform vec4 uTransformST;
uniform ivec2 uFramebufferSize;
uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexPathIDDimensions;
@@ -37,7 +36,6 @@ void main() {
vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
- transform.xz *= uScaleX;
// Transform the points, and compute the position of this vertex.
vec2 position;
@@ -47,6 +45,7 @@ void main() {
aQuadPosition,
uFramebufferSize,
transform,
+ uTransformST,
hints);
float depth = convertPathIndexToViewportDepthValue(pathID);