Implement basic working 3D support
This commit is contained in:
parent
a599db4eb9
commit
4b7ac0182c
|
@ -29,7 +29,9 @@ const PIXELS_PER_UNIT: number = 1.0;
|
||||||
|
|
||||||
const FOV: number = 45.0;
|
const FOV: number = 45.0;
|
||||||
const NEAR_CLIP_PLANE: number = 0.01;
|
const NEAR_CLIP_PLANE: number = 0.01;
|
||||||
const FAR_CLIP_PLANE: number = 1000.0;
|
const FAR_CLIP_PLANE: number = 10000.0;
|
||||||
|
|
||||||
|
const SCALE: glmatrix.vec3 = glmatrix.vec3.fromValues(1.0 / 50.0, 1.0 / 50.0, 1.0);
|
||||||
|
|
||||||
const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
||||||
none: NoAAStrategy,
|
none: NoAAStrategy,
|
||||||
|
@ -142,17 +144,31 @@ class ThreeDView extends PathfinderDemoView {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get worldTransform() {
|
protected get worldTransform() {
|
||||||
const transform = glmatrix.mat4.create();
|
const projection = glmatrix.mat4.create();
|
||||||
glmatrix.mat4.perspective(transform,
|
glmatrix.mat4.perspective(projection,
|
||||||
FOV / 180.0 * Math.PI,
|
FOV / 180.0 * Math.PI,
|
||||||
this.canvas.width / this.canvas.height,
|
this.canvas.width / this.canvas.height,
|
||||||
NEAR_CLIP_PLANE,
|
NEAR_CLIP_PLANE,
|
||||||
FAR_CLIP_PLANE);
|
FAR_CLIP_PLANE);
|
||||||
glmatrix.mat4.mul(transform, transform, this.camera.rotationMatrix);
|
|
||||||
glmatrix.mat4.translate(transform, transform, this.camera.translation);
|
const modelview = glmatrix.mat4.create();
|
||||||
|
glmatrix.mat4.mul(modelview, modelview, this.camera.rotationMatrix);
|
||||||
|
glmatrix.mat4.translate(modelview, modelview, this.camera.translation);
|
||||||
|
glmatrix.mat4.scale(modelview, modelview, SCALE);
|
||||||
|
|
||||||
|
const transform = glmatrix.mat4.create();
|
||||||
|
glmatrix.mat4.mul(transform, projection, modelview);
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get directCurveProgramName(): keyof ShaderMap<void> {
|
||||||
|
return 'direct3DCurve';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get directInteriorProgramName(): keyof ShaderMap<void> {
|
||||||
|
return 'direct3DInterior';
|
||||||
|
}
|
||||||
|
|
||||||
private _scale: number;
|
private _scale: number;
|
||||||
|
|
||||||
private appController: ThreeDController;
|
private appController: ThreeDController;
|
||||||
|
|
|
@ -18,6 +18,8 @@ const PERSPECTIVE_ROTATION_SPEED: number = 1.0 / 300.0;
|
||||||
|
|
||||||
const MOVEMENT_INTERVAL_DELAY: number = 10;
|
const MOVEMENT_INTERVAL_DELAY: number = 10;
|
||||||
|
|
||||||
|
const INITIAL_TRANSLATION: glmatrix.vec3 = glmatrix.vec3.fromValues(0.0, 0.0, -1000.0);
|
||||||
|
|
||||||
export abstract class Camera {
|
export abstract class Camera {
|
||||||
constructor(canvas: HTMLCanvasElement) {
|
constructor(canvas: HTMLCanvasElement) {
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
|
@ -83,7 +85,7 @@ export class PerspectiveCamera extends Camera {
|
||||||
constructor(canvas: HTMLCanvasElement) {
|
constructor(canvas: HTMLCanvasElement) {
|
||||||
super(canvas);
|
super(canvas);
|
||||||
|
|
||||||
this.translation = glmatrix.vec3.create();
|
this.translation = glmatrix.vec3.clone(INITIAL_TRANSLATION);
|
||||||
this.rotation = glmatrix.vec2.create();
|
this.rotation = glmatrix.vec2.create();
|
||||||
this.movementDelta = glmatrix.vec3.create();
|
this.movementDelta = glmatrix.vec3.create();
|
||||||
this.movementInterval = null;
|
this.movementInterval = null;
|
||||||
|
@ -133,8 +135,8 @@ export class PerspectiveCamera extends Camera {
|
||||||
if (document.pointerLockElement !== this.canvas)
|
if (document.pointerLockElement !== this.canvas)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.rotation[0] += event.movementY * PERSPECTIVE_ROTATION_SPEED;
|
|
||||||
this.rotation[1] += event.movementX * PERSPECTIVE_ROTATION_SPEED;
|
this.rotation[1] += event.movementX * PERSPECTIVE_ROTATION_SPEED;
|
||||||
|
this.rotation[0] += event.movementY * PERSPECTIVE_ROTATION_SPEED;
|
||||||
|
|
||||||
if (this.onChange != null)
|
if (this.onChange != null)
|
||||||
this.onChange();
|
this.onChange();
|
||||||
|
@ -142,8 +144,8 @@ export class PerspectiveCamera extends Camera {
|
||||||
|
|
||||||
get rotationMatrix(): glmatrix.mat4 {
|
get rotationMatrix(): glmatrix.mat4 {
|
||||||
const matrix = glmatrix.mat4.create();
|
const matrix = glmatrix.mat4.create();
|
||||||
glmatrix.mat4.fromXRotation(matrix, this.rotation[0]);
|
glmatrix.mat4.fromYRotation(matrix, this.rotation[1]);
|
||||||
glmatrix.mat4.rotateY(matrix, matrix, this.rotation[1]);
|
glmatrix.mat4.rotateX(matrix, matrix, this.rotation[0]);
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ export const SHADER_NAMES: Array<keyof ShaderMap<void>> = [
|
||||||
'blit',
|
'blit',
|
||||||
'directCurve',
|
'directCurve',
|
||||||
'directInterior',
|
'directInterior',
|
||||||
|
'direct3DCurve',
|
||||||
|
'direct3DInterior',
|
||||||
'ecaaEdgeDetect',
|
'ecaaEdgeDetect',
|
||||||
'ecaaCover',
|
'ecaaCover',
|
||||||
'ecaaLine',
|
'ecaaLine',
|
||||||
|
@ -44,6 +46,14 @@ const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
|
||||||
vertex: "/glsl/gles2/direct-interior.vs.glsl",
|
vertex: "/glsl/gles2/direct-interior.vs.glsl",
|
||||||
fragment: "/glsl/gles2/direct-interior.fs.glsl",
|
fragment: "/glsl/gles2/direct-interior.fs.glsl",
|
||||||
},
|
},
|
||||||
|
direct3DCurve: {
|
||||||
|
vertex: "/glsl/gles2/direct-3d-curve.vs.glsl",
|
||||||
|
fragment: "/glsl/gles2/direct-curve.fs.glsl",
|
||||||
|
},
|
||||||
|
direct3DInterior: {
|
||||||
|
vertex: "/glsl/gles2/direct-3d-interior.vs.glsl",
|
||||||
|
fragment: "/glsl/gles2/direct-interior.fs.glsl",
|
||||||
|
},
|
||||||
ecaaEdgeDetect: {
|
ecaaEdgeDetect: {
|
||||||
vertex: "/glsl/gles2/ecaa-edge-detect.vs.glsl",
|
vertex: "/glsl/gles2/ecaa-edge-detect.vs.glsl",
|
||||||
fragment: "/glsl/gles2/ecaa-edge-detect.fs.glsl",
|
fragment: "/glsl/gles2/ecaa-edge-detect.fs.glsl",
|
||||||
|
@ -78,6 +88,8 @@ export interface ShaderMap<T> {
|
||||||
blit: T;
|
blit: T;
|
||||||
directCurve: T;
|
directCurve: T;
|
||||||
directInterior: T;
|
directInterior: T;
|
||||||
|
direct3DCurve: T;
|
||||||
|
direct3DInterior: T;
|
||||||
ecaaEdgeDetect: T;
|
ecaaEdgeDetect: T;
|
||||||
ecaaCover: T;
|
ecaaCover: T;
|
||||||
ecaaLine: T;
|
ecaaLine: T;
|
||||||
|
|
|
@ -235,6 +235,14 @@ class SVGDemoView extends PathfinderDemoView {
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get directCurveProgramName(): keyof ShaderMap<void> {
|
||||||
|
return 'directCurve';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get directInteriorProgramName(): keyof ShaderMap<void> {
|
||||||
|
return 'directInterior';
|
||||||
|
}
|
||||||
|
|
||||||
private appController: SVGDemoController;
|
private appController: SVGDemoController;
|
||||||
|
|
||||||
camera: OrthographicCamera;
|
camera: OrthographicCamera;
|
||||||
|
|
|
@ -490,6 +490,14 @@ class TextDemoView extends MonochromePathfinderView {
|
||||||
return glmatrix.mat4.create();
|
return glmatrix.mat4.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get directCurveProgramName(): keyof ShaderMap<void> {
|
||||||
|
return 'directCurve';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get directInteriorProgramName(): keyof ShaderMap<void> {
|
||||||
|
return 'directInterior';
|
||||||
|
}
|
||||||
|
|
||||||
atlasFramebuffer: WebGLFramebuffer;
|
atlasFramebuffer: WebGLFramebuffer;
|
||||||
atlasDepthTexture: WebGLTexture;
|
atlasDepthTexture: WebGLTexture;
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
||||||
this.gl.disable(this.gl.BLEND);
|
this.gl.disable(this.gl.BLEND);
|
||||||
|
|
||||||
// Set up the implicit cover interior VAO.
|
// Set up the implicit cover interior VAO.
|
||||||
const directInteriorProgram = this.shaderPrograms.directInterior;
|
const directInteriorProgram = this.shaderPrograms[this.directInteriorProgramName];
|
||||||
this.gl.useProgram(directInteriorProgram.program);
|
this.gl.useProgram(directInteriorProgram.program);
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
||||||
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPosition,
|
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPosition,
|
||||||
|
@ -315,7 +315,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
||||||
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
|
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
// Set up the direct curve VAO.
|
// Set up the direct curve VAO.
|
||||||
const directCurveProgram = this.shaderPrograms.directCurve;
|
const directCurveProgram = this.shaderPrograms[this.directCurveProgramName];
|
||||||
this.gl.useProgram(directCurveProgram.program);
|
this.gl.useProgram(directCurveProgram.program);
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
||||||
this.gl.vertexAttribPointer(directCurveProgram.attributes.aPosition,
|
this.gl.vertexAttribPointer(directCurveProgram.attributes.aPosition,
|
||||||
|
@ -425,6 +425,9 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
||||||
|
|
||||||
protected abstract get worldTransform(): glmatrix.mat4;
|
protected abstract get worldTransform(): glmatrix.mat4;
|
||||||
|
|
||||||
|
protected abstract get directCurveProgramName(): keyof ShaderMap<void>;
|
||||||
|
protected abstract get directInteriorProgramName(): keyof ShaderMap<void>;
|
||||||
|
|
||||||
protected antialiasingStrategy: AntialiasingStrategy | null;
|
protected antialiasingStrategy: AntialiasingStrategy | null;
|
||||||
|
|
||||||
gl: WebGLRenderingContext;
|
gl: WebGLRenderingContext;
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// pathfinder/shaders/gles2/direct-3d-curve.vs.glsl
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform mat4 uTransform;
|
||||||
|
uniform ivec2 uPathColorsDimensions;
|
||||||
|
uniform ivec2 uPathTransformDimensions;
|
||||||
|
uniform sampler2D uPathColors;
|
||||||
|
uniform sampler2D uPathTransform;
|
||||||
|
|
||||||
|
attribute vec2 aPosition;
|
||||||
|
attribute vec2 aTexCoord;
|
||||||
|
attribute float aPathID;
|
||||||
|
attribute float aSign;
|
||||||
|
|
||||||
|
varying vec4 vColor;
|
||||||
|
varying vec2 vPathID;
|
||||||
|
varying vec2 vTexCoord;
|
||||||
|
varying float vSign;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
int pathID = int(aPathID);
|
||||||
|
|
||||||
|
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
||||||
|
|
||||||
|
vec2 position = transformVertexPositionST(aPosition, pathTransform);
|
||||||
|
|
||||||
|
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
||||||
|
|
||||||
|
vColor = fetchFloat4Data(uPathColors, pathID, uPathColorsDimensions);
|
||||||
|
vPathID = packPathID(pathID);
|
||||||
|
vTexCoord = vec2(aTexCoord) / 2.0;
|
||||||
|
vSign = aSign;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// pathfinder/shaders/gles2/direct-3d-interior.vs.glsl
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform mat4 uTransform;
|
||||||
|
uniform ivec2 uPathColorsDimensions;
|
||||||
|
uniform ivec2 uPathTransformDimensions;
|
||||||
|
uniform sampler2D uPathColors;
|
||||||
|
uniform sampler2D uPathTransform;
|
||||||
|
|
||||||
|
attribute vec2 aPosition;
|
||||||
|
attribute float aPathID;
|
||||||
|
|
||||||
|
varying vec4 vColor;
|
||||||
|
varying vec2 vPathID;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
int pathID = int(aPathID);
|
||||||
|
|
||||||
|
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
|
||||||
|
|
||||||
|
vec2 position = transformVertexPositionST(aPosition, pathTransform);
|
||||||
|
|
||||||
|
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
||||||
|
|
||||||
|
vColor = fetchFloat4Data(uPathColors, pathID, uPathColorsDimensions);
|
||||||
|
vPathID = packPathID(pathID);
|
||||||
|
}
|
Loading…
Reference in New Issue