Browse Source

Use TypedArray for culling. This is up to 10 times faster!

ssao
A.Olokhtonov 1 year ago
parent
commit
0d8667aa3a
  1. 2
      client/index.js
  2. 26
      client/math.js
  3. 8
      client/webgl_draw.js

2
client/index.js

@ -173,7 +173,7 @@ function main() {
}, },
'players': {}, 'players': {},
'onscreen_segments': [], 'onscreen_segments': null,
}; };
const context = { const context = {

26
client/math.js

@ -218,7 +218,19 @@ function quad_fully_onscreen(screen, bbox) {
function segments_onscreen(state, context) { function segments_onscreen(state, context) {
// TODO: handle stroke width // TODO: handle stroke width
state.onscreen_segments.length = 0; if (state.onscreen_segments === null) {
let total_points = 0;
for (const event of state.events) {
if (event.type === EVENT.STROKE && !event.deleted) {
total_points += event.points.length - 1;
}
}
state.onscreen_segments = new Uint32Array(total_points * 6);
}
let at = 0;
const screen_topleft = screen_to_canvas(state, {'x': 0, 'y': 0}); const screen_topleft = screen_to_canvas(state, {'x': 0, 'y': 0});
const screen_bottomright = screen_to_canvas(state, {'x': context.canvas.width, 'y': context.canvas.height}); const screen_bottomright = screen_to_canvas(state, {'x': context.canvas.width, 'y': context.canvas.height});
@ -240,12 +252,20 @@ function segments_onscreen(state, context) {
if (fully_onscreen || segment_interesects_quad(a, b, screen_topleft, screen_bottomright, screen_topright, screen_bottomleft)) { if (fully_onscreen || segment_interesects_quad(a, b, screen_topleft, screen_bottomright, screen_topright, screen_bottomleft)) {
let base = head + j * 4; let base = head + j * 4;
// We draw quads as [1, 2, 3, 4, 3, 2] // We draw quads as [1, 2, 3, 4, 3, 2]
state.onscreen_segments.push(base + 0, base + 1, base + 2); state.onscreen_segments[at + 0] = base + 0;
state.onscreen_segments.push(base + 3, base + 2, base + 1); state.onscreen_segments[at + 1] = base + 1;
state.onscreen_segments[at + 2] = base + 2;
state.onscreen_segments[at + 3] = base + 3;
state.onscreen_segments[at + 4] = base + 2;
state.onscreen_segments[at + 5] = base + 1;
at += 6;
} }
} }
} }
head += (event.points.length - 1) * 4; head += (event.points.length - 1) * 4;
} }
} }
return at;
} }

8
client/webgl_draw.js

@ -69,16 +69,16 @@ function draw(state, context) {
} }
const before_clip = performance.now(); const before_clip = performance.now();
segments_onscreen(state, context); const index_count = segments_onscreen(state, context);
const after_clip = performance.now(); const after_clip = performance.now();
console.debug('clip', after_clip - before_clip); console.debug('clip', after_clip - before_clip);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers['b_packed_static_index']); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers['b_packed_static_index']);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(state.onscreen_segments), gl.DYNAMIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(state.onscreen_segments.buffer, 0, index_count), gl.DYNAMIC_DRAW);
const after_index_uploads = performance.now(); const after_index_uploads = performance.now();
console.debug('index upload', after_index_uploads - after_clip); // console.debug('index upload', after_index_uploads - after_clip);
gl.drawElements(gl.TRIANGLES, state.onscreen_segments.length, gl.UNSIGNED_INT, 0); gl.drawElements(gl.TRIANGLES, index_count, gl.UNSIGNED_INT, 0);
} }
if (dynamic_points > 0) { if (dynamic_points > 0) {

Loading…
Cancel
Save