Skip to content

Commit

Permalink
[Webgl1]: Support index for area (polygon).
Browse files Browse the repository at this point in the history
  • Loading branch information
kalenkevich committed Nov 4, 2023
1 parent 3a9b72d commit f8e397f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
48 changes: 37 additions & 11 deletions src/webgl/object/area.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import earcut from 'earcut';
import { GlProgram, GlProgramProps, GlProgramType, BufferAttrs } from './program';
import { GlProgram, GlProgramProps, GlProgramType, BufferAttrs, ProgramCache } from './program';
import { v2 } from '../types';

export interface GlAreaPorps extends GlProgramProps {
Expand Down Expand Up @@ -28,25 +28,51 @@ export class WebGlArea extends GlProgram {
this.points = points;
}

public draw(gl: WebGLRenderingContext, cache: ProgramCache) {
const program = this.getProgram(gl, cache);
if (program !== cache.currentProgram) {
gl.useProgram(program);
cache.currentProgram = program;
}

const bufferAttrs = this.bufferAttrsCache || this.getBufferAttrs(gl);
if (!this.bufferAttrsCache) {
this.bufferAttrsCache = bufferAttrs;
}
this.setBuffers(gl, bufferAttrs);
this.setUniforms(gl, program);

const primitiveType = this.getPrimitiveType(gl);
const offset = bufferAttrs.offset || 0;

gl.drawElements(primitiveType, bufferAttrs.numElements, gl.UNSIGNED_SHORT, offset);
}

protected setBuffers(gl: WebGLRenderingContext, buffers: BufferAttrs) {
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(buffers.indices), gl.STATIC_DRAW);

const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, buffers.a_position.data, gl.STATIC_DRAW);
gl.enableVertexAttribArray(this.a_positionLocation);
gl.vertexAttribPointer(this.a_positionLocation, buffers.a_position.numComponents, gl.FLOAT, true, 8, 0);
}

public getBufferAttrs(gl: WebGLRenderingContext): BufferAttrs {
const points = this.points.flatMap(p => p);
// Magic here! This function returns the indexes of the coordinates for triangle from the source point array.
const indexes = earcut(points);
const data = new Float32Array(indexes.length * 2);

let offset = 0;
for (const index of indexes) {
data.set([points[index * 2], points[index * 2 + 1]], offset);
offset += 2;
}
const indices = earcut(points);

return {
type: 'arrays',
a_position: {
numComponents: 2,
data: data,
data: new Float32Array(points),
},
numElements: indexes.length,
indices,
numElements: indices.length,
};
}
}
2 changes: 2 additions & 0 deletions src/webgl/object/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export interface BufferAttrs {
divisor?: number;
};
numElements: number;
indices?: number[];
offset?: number;
instanceCount?: number;
}
Expand Down Expand Up @@ -298,6 +299,7 @@ export abstract class GlProgram {
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, buffers.a_position.data, gl.STATIC_DRAW);
gl.enableVertexAttribArray(this.a_positionLocation);
gl.vertexAttribPointer(this.a_positionLocation, buffers.a_position.numComponents, gl.FLOAT, true, 8, 0);
}

Expand Down

0 comments on commit f8e397f

Please sign in to comment.