Rework mask/tile in demo

This commit is contained in:
Patrick Walton 2018-12-19 17:05:01 -08:00
parent 0e0064eff1
commit 4a00468595
2 changed files with 24 additions and 52 deletions

View File

@ -19,7 +19,6 @@ uniform vec2 uStencilTextureSize;
in vec2 aTessCoord; in vec2 aTessCoord;
in vec2 aTileOrigin; in vec2 aTileOrigin;
in float aBackdrop; in float aBackdrop;
in uint aTileIndex;
in vec4 aColor; in vec4 aColor;
out vec2 vTexCoord; out vec2 vTexCoord;
@ -28,13 +27,14 @@ out vec4 vColor;
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x); uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
uvec2 tileOffset = uvec2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow); uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
return vec2(tileOffset) * uTileSize; return vec2(tileOffset) * uTileSize;
} }
void main() { void main() {
uint tileIndex = uint(gl_InstanceID);
vec2 position = aTileOrigin + uTileSize * aTessCoord; vec2 position = aTileOrigin + uTileSize * aTessCoord;
vec2 texCoord = computeTileOffset(aTileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize; vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
vTexCoord = texCoord / uStencilTextureSize; vTexCoord = texCoord / uStencilTextureSize;
vBackdrop = aBackdrop; vBackdrop = aBackdrop;
vColor = aColor; vColor = aColor;

View File

@ -34,7 +34,8 @@ const QUAD_VERTEX_POSITIONS: Uint8Array = new Uint8Array([
]); ]);
const FILL_INSTANCE_SIZE: number = 20; const FILL_INSTANCE_SIZE: number = 20;
const TILE_INSTANCE_SIZE: number = 16; const SOLID_TILE_INSTANCE_SIZE: number = 12;
const MASK_TILE_INSTANCE_SIZE: number = 16;
interface Color { interface Color {
r: number; r: number;
@ -61,19 +62,16 @@ class App {
'TessCoord' | 'TileOrigin' | 'Color'>; 'TessCoord' | 'TileOrigin' | 'Color'>;
private maskTileProgram: private maskTileProgram:
Program<'FramebufferSize' | 'TileSize' | 'StencilTexture' | 'StencilTextureSize', Program<'FramebufferSize' | 'TileSize' | 'StencilTexture' | 'StencilTextureSize',
'TessCoord' | 'TileOrigin' | 'TileIndex' | 'Backdrop' | 'Color'>; 'TessCoord' | 'TileOrigin' | 'Backdrop' | 'Color'>;
private quadVertexBuffer: WebGLBuffer; private quadVertexBuffer: WebGLBuffer;
private fillVertexBuffer: WebGLBuffer; private fillVertexBuffer: WebGLBuffer;
private fillVertexArray: WebGLVertexArrayObject; private fillVertexArray: WebGLVertexArrayObject;
private tileVertexBuffer: WebGLBuffer; private solidTileVertexBuffer: WebGLBuffer;
private instanceIDVertexBuffer: WebGLBuffer;
private solidIndexBuffer: WebGLBuffer;
private solidVertexArray: WebGLVertexArrayObject; private solidVertexArray: WebGLVertexArrayObject;
private maskIndexBuffer: WebGLBuffer; private maskTileVertexBuffer: WebGLBuffer;
private maskVertexArray: WebGLVertexArrayObject; private maskVertexArray: WebGLVertexArrayObject;
private fillPrimitiveCount: number; private fillPrimitiveCount: number;
private totalTileCount: number;
private solidTileCount: number; private solidTileCount: number;
private maskTileCount: number; private maskTileCount: number;
@ -209,10 +207,8 @@ class App {
gl.enableVertexAttribArray(fillProgram.attributes.TileIndex); gl.enableVertexAttribArray(fillProgram.attributes.TileIndex);
// Initialize tile VBOs and IBOs. // Initialize tile VBOs and IBOs.
this.tileVertexBuffer = unwrapNull(gl.createBuffer()); this.solidTileVertexBuffer = unwrapNull(gl.createBuffer());
this.instanceIDVertexBuffer = unwrapNull(gl.createBuffer()); this.maskTileVertexBuffer = unwrapNull(gl.createBuffer());
this.solidIndexBuffer = unwrapNull(gl.createBuffer());
this.maskIndexBuffer = unwrapNull(gl.createBuffer());
// Initialize solid tile VAO. // Initialize solid tile VAO.
this.solidVertexArray = unwrapNull(gl.createVertexArray()); this.solidVertexArray = unwrapNull(gl.createVertexArray());
@ -225,20 +221,20 @@ class App {
false, false,
0, 0,
0); 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.tileVertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, this.solidTileVertexBuffer);
gl.vertexAttribPointer(solidTileProgram.attributes.TileOrigin, gl.vertexAttribPointer(solidTileProgram.attributes.TileOrigin,
2, 2,
gl.FLOAT, gl.FLOAT,
false, false,
TILE_INSTANCE_SIZE, SOLID_TILE_INSTANCE_SIZE,
0); 0);
gl.vertexAttribDivisor(solidTileProgram.attributes.TileOrigin, 1); gl.vertexAttribDivisor(solidTileProgram.attributes.TileOrigin, 1);
gl.vertexAttribPointer(solidTileProgram.attributes.Color, gl.vertexAttribPointer(solidTileProgram.attributes.Color,
4, 4,
gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE,
true, true,
TILE_INSTANCE_SIZE, SOLID_TILE_INSTANCE_SIZE,
12); 8);
gl.vertexAttribDivisor(solidTileProgram.attributes.Color, 1); gl.vertexAttribDivisor(solidTileProgram.attributes.Color, 1);
gl.enableVertexAttribArray(solidTileProgram.attributes.TessCoord); gl.enableVertexAttribArray(solidTileProgram.attributes.TessCoord);
gl.enableVertexAttribArray(solidTileProgram.attributes.TileOrigin); gl.enableVertexAttribArray(solidTileProgram.attributes.TileOrigin);
@ -255,41 +251,36 @@ class App {
false, false,
0, 0,
0); 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.tileVertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, this.maskTileVertexBuffer);
gl.vertexAttribPointer(maskTileProgram.attributes.TileOrigin, gl.vertexAttribPointer(maskTileProgram.attributes.TileOrigin,
2, 2,
gl.FLOAT, gl.FLOAT,
false, false,
TILE_INSTANCE_SIZE, MASK_TILE_INSTANCE_SIZE,
0); 0);
gl.vertexAttribDivisor(maskTileProgram.attributes.TileOrigin, 1); gl.vertexAttribDivisor(maskTileProgram.attributes.TileOrigin, 1);
gl.vertexAttribPointer(maskTileProgram.attributes.Backdrop, gl.vertexAttribPointer(maskTileProgram.attributes.Backdrop,
1, 1,
gl.FLOAT, gl.FLOAT,
false, false,
TILE_INSTANCE_SIZE, MASK_TILE_INSTANCE_SIZE,
8); 8);
gl.vertexAttribDivisor(maskTileProgram.attributes.Backdrop, 1); gl.vertexAttribDivisor(maskTileProgram.attributes.Backdrop, 1);
gl.vertexAttribPointer(maskTileProgram.attributes.Color, gl.vertexAttribPointer(maskTileProgram.attributes.Color,
4, 4,
gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE,
true, true,
TILE_INSTANCE_SIZE, MASK_TILE_INSTANCE_SIZE,
12); 12);
gl.vertexAttribDivisor(maskTileProgram.attributes.Color, 1); gl.vertexAttribDivisor(maskTileProgram.attributes.Color, 1);
gl.bindBuffer(gl.ARRAY_BUFFER, this.tileVertexBuffer);
gl.vertexAttribIPointer(maskTileProgram.attributes.TileIndex, 1, gl.UNSIGNED_SHORT, 10, 4);
gl.vertexAttribDivisor(maskTileProgram.attributes.TileIndex, 1);
gl.enableVertexAttribArray(maskTileProgram.attributes.TessCoord); gl.enableVertexAttribArray(maskTileProgram.attributes.TessCoord);
gl.enableVertexAttribArray(maskTileProgram.attributes.TileOrigin); gl.enableVertexAttribArray(maskTileProgram.attributes.TileOrigin);
gl.enableVertexAttribArray(maskTileProgram.attributes.TileIndex);
gl.enableVertexAttribArray(maskTileProgram.attributes.Color); gl.enableVertexAttribArray(maskTileProgram.attributes.Color);
// Set up event handlers. // Set up event handlers.
this.canvas.addEventListener('click', event => this.onClick(event), false); this.canvas.addEventListener('click', event => this.onClick(event), false);
this.fillPrimitiveCount = 0; this.fillPrimitiveCount = 0;
this.totalTileCount = 0;
this.solidTileCount = 0; this.solidTileCount = 0;
this.maskTileCount = 0; this.maskTileCount = 0;
} }
@ -344,7 +335,6 @@ class App {
gl.disable(gl.BLEND); gl.disable(gl.BLEND);
gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.solidTileCount); gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.solidTileCount);
/*
// Draw masked tiles. // Draw masked tiles.
gl.bindVertexArray(this.maskVertexArray); gl.bindVertexArray(this.maskVertexArray);
gl.useProgram(this.maskTileProgram.program); gl.useProgram(this.maskTileProgram.program);
@ -363,7 +353,6 @@ class App {
gl.enable(gl.BLEND); gl.enable(gl.BLEND);
gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.maskTileCount); gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.maskTileCount);
gl.disable(gl.BLEND); gl.disable(gl.BLEND);
*/
// End timer. // End timer.
if (timerQuery != null) { if (timerQuery != null) {
@ -424,23 +413,17 @@ class App {
countFieldName = 'fillPrimitiveCount'; countFieldName = 'fillPrimitiveCount';
instanceSize = FILL_INSTANCE_SIZE; instanceSize = FILL_INSTANCE_SIZE;
break; break;
case 'tile':
bindPoint = gl.ARRAY_BUFFER;
buffer = this.tileVertexBuffer;
countFieldName = 'totalTileCount';
instanceSize = TILE_INSTANCE_SIZE;
break;
case 'soli': case 'soli':
bindPoint = gl.ELEMENT_ARRAY_BUFFER; bindPoint = gl.ARRAY_BUFFER;
buffer = this.solidIndexBuffer; buffer = this.solidTileVertexBuffer;
countFieldName = 'solidTileCount'; countFieldName = 'solidTileCount';
instanceSize = 4; instanceSize = SOLID_TILE_INSTANCE_SIZE;
break; break;
case 'mask': case 'mask':
bindPoint = gl.ELEMENT_ARRAY_BUFFER; bindPoint = gl.ARRAY_BUFFER;
buffer = this.maskIndexBuffer; buffer = this.maskTileVertexBuffer;
countFieldName = 'maskTileCount'; countFieldName = 'maskTileCount';
instanceSize = 4; instanceSize = MASK_TILE_INSTANCE_SIZE;
break; break;
default: default:
throw new Error("Unexpected subchunk ID: " + id); throw new Error("Unexpected subchunk ID: " + id);
@ -451,22 +434,11 @@ class App {
this[countFieldName] = subchunk.length() / instanceSize; this[countFieldName] = subchunk.length() / instanceSize;
} }
this.regenerateInstanceIDBuffer();
this.redraw(); this.redraw();
}, false); }, false);
reader.readAsArrayBuffer(file); reader.readAsArrayBuffer(file);
} }
private regenerateInstanceIDBuffer(): void {
const instanceIDs = new Uint32Array(this.totalTileCount);
for (let instanceID = 0; instanceID < this.totalTileCount; instanceID++)
instanceIDs[instanceID] = instanceID;
const gl = this.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceIDVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, instanceIDs, gl.DYNAMIC_DRAW);
}
private onClick(event: MouseEvent): void { private onClick(event: MouseEvent): void {
this.redraw(); this.redraw();
} }