Browse Source

Pictures good

infinite
A.Olokhtonov 2 years ago
parent
commit
f24e8d386b
  1. 13
      client/webgl.js
  2. 37
      client/webgl_geometry.js
  3. 57
      client/webgl_listeners.js
  4. 41
      client/webgl_shaders.js

13
client/webgl.js

@ -25,7 +25,6 @@ function draw(state, context) {
gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom); gl.uniform2f(locations['u_scale'], state.canvas.zoom, state.canvas.zoom);
gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y); gl.uniform2f(locations['u_translation'], state.canvas.offset.x, state.canvas.offset.y);
gl.uniform1i(locations['u_layer'], 0); gl.uniform1i(locations['u_layer'], 0);
gl.uniform1i(locations['u_texture'], 0);
gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_pos']); gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_pos']);
gl.vertexAttribPointer(locations['a_pos'], 2, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(locations['a_pos'], 2, gl.FLOAT, false, 0, 0);
@ -35,7 +34,13 @@ function draw(state, context) {
gl.vertexAttribPointer(locations['a_texcoord'], 2, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(locations['a_texcoord'], 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, context.quad_texcoords_f32, gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, context.quad_texcoords_f32, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, context.quad_positions.length / 2); let tex_index = 0;
for (const key in context.textures) {
gl.bindTexture(gl.TEXTURE_2D, context.textures[key]);
gl.drawArrays(gl.TRIANGLES, tex_index * 6, 6);
++tex_index;
}
// Draw strokes // Draw strokes
locations = context.locations['stroke']; locations = context.locations['stroke'];
@ -78,8 +83,8 @@ const config = {
second_finger_timeout: 500, second_finger_timeout: 500,
buffer_first_touchmoves: 5, buffer_first_touchmoves: 5,
debug_print: false, debug_print: false,
min_zoom: 0.1, min_zoom: 0.01,
max_zoom: 10.0, max_zoom: 100.0,
}; };
function main() { function main() {

37
client/webgl_geometry.js

@ -129,3 +129,40 @@ function clear_dynamic_stroke(state, context) {
context.dynamic_positions_f32 = new Float32Array(0); context.dynamic_positions_f32 = new Float32Array(0);
context.dynamic_colors_u8 = new Uint8Array(0); context.dynamic_colors_u8 = new Uint8Array(0);
} }
function add_image(context, bitmap, p) {
const x = p.x;
const y = p.y;
const gl = context.gl;
const id = Object.keys(context.textures).length;
context.textures[id] = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, context.textures[id]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, bitmap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
context.quad_positions.push(...[
x, y,
x, y + bitmap.height,
x + bitmap.width, y + bitmap.height,
x + bitmap.width, y,
x, y,
x + bitmap.width, y + bitmap.height,
]);
context.quad_texcoords.push(...[
0, 0,
0, 1,
1, 1,
1, 0,
0, 0,
1, 1,
]);
context.quad_positions_f32 = new Float32Array(context.quad_positions);
context.quad_texcoords_f32 = new Float32Array(context.quad_texcoords);
}

57
client/webgl_listeners.js

@ -12,6 +12,14 @@ function init_listeners(state, context) {
context.canvas.addEventListener('touchmove', (e) => touchmove(e, state, context)); context.canvas.addEventListener('touchmove', (e) => touchmove(e, state, context));
context.canvas.addEventListener('touchend', (e) => touchend(e, state, context)); context.canvas.addEventListener('touchend', (e) => touchend(e, state, context));
context.canvas.addEventListener('touchcancel', (e) => touchend(e, state, context)); context.canvas.addEventListener('touchcancel', (e) => touchend(e, state, context));
context.canvas.addEventListener('drop', (e) => on_drop(e, state, context));
context.canvas.addEventListener('dragover', (e) => mousemove(e, state, context));
}
function cancel(e) {
e.preventDefault();
return false;
} }
function keydown(e, state, context) { function keydown(e, state, context) {
@ -45,7 +53,6 @@ function mousedown(e, state, context) {
const screenp = {'x': e.clientX, 'y': e.clientY}; const screenp = {'x': e.clientX, 'y': e.clientY};
const canvasp = screen_to_canvas(state, screenp); const canvasp = screen_to_canvas(state, screenp);
state.cursor = canvasp;
clear_dynamic_stroke(state, context); clear_dynamic_stroke(state, context);
update_dynamic_stroke(state, context, canvasp); update_dynamic_stroke(state, context, canvasp);
state.drawing = true; state.drawing = true;
@ -54,6 +61,8 @@ function mousedown(e, state, context) {
} }
function mousemove(e, state, context) { function mousemove(e, state, context) {
e.preventDefault();
let do_draw = false; let do_draw = false;
if (state.moving) { if (state.moving) {
@ -63,10 +72,11 @@ function mousemove(e, state, context) {
} }
const screenp = {'x': e.clientX, 'y': e.clientY}; const screenp = {'x': e.clientX, 'y': e.clientY};
const canvasp = screen_to_canvas(state, screenp);
state.cursor = screenp;
if (state.drawing) { if (state.drawing) {
const canvasp = screen_to_canvas(state, screenp);
state.cursor = canvasp;
update_dynamic_stroke(state, context, canvasp); update_dynamic_stroke(state, context, canvasp);
do_draw = true; do_draw = true;
} }
@ -74,6 +84,8 @@ function mousemove(e, state, context) {
if (do_draw) { if (do_draw) {
window.requestAnimationFrame(() => draw(state, context)); window.requestAnimationFrame(() => draw(state, context));
} }
return false;
} }
function mouseup(e, state, context) { function mouseup(e, state, context) {
@ -322,3 +334,42 @@ function touchend(e, state, context) {
waiting_for_second_finger = false; waiting_for_second_finger = false;
} }
} }
async function on_drop(e, state, context) {
e.preventDefault();
if (e.dataTransfer.files.length !== 1) {
return;
}
const file = e.dataTransfer.files[0];
const bitmap = await createImageBitmap(file);
const p = { 'x': state.cursor.x, 'y': state.cursor.y };
const canvasp = screen_to_canvas(state, p);
canvasp.x -= bitmap.width / 2;
canvasp.y -= bitmap.height / 2;
add_image(context, bitmap, canvasp);
// storage.ctx0.drawImage(bitmap, x, y);
const form_data = new FormData();
form_data.append('file', file);
const resp = await fetch(`/api/image?deskId=333`, {
method: 'post',
body: form_data,
})
if (resp.ok) {
// const image_id = await resp.text();
// const event = image_event(image_id, x, y);
// await queue_event(event);
}
window.requestAnimationFrame(() => draw(state, context));
return false;
}

41
client/webgl_shaders.js

@ -112,47 +112,6 @@ function init_webgl(state, context) {
'b_texcoord': context.gl.createBuffer(), 'b_texcoord': context.gl.createBuffer(),
}; };
context.textures['test'] = gl.createTexture();
// Fill the texture with a 1x1 blue pixel.
gl.bindTexture(gl.TEXTURE_2D, context.textures['test']);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([0, 0, 255, 255]));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
var image = new Image();
image.src = "http://192.168.100.2/images/3697505915";
image.addEventListener('load', function() {
// Now that the image has loaded make copy it to the texture.
context.quad_positions = [
100, 100,
100, 100 + image.height,
100 + image.width, 100 + image.height,
100 + image.width, 100,
100, 100,
100 + image.width, 100 + image.height,
];
context.quad_texcoords = [
0, 0,
0, 1,
1, 1,
1, 0,
0, 0,
1, 1,
];
context.quad_positions_f32 = new Float32Array(context.quad_positions);
context.quad_texcoords_f32 = new Float32Array(context.quad_texcoords);
gl.bindTexture(gl.TEXTURE_2D, context.textures['test']);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image);
});
const resize_canvas = (entries) => { const resize_canvas = (entries) => {
// https://www.khronos.org/webgl/wiki/HandlingHighDPI // https://www.khronos.org/webgl/wiki/HandlingHighDPI
const entry = entries[0]; const entry = entries[0];

Loading…
Cancel
Save