|
|
@ -5,13 +5,39 @@ let config = { |
|
|
|
bytes_per_quad: 20, |
|
|
|
bytes_per_quad: 20, |
|
|
|
w: 24, |
|
|
|
w: 24, |
|
|
|
h: 24, |
|
|
|
h: 24, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
predefined_colors: { |
|
|
|
|
|
|
|
'Np': [75, 62, 143], |
|
|
|
|
|
|
|
'F': [62, 123, 143], |
|
|
|
|
|
|
|
'Pd': [61, 142, 88], |
|
|
|
|
|
|
|
'Dc': [109, 143, 61], |
|
|
|
|
|
|
|
'Rn': [143, 102, 61], |
|
|
|
|
|
|
|
'Ds': [142, 61, 95], |
|
|
|
|
|
|
|
'Sc': [115, 61, 143], |
|
|
|
|
|
|
|
'Is': [61, 81, 143], |
|
|
|
|
|
|
|
'Rr': [61, 143, 129], |
|
|
|
|
|
|
|
'X': [68, 143, 61], |
|
|
|
|
|
|
|
'Rw': [142, 142, 61], |
|
|
|
|
|
|
|
'Cm': [61, 81, 143], |
|
|
|
|
|
|
|
'Mt': [142, 142, 61], |
|
|
|
|
|
|
|
'Ma': [143, 68, 61], |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
limit: -1, |
|
|
|
|
|
|
|
zoom_delta: 0.05, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
let canvas = null; |
|
|
|
let canvas = null; |
|
|
|
let gl = null; |
|
|
|
let gl = null; |
|
|
|
let gpu_timer_ext = null; |
|
|
|
let gpu_timer_ext = null; |
|
|
|
let offset = { x: 0, y: 0 }; |
|
|
|
let offset = { x: 0, y: 0 }; |
|
|
|
let scale = 1; |
|
|
|
let moving = false; |
|
|
|
|
|
|
|
let zoom = 1; |
|
|
|
|
|
|
|
let zoom_target = 1.0; |
|
|
|
|
|
|
|
let zoom_level = 0; |
|
|
|
|
|
|
|
let zoom_screenp = { 'x': 0, 'y': 0 }; |
|
|
|
|
|
|
|
let last_frame_dt = 0; |
|
|
|
|
|
|
|
let last_frame_ts = 0; |
|
|
|
|
|
|
|
|
|
|
|
const tquad_vs_src = `#version 300 es
|
|
|
|
const tquad_vs_src = `#version 300 es
|
|
|
|
in vec2 a_pos; |
|
|
|
in vec2 a_pos; |
|
|
@ -30,16 +56,16 @@ const tquad_vs_src = `#version 300 es |
|
|
|
|
|
|
|
|
|
|
|
if (vertex_index == 0) { |
|
|
|
if (vertex_index == 0) { |
|
|
|
// "top left" aka "p1"
|
|
|
|
// "top left" aka "p1"
|
|
|
|
corner = a_pos + vec2(1.0); |
|
|
|
corner = a_pos; |
|
|
|
} else if (vertex_index == 1 || vertex_index == 5) { |
|
|
|
} else if (vertex_index == 1 || vertex_index == 5) { |
|
|
|
// "top right" aka "p2"
|
|
|
|
// "top right" aka "p2"
|
|
|
|
corner = a_pos + vec2(a_size.x - 1.0, 1.0); |
|
|
|
corner = a_pos + vec2(a_size.x, 0); |
|
|
|
} else if (vertex_index == 2 || vertex_index == 4) { |
|
|
|
} else if (vertex_index == 2 || vertex_index == 4) { |
|
|
|
// "bottom left" aka "p3"
|
|
|
|
// "bottom left" aka "p3"
|
|
|
|
corner = a_pos + vec2(1.0, a_size.y - 1.0); |
|
|
|
corner = a_pos + vec2(0, a_size.y); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// "bottom right" aka "p4"
|
|
|
|
// "bottom right" aka "p4"
|
|
|
|
corner = a_pos + a_size - vec2(1.0); |
|
|
|
corner = a_pos + a_size; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec2 screen02 = (corner.xy * vec2(u_scale) + u_translation) / u_res * 2.0; |
|
|
|
vec2 screen02 = (corner.xy * vec2(u_scale) + u_translation) / u_res * 2.0; |
|
|
@ -62,18 +88,21 @@ const tquad_fs_src = `#version 300 es |
|
|
|
} |
|
|
|
} |
|
|
|
`;
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
|
|
function schedule_draw() { |
|
|
|
function schedule_draw(animation = false) { |
|
|
|
if (!timers.raf) { |
|
|
|
if (!timers.raf) { |
|
|
|
window.requestAnimationFrame(draw); |
|
|
|
window.requestAnimationFrame((ts) => draw(ts, animation)); |
|
|
|
timers.raf = true; |
|
|
|
timers.raf = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function draw() { |
|
|
|
function draw(ts, animation) { |
|
|
|
|
|
|
|
const dt = ts - last_frame_ts; |
|
|
|
const cpu_before = performance.now(); |
|
|
|
const cpu_before = performance.now(); |
|
|
|
const width = window.innerWidth; |
|
|
|
const width = window.innerWidth; |
|
|
|
const height = window.innerHeight; |
|
|
|
const height = window.innerHeight; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last_frame_ts = ts; |
|
|
|
|
|
|
|
|
|
|
|
let query = null; |
|
|
|
let query = null; |
|
|
|
|
|
|
|
|
|
|
|
if (gpu_timer_ext !== null) { |
|
|
|
if (gpu_timer_ext !== null) { |
|
|
@ -82,7 +111,7 @@ function draw() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
gl.viewport(0, 0, canvas.width, canvas.height); |
|
|
|
gl.viewport(0, 0, canvas.width, canvas.height); |
|
|
|
gl.clearColor(0, 0, 0, 1); |
|
|
|
gl.clearColor(0.11, 0.11, 0.11, 1); |
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT); |
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT); |
|
|
|
|
|
|
|
|
|
|
|
const quads = generate('0'); |
|
|
|
const quads = generate('0'); |
|
|
@ -99,7 +128,7 @@ function draw() { |
|
|
|
|
|
|
|
|
|
|
|
gl.uniform2f(program.locations['u_res'], canvas.width, canvas.height); |
|
|
|
gl.uniform2f(program.locations['u_res'], canvas.width, canvas.height); |
|
|
|
gl.uniform2f(program.locations['u_translation'], offset.x, offset.y); |
|
|
|
gl.uniform2f(program.locations['u_translation'], offset.x, offset.y); |
|
|
|
gl.uniform1f(program.locations['u_scale'], scale); |
|
|
|
gl.uniform1f(program.locations['u_scale'], zoom); |
|
|
|
|
|
|
|
|
|
|
|
gl.enableVertexAttribArray(program.locations['a_pos']); |
|
|
|
gl.enableVertexAttribArray(program.locations['a_pos']); |
|
|
|
gl.enableVertexAttribArray(program.locations['a_size']); |
|
|
|
gl.enableVertexAttribArray(program.locations['a_size']); |
|
|
@ -150,10 +179,31 @@ function draw() { |
|
|
|
timers.raf = false; |
|
|
|
timers.raf = false; |
|
|
|
|
|
|
|
|
|
|
|
console.log('Last CPU Frametime: ' + Math.round((cpu_after - cpu_before) * 100) / 100 + 'ms'); |
|
|
|
console.log('Last CPU Frametime: ' + Math.round((cpu_after - cpu_before) * 100) / 100 + 'ms'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (zoom_target != zoom) { |
|
|
|
|
|
|
|
update_canvas_zoom(zoom, zoom_target, animation ? dt : last_frame_dt); |
|
|
|
|
|
|
|
schedule_draw(true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last_frame_dt = dt; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function update_canvas_zoom(current, target, dt) { |
|
|
|
|
|
|
|
const rate = Math.min(1.0, dt / 16.66 * 0.3); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Math.abs(1.0 - current / target) > 0.01) { |
|
|
|
|
|
|
|
zoom = current + (target - current) * rate; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
zoom = target; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// https://gist.github.com/aolo2/a373363419bd5a9283977ab9f8841f78
|
|
|
|
|
|
|
|
const zc = zoom_screenp; |
|
|
|
|
|
|
|
offset.x = zc.x - (zc.x - offset.x) * zoom / current; |
|
|
|
|
|
|
|
offset.y = zc.y - (zc.y - offset.y) * zoom / current; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function init_webgl() { |
|
|
|
function init_webgl() { |
|
|
|
canvas = document.querySelector('#c'); |
|
|
|
canvas = document.querySelector('#c'); |
|
|
|
gl = canvas.getContext('webgl2'); |
|
|
|
gl = canvas.getContext('webgl2'); |
|
|
|
|
|
|
|
|
|
|
|