From 052e9b27cdd69d6c69ea4b73207b2a186d03cfed Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 15 Nov 2018 19:23:42 -0800 Subject: [PATCH] WIP with fills --- demo2/cover.fs.glsl | 4 ++-- demo2/pathfinder.ts | 38 ++++++++++++++++++++++++++++---------- demo2/stencil.fs.glsl | 3 ++- demo2/stencil.vs.glsl | 13 ++++++++++--- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/demo2/cover.fs.glsl b/demo2/cover.fs.glsl index 1801a630..0deaafdc 100644 --- a/demo2/cover.fs.glsl +++ b/demo2/cover.fs.glsl @@ -20,6 +20,6 @@ in vec4 vColor; out vec4 oFragColor; void main() { - float coverage = texture(uStencilTexture, vTexCoord).r; - oFragColor = vColor * coverage; + float coverage = abs(texture(uStencilTexture, vTexCoord).r); + oFragColor = vec4(vColor.rgb, vColor.a * coverage); } diff --git a/demo2/pathfinder.ts b/demo2/pathfinder.ts index d4c0fb94..19a13af2 100644 --- a/demo2/pathfinder.ts +++ b/demo2/pathfinder.ts @@ -27,8 +27,8 @@ const GLOBAL_OFFSET: Point2D = {x: 200.0, y: 150.0}; const QUAD_VERTEX_POSITIONS: Uint8Array = new Uint8Array([ 0, 0, 1, 0, - 0, 1, 1, 1, + 0, 1, ]); interface SVGPath { @@ -78,7 +78,8 @@ class App { private coverProgram: Program<'FramebufferSize' | 'TileSize' | 'StencilTexture' | 'StencilTextureSize', 'TessCoord' | 'TileOrigin' | 'TileIndex' | 'Color'>; - private stencilProgram: Program<'FramebufferSize' | 'TileSize', 'Position' | 'TileIndex'>; + private stencilProgram: Program<'FramebufferSize' | 'TileSize', + 'TessCoord' | 'From' | 'To' | 'TileIndex'>; private quadVertexBuffer: WebGLBuffer; private stencilVertexPositionsBuffer: WebGLBuffer; private stencilVertexTileIndicesBuffer: WebGLBuffer; @@ -136,7 +137,7 @@ class App { STENCIL_VERTEX_SHADER_SOURCE, STENCIL_FRAGMENT_SHADER_SOURCE, ['FramebufferSize', 'TileSize'], - ['Position', 'TileIndex']); + ['TessCoord', 'From', 'To', 'TileIndex']); this.stencilProgram = stencilProgram; // Initialize quad VBO. @@ -152,15 +153,28 @@ class App { this.stencilVertexArray = unwrapNull(gl.createVertexArray()); gl.bindVertexArray(this.stencilVertexArray); gl.useProgram(this.stencilProgram.program); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer); + gl.vertexAttribPointer(stencilProgram.attributes.TessCoord, + 2, + gl.UNSIGNED_BYTE, + false, + 0, + 0); gl.bindBuffer(gl.ARRAY_BUFFER, this.stencilVertexPositionsBuffer); - gl.vertexAttribPointer(stencilProgram.attributes.Position, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(stencilProgram.attributes.From, 2, gl.FLOAT, false, 16, 0); + gl.vertexAttribDivisor(stencilProgram.attributes.From, 1); + gl.vertexAttribPointer(stencilProgram.attributes.To, 2, gl.FLOAT, false, 16, 8); + gl.vertexAttribDivisor(stencilProgram.attributes.To, 1); gl.bindBuffer(gl.ARRAY_BUFFER, this.stencilVertexTileIndicesBuffer); gl.vertexAttribIPointer(stencilProgram.attributes.TileIndex, 1, gl.UNSIGNED_SHORT, 0, 0); - gl.enableVertexAttribArray(stencilProgram.attributes.Position); + gl.vertexAttribDivisor(stencilProgram.attributes.TileIndex, 1); + gl.enableVertexAttribArray(stencilProgram.attributes.TessCoord); + gl.enableVertexAttribArray(stencilProgram.attributes.From); + gl.enableVertexAttribArray(stencilProgram.attributes.To); gl.enableVertexAttribArray(stencilProgram.attributes.TileIndex); // Initialize cover VBO. @@ -221,7 +235,7 @@ class App { throw new Error("y too high"); if (segment[0] !== 'M') { stencilVertexPositions.push(lastPoint.x, lastPoint.y, point.x, point.y); - stencilVertexTileIndices.push(tileIndex, tileIndex); + stencilVertexTileIndices.push(tileIndex); primitives++; } lastPoint = point; @@ -247,7 +261,11 @@ class App { STENCIL_FRAMEBUFFER_SIZE, STENCIL_FRAMEBUFFER_SIZE); gl.uniform2f(this.stencilProgram.uniforms.TileSize, TILE_SIZE, TILE_SIZE); - gl.drawArrays(gl.LINES, 0, primitives * 2); + gl.blendEquation(gl.FUNC_ADD); + gl.blendFunc(gl.ONE, gl.ONE); + gl.enable(gl.BLEND); + gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, primitives); + gl.disable(gl.BLEND); // Populate the cover VBO. const coverVertexBufferData = new Int16Array(scene.tiles.length * 5); @@ -286,7 +304,7 @@ class App { gl.blendEquation(gl.FUNC_ADD); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.enable(gl.BLEND); - gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, scene.tiles.length); + gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, scene.tiles.length); gl.disable(gl.BLEND); } } @@ -311,8 +329,8 @@ class Scene { let paint: string; if (style.fill != null && style.fill !== 'none') { paint = style.fill; - } else if (style.stroke != null && style.stroke !== 'none') { - paint = style.stroke; + /*} else if (style.stroke != null && style.stroke !== 'none') { + paint = style.stroke;*/ } else { pathColors.push({r: 0, g: 0, b: 0, a: 0}); continue; diff --git a/demo2/stencil.fs.glsl b/demo2/stencil.fs.glsl index f9b21da7..a554bc46 100644 --- a/demo2/stencil.fs.glsl +++ b/demo2/stencil.fs.glsl @@ -15,5 +15,6 @@ precision highp float; out vec4 oFragColor; void main() { - oFragColor = vec4(1.0, 1.0, 1.0, 1.0); + float coverage = gl_FrontFacing ? 1.0 : -1.0; + oFragColor = vec4(coverage); } diff --git a/demo2/stencil.vs.glsl b/demo2/stencil.vs.glsl index 0f33f61e..78bbb007 100644 --- a/demo2/stencil.vs.glsl +++ b/demo2/stencil.vs.glsl @@ -15,7 +15,9 @@ precision highp float; uniform vec2 uFramebufferSize; uniform vec2 uTileSize; -in vec2 aPosition; +in vec2 aTessCoord; +in vec2 aFrom; +in vec2 aTo; in uint aTileIndex; vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { @@ -25,6 +27,11 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { } void main() { - vec2 position = computeTileOffset(aTileIndex, uFramebufferSize.x) + aPosition; - gl_Position = vec4(position / uFramebufferSize * 2.0 - 1.0, 0.0, 1.0); + vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize.x); + + vec2 offset = aTessCoord.x < 0.5 ? aFrom : aTo; + if (aTessCoord.y > 0.5) + offset.y = uTileSize.y; + + gl_Position = vec4((tileOrigin + offset) / uFramebufferSize * 2.0 - 1.0, 0.0, 1.0); }