Get basic polygons rendering in the demo
This commit is contained in:
parent
5f89f7ba50
commit
f8bd405759
|
@ -3,14 +3,30 @@
|
||||||
const base64js = require('base64-js');
|
const base64js = require('base64-js');
|
||||||
const opentype = require('opentype.js');
|
const opentype = require('opentype.js');
|
||||||
|
|
||||||
const TEXT: string = "A";
|
const TEXT: string = "G";
|
||||||
const FONT_SIZE: number = 16.0;
|
const FONT_SIZE: number = 16.0;
|
||||||
|
|
||||||
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
|
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
|
||||||
|
|
||||||
const COMMON_SHADER_URL: string = '/glsl/gles2/common.inc.glsl';
|
const COMMON_SHADER_URL: string = '/glsl/gles2/common.inc.glsl';
|
||||||
|
|
||||||
const SHADER_URLS: ShaderURLMap = {
|
const UINT32_SIZE: number = 4;
|
||||||
|
|
||||||
|
const B_POSITION_SIZE: number = 8;
|
||||||
|
|
||||||
|
const B_VERTEX_QUAD_SIZE: number = 8;
|
||||||
|
const B_VERTEX_QUAD_PATH_ID_OFFSET: number = 0;
|
||||||
|
const B_VERTEX_QUAD_TEX_COORD_OFFSET: number = 4;
|
||||||
|
const B_VERTEX_QUAD_SIGN_OFFSET: number = 6;
|
||||||
|
|
||||||
|
const IDENTITY: Matrix4D = [
|
||||||
|
1.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 1.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 1.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 1.0,
|
||||||
|
];
|
||||||
|
|
||||||
|
const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
|
||||||
directCurve: {
|
directCurve: {
|
||||||
vertex: "/glsl/gles2/direct-curve.vs.glsl",
|
vertex: "/glsl/gles2/direct-curve.vs.glsl",
|
||||||
fragment: "/glsl/gles2/direct-curve.fs.glsl",
|
fragment: "/glsl/gles2/direct-curve.fs.glsl",
|
||||||
|
@ -21,16 +37,34 @@ const SHADER_URLS: ShaderURLMap = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ShaderURLMap {
|
interface UnlinkedShaderProgram {
|
||||||
[shaderName: string]: { 'vertex': string, 'fragment': string };
|
vertex: WebGLShader;
|
||||||
|
fragment: WebGLShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ShaderMap {
|
type Matrix4D = number[];
|
||||||
[shaderName: string]: { [shaderType: number]: WebGLShader };
|
|
||||||
|
interface ShaderProgramSource {
|
||||||
|
vertex: string;
|
||||||
|
fragment: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ShaderProgramMap {
|
interface ShaderProgramURLs {
|
||||||
[shaderProgramName: string]: PathfinderShaderProgram;
|
vertex: string;
|
||||||
|
fragment: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ShaderMap<T> {
|
||||||
|
directCurve: T;
|
||||||
|
directInterior: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UniformMap {
|
||||||
|
[uniformName: string]: WebGLUniformLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AttributeMap {
|
||||||
|
[attributeName: string]: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShaderType = number;
|
type ShaderType = number;
|
||||||
|
@ -43,26 +77,91 @@ function expect<T>(value: T | null, message: string): T {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function unwrap<T>(value: T | null): T {
|
||||||
|
return expect(value, "Unexpected null!");
|
||||||
|
}
|
||||||
|
|
||||||
class PathfinderError extends Error {
|
class PathfinderError extends Error {
|
||||||
constructor(message?: string | undefined) {
|
constructor(message?: string | undefined) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PathfinderMeshes {
|
interface Meshes<T> {
|
||||||
|
readonly bQuads: T;
|
||||||
|
readonly bVertexPositions: T;
|
||||||
|
readonly bVertexInfo: T;
|
||||||
|
readonly coverInteriorIndices: T;
|
||||||
|
readonly coverCurveIndices: T;
|
||||||
|
readonly edgeUpperLineIndices: T;
|
||||||
|
readonly edgeUpperCurveIndices: T;
|
||||||
|
readonly edgeLowerLineIndices: T;
|
||||||
|
readonly edgeLowerCurveIndices: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
type BufferType = number;
|
||||||
|
|
||||||
|
const BUFFER_TYPES: Meshes<BufferType> = {
|
||||||
|
bQuads: WebGLRenderingContext.ARRAY_BUFFER,
|
||||||
|
bVertexPositions: WebGLRenderingContext.ARRAY_BUFFER,
|
||||||
|
bVertexInfo: WebGLRenderingContext.ARRAY_BUFFER,
|
||||||
|
coverInteriorIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
|
||||||
|
coverCurveIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
|
||||||
|
edgeUpperLineIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
|
||||||
|
edgeUpperCurveIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
|
||||||
|
edgeLowerLineIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
|
||||||
|
edgeLowerCurveIndices: WebGLRenderingContext.ELEMENT_ARRAY_BUFFER,
|
||||||
|
};
|
||||||
|
|
||||||
|
class PathfinderMeshData implements Meshes<ArrayBuffer> {
|
||||||
constructor(encodedResponse: string) {
|
constructor(encodedResponse: string) {
|
||||||
const response = JSON.parse(encodedResponse);
|
const response = JSON.parse(encodedResponse);
|
||||||
if (!('Ok' in response))
|
if (!('Ok' in response))
|
||||||
throw new PathfinderError("Failed to partition the font!");
|
throw new PathfinderError("Failed to partition the font!");
|
||||||
const meshes = response.Ok;
|
const meshes = response.Ok;
|
||||||
this.bQuadPositions = base64js.toByteArray(meshes.bQuadPositions);
|
for (const bufferName of Object.keys(BUFFER_TYPES) as Array<keyof PathfinderMeshData>)
|
||||||
this.bQuadInfo = base64js.toByteArray(meshes.bQuadInfo);
|
this[bufferName] = base64js.toByteArray(meshes[bufferName]).buffer;
|
||||||
this.bVertices = base64js.toByteArray(meshes.bVertices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bQuadPositions: ArrayBuffer;
|
readonly bQuads: ArrayBuffer;
|
||||||
bQuadInfo: ArrayBuffer;
|
readonly bVertexPositions: ArrayBuffer;
|
||||||
bVertices: ArrayBuffer;
|
readonly bVertexInfo: ArrayBuffer;
|
||||||
|
readonly coverInteriorIndices: ArrayBuffer;
|
||||||
|
readonly coverCurveIndices: ArrayBuffer;
|
||||||
|
readonly edgeUpperLineIndices: ArrayBuffer;
|
||||||
|
readonly edgeUpperCurveIndices: ArrayBuffer;
|
||||||
|
readonly edgeLowerLineIndices: ArrayBuffer;
|
||||||
|
readonly edgeLowerCurveIndices: ArrayBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PathfinderMeshBuffers implements Meshes<WebGLBuffer> {
|
||||||
|
constructor(gl: WebGLRenderingContext, meshData: PathfinderMeshData) {
|
||||||
|
for (const bufferName of Object.keys(BUFFER_TYPES) as Array<keyof PathfinderMeshBuffers>) {
|
||||||
|
const bufferType = BUFFER_TYPES[bufferName];
|
||||||
|
const buffer = expect(gl.createBuffer(), "Failed to create buffer!");
|
||||||
|
gl.bindBuffer(bufferType, buffer);
|
||||||
|
gl.bufferData(bufferType, meshData[bufferName], gl.STATIC_DRAW);
|
||||||
|
console.log(`${bufferName} has size ${meshData[bufferName].byteLength}`);
|
||||||
|
if (bufferName == 'coverInteriorIndices') {
|
||||||
|
const typedArray = new Uint32Array(meshData[bufferName]);
|
||||||
|
let array = [];
|
||||||
|
for (let i = 0; i < typedArray.length; i++)
|
||||||
|
array[i] = typedArray[i];
|
||||||
|
console.log(array.toString());
|
||||||
|
}
|
||||||
|
this[bufferName] = buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly bQuads: WebGLBuffer;
|
||||||
|
readonly bVertexPositions: WebGLBuffer;
|
||||||
|
readonly bVertexInfo: WebGLBuffer;
|
||||||
|
readonly coverInteriorIndices: WebGLBuffer;
|
||||||
|
readonly coverCurveIndices: WebGLBuffer;
|
||||||
|
readonly edgeUpperLineIndices: WebGLBuffer;
|
||||||
|
readonly edgeUpperCurveIndices: WebGLBuffer;
|
||||||
|
readonly edgeLowerLineIndices: WebGLBuffer;
|
||||||
|
readonly edgeLowerCurveIndices: WebGLBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppController {
|
class AppController {
|
||||||
|
@ -105,21 +204,21 @@ class AppController {
|
||||||
body: JSON.stringify(request),
|
body: JSON.stringify(request),
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
response.text().then((encodedMeshes) => {
|
response.text().then((encodedMeshes) => {
|
||||||
this.meshes = new PathfinderMeshes(encodedMeshes);
|
this.meshes = new PathfinderMeshData(encodedMeshes);
|
||||||
this.meshesReceived();
|
this.meshesReceived();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
meshesReceived() {
|
meshesReceived() {
|
||||||
// TODO(pcwalton)
|
this.view.attachMeshes(this.meshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
view: PathfinderView;
|
view: PathfinderView;
|
||||||
loadFontButton: HTMLInputElement;
|
loadFontButton: HTMLInputElement;
|
||||||
fontData: ArrayBuffer;
|
fontData: ArrayBuffer;
|
||||||
font: any;
|
font: any;
|
||||||
meshes: PathfinderMeshes;
|
meshes: PathfinderMeshData;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PathfinderView {
|
class PathfinderView {
|
||||||
|
@ -137,18 +236,15 @@ class PathfinderView {
|
||||||
initContext() {
|
initContext() {
|
||||||
this.gl = expect(this.canvas.getContext('webgl', { antialias: false, depth: true }),
|
this.gl = expect(this.canvas.getContext('webgl', { antialias: false, depth: true }),
|
||||||
"Failed to initialize WebGL! Check that your browser supports it.");
|
"Failed to initialize WebGL! Check that your browser supports it.");
|
||||||
|
this.gl.getExtension('OES_element_index_uint');
|
||||||
this.gl.clearColor(0.0, 0.0, 1.0, 1.0);
|
|
||||||
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
||||||
this.gl.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadShaders(): Promise<ShaderMap> {
|
loadShaders(): Promise<ShaderMap<UnlinkedShaderProgram>> {
|
||||||
let shaders: ShaderMap = {};
|
let shaders: Partial<ShaderMap<Partial<UnlinkedShaderProgram>>> = {};
|
||||||
return window.fetch(COMMON_SHADER_URL)
|
return window.fetch(COMMON_SHADER_URL)
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((commonSource) => {
|
.then((commonSource) => {
|
||||||
const shaderKeys = Object.keys(SHADER_URLS);
|
const shaderKeys = Object.keys(SHADER_URLS) as Array<keyof ShaderMap<string>>;
|
||||||
|
|
||||||
let promises = [];
|
let promises = [];
|
||||||
for (const shaderKey of shaderKeys) {
|
for (const shaderKey of shaderKeys) {
|
||||||
|
@ -173,53 +269,150 @@ class PathfinderView {
|
||||||
`"${shaderKey}":\n${infoLog}`);
|
`"${shaderKey}":\n${infoLog}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(shaderKey in shaders))
|
if (shaders[shaderKey] == null)
|
||||||
shaders[shaderKey] = {};
|
shaders[shaderKey] = {};
|
||||||
shaders[shaderKey][type] = shader;
|
shaders[shaderKey]![typeName] = shader;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}).then(() => shaders);
|
}).then(() => shaders as ShaderMap<UnlinkedShaderProgram>);
|
||||||
}
|
}
|
||||||
|
|
||||||
linkShaders(shaders: ShaderMap): Promise<ShaderProgramMap> {
|
linkShaders(shaders: ShaderMap<UnlinkedShaderProgram>):
|
||||||
|
Promise<ShaderMap<PathfinderShaderProgram>> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let shaderProgramMap: ShaderProgramMap = {};
|
let shaderProgramMap: Partial<ShaderMap<PathfinderShaderProgram>> = {};
|
||||||
for (const shaderKey of Object.keys(shaders)) {
|
for (const shaderName of Object.keys(shaders) as
|
||||||
const program = expect(this.gl.createProgram(), "Failed to create shader program!");
|
Array<keyof ShaderMap<UnlinkedShaderProgram>>) {
|
||||||
const compiledShaders = shaders[shaderKey];
|
shaderProgramMap[shaderName] = new PathfinderShaderProgram(this.gl,
|
||||||
for (const compiledShader of Object.values(compiledShaders))
|
shaderName,
|
||||||
this.gl.attachShader(program, compiledShader);
|
shaders[shaderName]);
|
||||||
this.gl.linkProgram(program);
|
|
||||||
|
|
||||||
if (this.gl.getProgramParameter(program, this.gl.LINK_STATUS) == 0) {
|
|
||||||
const infoLog = this.gl.getProgramInfoLog(program);
|
|
||||||
throw new PathfinderError(`Failed to link program "${program}":\n${infoLog}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderProgramMap[shaderKey] = program;
|
resolve(shaderProgramMap as ShaderMap<PathfinderShaderProgram>);
|
||||||
}
|
|
||||||
|
|
||||||
resolve(shaderProgramMap);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attachMeshes(meshes: PathfinderMeshData) {
|
||||||
|
this.meshes = new PathfinderMeshBuffers(this.gl, meshes);
|
||||||
|
this.setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
setDirty() {
|
||||||
|
if (this.dirty)
|
||||||
|
return;
|
||||||
|
this.dirty = true;
|
||||||
|
window.requestAnimationFrame(() => this.redraw());
|
||||||
|
}
|
||||||
|
|
||||||
resizeToFit() {
|
resizeToFit() {
|
||||||
this.canvas.width = window.innerWidth;
|
const width = window.innerWidth, height = window.innerHeight - this.canvas.scrollTop;
|
||||||
this.canvas.height = window.innerHeight - this.canvas.scrollTop;
|
const devicePixelRatio = window.devicePixelRatio;
|
||||||
|
this.canvas.style.width = width + 'px';
|
||||||
|
this.canvas.style.height = height + 'px';
|
||||||
|
this.canvas.width = width * devicePixelRatio;
|
||||||
|
this.canvas.height = height * devicePixelRatio;
|
||||||
|
this.setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw() {
|
||||||
|
this.shaderProgramsPromise.then((shaderPrograms: ShaderMap<PathfinderShaderProgram>) => {
|
||||||
|
if (this.meshes == null) {
|
||||||
|
this.dirty = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear.
|
||||||
|
this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||||
|
this.gl.clearDepth(0.0);
|
||||||
|
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
// Set up the depth buffer.
|
||||||
|
this.gl.depthFunc(this.gl.GREATER);
|
||||||
|
this.gl.enable(this.gl.DEPTH_TEST);
|
||||||
|
|
||||||
|
// Set up the implicit cover interior VAO.
|
||||||
|
const directInteriorProgram = shaderPrograms.directInterior;
|
||||||
|
this.gl.useProgram(directInteriorProgram.program);
|
||||||
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
||||||
|
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPosition,
|
||||||
|
2,
|
||||||
|
this.gl.FLOAT,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexInfo);
|
||||||
|
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPathDepth,
|
||||||
|
1,
|
||||||
|
this.gl.UNSIGNED_SHORT, // FIXME(pcwalton)
|
||||||
|
true,
|
||||||
|
B_VERTEX_QUAD_SIZE,
|
||||||
|
B_VERTEX_QUAD_PATH_ID_OFFSET);
|
||||||
|
this.gl.enableVertexAttribArray(directInteriorProgram.attributes.aPosition);
|
||||||
|
this.gl.enableVertexAttribArray(directInteriorProgram.attributes.aPathDepth);
|
||||||
|
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.meshes.coverInteriorIndices);
|
||||||
|
|
||||||
|
// Draw direct interior parts.
|
||||||
|
this.gl.uniformMatrix4fv(directInteriorProgram.uniforms.uTransform, false, IDENTITY);
|
||||||
|
this.gl.uniform2i(directInteriorProgram.uniforms.uFramebufferSize,
|
||||||
|
this.canvas.width,
|
||||||
|
this.canvas.height);
|
||||||
|
const triangleCount =
|
||||||
|
this.gl.getBufferParameter(this.gl.ELEMENT_ARRAY_BUFFER, this.gl.BUFFER_SIZE) /
|
||||||
|
UINT32_SIZE;
|
||||||
|
this.gl.drawElements(this.gl.TRIANGLES, triangleCount, this.gl.UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
// Clear dirty bit and finish.
|
||||||
|
this.dirty = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas: HTMLCanvasElement;
|
canvas: HTMLCanvasElement;
|
||||||
gl: WebGLRenderingContext;
|
gl: WebGLRenderingContext;
|
||||||
shaderProgramsPromise: Promise<ShaderProgramMap>;
|
shaderProgramsPromise: Promise<ShaderMap<PathfinderShaderProgram>>;
|
||||||
|
meshes: PathfinderMeshBuffers;
|
||||||
|
dirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PathfinderShaderProgram {
|
class PathfinderShaderProgram {
|
||||||
constructor(vertexShader: WebGLShader, fragmentShader: WebGLShader) {
|
constructor(gl: WebGLRenderingContext,
|
||||||
// TODO(pcwalton)
|
programName: string,
|
||||||
|
unlinkedShaderProgram: UnlinkedShaderProgram) {
|
||||||
|
this.program = expect(gl.createProgram(), "Failed to create shader program!");
|
||||||
|
for (const compiledShader of Object.values(unlinkedShaderProgram))
|
||||||
|
gl.attachShader(this.program, compiledShader);
|
||||||
|
gl.linkProgram(this.program);
|
||||||
|
|
||||||
|
if (gl.getProgramParameter(this.program, gl.LINK_STATUS) == 0) {
|
||||||
|
const infoLog = gl.getProgramInfoLog(this.program);
|
||||||
|
throw new PathfinderError(`Failed to link program "${programName}":\n${infoLog}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);
|
||||||
|
const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);
|
||||||
|
|
||||||
|
let uniforms: UniformMap = {};
|
||||||
|
let attributes: AttributeMap = {};
|
||||||
|
|
||||||
|
for (let uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) {
|
||||||
|
const uniformName = unwrap(gl.getActiveUniform(this.program, uniformIndex)).name;
|
||||||
|
uniforms[uniformName] = expect(gl.getUniformLocation(this.program, uniformName),
|
||||||
|
`Didn't find uniform "${uniformName}"!`);
|
||||||
|
}
|
||||||
|
for (let attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++) {
|
||||||
|
const attributeName = unwrap(gl.getActiveAttrib(this.program, attributeIndex)).name;
|
||||||
|
attributes[attributeName] = attributeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.uniforms = uniforms;
|
||||||
|
this.attributes = attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly uniforms: UniformMap;
|
||||||
|
readonly attributes: AttributeMap;
|
||||||
|
readonly program: WebGLProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
],
|
],
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"strictNullChecks": true,
|
"strict": true
|
||||||
"noImplicitAny": true
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src"
|
||||||
|
|
|
@ -57,21 +57,13 @@ impl IndexRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_vector_append_operation<T>(dest: &mut Vec<T>, src: &[T]) -> IndexRange where T: Clone {
|
|
||||||
let start = dest.len();
|
|
||||||
dest.extend(src.iter().cloned());
|
|
||||||
let end = dest.len();
|
|
||||||
IndexRange {
|
|
||||||
start: start,
|
|
||||||
end: end,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_vector_append_and_serialization<T>(dest: &mut Vec<u8>, src: &[T])
|
fn from_vector_append_and_serialization<T>(dest: &mut Vec<u8>, src: &[T])
|
||||||
-> Result<IndexRange, ()>
|
-> Result<IndexRange, ()>
|
||||||
where T: Serialize {
|
where T: Serialize {
|
||||||
let byte_len_before = dest.len();
|
let byte_len_before = dest.len();
|
||||||
try!(bincode::serialize_into(dest, src, Infinite).map_err(drop));
|
for src_value in src {
|
||||||
|
try!(bincode::serialize_into(dest, src_value, Infinite).map_err(drop))
|
||||||
|
}
|
||||||
let byte_len_after = dest.len();
|
let byte_len_after = dest.len();
|
||||||
Ok(IndexRange {
|
Ok(IndexRange {
|
||||||
start: byte_len_before / mem::size_of::<T>(),
|
start: byte_len_before / mem::size_of::<T>(),
|
||||||
|
@ -129,8 +121,10 @@ struct PartitionFontResponse {
|
||||||
bVertexPositions: String,
|
bVertexPositions: String,
|
||||||
// Base64-encoded `bincode`-encoded `BVertexInfo`s.
|
// Base64-encoded `bincode`-encoded `BVertexInfo`s.
|
||||||
bVertexInfo: String,
|
bVertexInfo: String,
|
||||||
coverInteriorIndices: Vec<u32>,
|
// Base64-encoded `u32`s.
|
||||||
coverCurveIndices: Vec<u32>,
|
coverInteriorIndices: String,
|
||||||
|
// Base64-encoded `u32`s.
|
||||||
|
coverCurveIndices: String,
|
||||||
// Base64-encoded `bincode`-encoded `LineIndices` instances.
|
// Base64-encoded `bincode`-encoded `LineIndices` instances.
|
||||||
edgeUpperLineIndices: String,
|
edgeUpperLineIndices: String,
|
||||||
// Base64-encoded `bincode`-encoded `CurveIndices` instances.
|
// Base64-encoded `bincode`-encoded `CurveIndices` instances.
|
||||||
|
@ -251,12 +245,12 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
||||||
bVertexIndices:
|
bVertexIndices:
|
||||||
IndexRange::from_vector_append_and_serialization(&mut b_vertex_info,
|
IndexRange::from_vector_append_and_serialization(&mut b_vertex_info,
|
||||||
path_b_vertex_info).unwrap(),
|
path_b_vertex_info).unwrap(),
|
||||||
coverInteriorIndices:
|
coverInteriorIndices: IndexRange::from_vector_append_and_serialization(
|
||||||
IndexRange::from_vector_append_operation(&mut cover_interior_indices,
|
&mut cover_interior_indices,
|
||||||
cover_indices.interior_indices),
|
cover_indices.interior_indices).unwrap(),
|
||||||
coverCurveIndices:
|
coverCurveIndices: IndexRange::from_vector_append_and_serialization(
|
||||||
IndexRange::from_vector_append_operation(&mut cover_curve_indices,
|
&mut cover_curve_indices,
|
||||||
cover_indices.curve_indices),
|
cover_indices.curve_indices).unwrap(),
|
||||||
edgeUpperLineIndices: IndexRange::from_vector_append_and_serialization(
|
edgeUpperLineIndices: IndexRange::from_vector_append_and_serialization(
|
||||||
&mut edge_upper_line_indices,
|
&mut edge_upper_line_indices,
|
||||||
edge_indices.upper_line_indices).unwrap(),
|
edge_indices.upper_line_indices).unwrap(),
|
||||||
|
@ -278,8 +272,8 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
||||||
bQuads: base64::encode(&b_quads),
|
bQuads: base64::encode(&b_quads),
|
||||||
bVertexPositions: base64::encode(&b_vertex_positions),
|
bVertexPositions: base64::encode(&b_vertex_positions),
|
||||||
bVertexInfo: base64::encode(&b_vertex_info),
|
bVertexInfo: base64::encode(&b_vertex_info),
|
||||||
coverInteriorIndices: cover_interior_indices,
|
coverInteriorIndices: base64::encode(&cover_interior_indices),
|
||||||
coverCurveIndices: cover_curve_indices,
|
coverCurveIndices: base64::encode(&cover_curve_indices),
|
||||||
edgeUpperLineIndices: base64::encode(&edge_upper_line_indices),
|
edgeUpperLineIndices: base64::encode(&edge_upper_line_indices),
|
||||||
edgeUpperCurveIndices: base64::encode(&edge_upper_curve_indices),
|
edgeUpperCurveIndices: base64::encode(&edge_upper_curve_indices),
|
||||||
edgeLowerLineIndices: base64::encode(&edge_lower_line_indices),
|
edgeLowerLineIndices: base64::encode(&edge_lower_line_indices),
|
||||||
|
|
|
@ -6,7 +6,6 @@ precision highp float;
|
||||||
|
|
||||||
uniform mat4 uTransform;
|
uniform mat4 uTransform;
|
||||||
uniform ivec2 uFramebufferSize;
|
uniform ivec2 uFramebufferSize;
|
||||||
uniform int uMaxTextureSize;
|
|
||||||
uniform ivec2 uPathColorsDimensions;
|
uniform ivec2 uPathColorsDimensions;
|
||||||
uniform sampler2D uPathColors;
|
uniform sampler2D uPathColors;
|
||||||
|
|
||||||
|
@ -20,5 +19,6 @@ void main() {
|
||||||
position = convertScreenToClipSpace(position, uFramebufferSize);
|
position = convertScreenToClipSpace(position, uFramebufferSize);
|
||||||
gl_Position = vec4(position, aPathDepth, 1.0);
|
gl_Position = vec4(position, aPathDepth, 1.0);
|
||||||
|
|
||||||
vColor = fetchFloat4NormIndexedData(uPathColors, aPathDepth, uPathColorsDimensions);
|
//vColor = fetchFloat4NormIndexedData(uPathColors, aPathDepth, uPathColorsDimensions);
|
||||||
|
vColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue