|
|
|
@ -317,6 +317,7 @@ async function draw(state, context, animate, ts) {
@@ -317,6 +317,7 @@ async function draw(state, context, animate, ts) {
|
|
|
|
|
|
|
|
|
|
// Dynamic strokes should be drawn above static strokes
|
|
|
|
|
gl.clear(gl.DEPTH_BUFFER_BIT); |
|
|
|
|
gl.useProgram(pr.program); |
|
|
|
|
|
|
|
|
|
gl.uniform1i(pr.locations['u_stroke_count'], dynamic_stroke_count); |
|
|
|
|
gl.uniform1i(pr.locations['u_stroke_data'], 0); |
|
|
|
@ -422,17 +423,43 @@ async function draw(state, context, animate, ts) {
@@ -422,17 +423,43 @@ async function draw(state, context, animate, ts) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (config.draw_bvh) { |
|
|
|
|
const pr = programs['iquad']; |
|
|
|
|
const bboxes = tv_create(Float32Array, context.clipped_indices.size * 4); |
|
|
|
|
// Debug BVH viz
|
|
|
|
|
for (let i = 0; i < context.clipped_indices.size; ++i) { |
|
|
|
|
const stroke_id = context.clipped_indices.data[i]; |
|
|
|
|
const stroke = state.events[stroke_id]; |
|
|
|
|
const stroke_bbox = state.bvh.nodes[stroke.bvh_node].bbox; |
|
|
|
|
tv_add(bboxes, stroke.bbox.x1); |
|
|
|
|
tv_add(bboxes, stroke.bbox.x2); |
|
|
|
|
tv_add(bboxes, stroke.bbox.y1); |
|
|
|
|
tv_add(bboxes, stroke.bbox.x2); |
|
|
|
|
tv_add(bboxes, stroke.bbox.y2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const quad_count = bboxes.size / 4; |
|
|
|
|
|
|
|
|
|
gl.useProgram(pr.program); |
|
|
|
|
|
|
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_iquads']); |
|
|
|
|
gl.bufferData(gl.ARRAY_BUFFER, tv_data(bboxes), gl.STREAM_DRAW); |
|
|
|
|
|
|
|
|
|
gl.uniform2f(pr.locations['u_res'], context.canvas.width, context.canvas.height); |
|
|
|
|
gl.uniform2f(pr.locations['u_scale'], state.canvas.zoom, state.canvas.zoom); |
|
|
|
|
gl.uniform2f(pr.locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y); |
|
|
|
|
|
|
|
|
|
gl.enableVertexAttribArray(pr.locations['a_topleft']); |
|
|
|
|
gl.enableVertexAttribArray(pr.locations['a_bottomright']); |
|
|
|
|
|
|
|
|
|
gl.vertexAttribPointer(pr.locations['a_topleft'], 2, gl.FLOAT, false, 4 * 4, 0); |
|
|
|
|
gl.vertexAttribPointer(pr.locations['a_bottomright'], 2, gl.FLOAT, false, 4 * 4, 2 * 4); |
|
|
|
|
|
|
|
|
|
gl.vertexAttribDivisor(pr.locations['a_topleft'], 1); |
|
|
|
|
gl.vertexAttribDivisor(pr.locations['a_bottomright'], 1); |
|
|
|
|
|
|
|
|
|
// Static draw (everything already bound)
|
|
|
|
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, quad_count); |
|
|
|
|
|
|
|
|
|
gl.vertexAttribDivisor(pr.locations['a_topleft'], 0); |
|
|
|
|
gl.vertexAttribDivisor(pr.locations['a_bottomright'], 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
document.getElementById('debug-stats').innerHTML = ` |
|
|
|
|