Rework mask/tile in demo
This commit is contained in:
parent
0e0064eff1
commit
4a00468595
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue