From f24e8d386b5a8cd31229facbfa478bc150a35662 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Fri, 14 Apr 2023 22:14:14 +0300 Subject: [PATCH] Pictures good --- client/webgl.js | 15 +++++++---- client/webgl_geometry.js | 37 +++++++++++++++++++++++++ client/webgl_listeners.js | 57 ++++++++++++++++++++++++++++++++++++--- client/webgl_shaders.js | 41 ---------------------------- 4 files changed, 101 insertions(+), 49 deletions(-) diff --git a/client/webgl.js b/client/webgl.js index 47247c5..e54f31e 100644 --- a/client/webgl.js +++ b/client/webgl.js @@ -25,8 +25,7 @@ function draw(state, context) { 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.uniform1i(locations['u_layer'], 0); - gl.uniform1i(locations['u_texture'], 0); - + gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_pos']); gl.vertexAttribPointer(locations['a_pos'], 2, gl.FLOAT, false, 0, 0); gl.bufferData(gl.ARRAY_BUFFER, context.quad_positions_f32, gl.STATIC_DRAW); @@ -35,7 +34,13 @@ function draw(state, context) { gl.vertexAttribPointer(locations['a_texcoord'], 2, gl.FLOAT, false, 0, 0); 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 locations = context.locations['stroke']; @@ -78,8 +83,8 @@ const config = { second_finger_timeout: 500, buffer_first_touchmoves: 5, debug_print: false, - min_zoom: 0.1, - max_zoom: 10.0, + min_zoom: 0.01, + max_zoom: 100.0, }; function main() { diff --git a/client/webgl_geometry.js b/client/webgl_geometry.js index 2567ca3..71e27af 100644 --- a/client/webgl_geometry.js +++ b/client/webgl_geometry.js @@ -128,4 +128,41 @@ function clear_dynamic_stroke(state, context) { context.dynamic_colors.length = 0; context.dynamic_positions_f32 = new Float32Array(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); } \ No newline at end of file diff --git a/client/webgl_listeners.js b/client/webgl_listeners.js index e63763e..4f55937 100644 --- a/client/webgl_listeners.js +++ b/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('touchend', (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) { @@ -45,7 +53,6 @@ function mousedown(e, state, context) { const screenp = {'x': e.clientX, 'y': e.clientY}; const canvasp = screen_to_canvas(state, screenp); - state.cursor = canvasp; clear_dynamic_stroke(state, context); update_dynamic_stroke(state, context, canvasp); state.drawing = true; @@ -54,6 +61,8 @@ function mousedown(e, state, context) { } function mousemove(e, state, context) { + e.preventDefault(); + let do_draw = false; if (state.moving) { @@ -63,10 +72,11 @@ function mousemove(e, state, context) { } const screenp = {'x': e.clientX, 'y': e.clientY}; + const canvasp = screen_to_canvas(state, screenp); + + state.cursor = screenp; if (state.drawing) { - const canvasp = screen_to_canvas(state, screenp); - state.cursor = canvasp; update_dynamic_stroke(state, context, canvasp); do_draw = true; } @@ -74,6 +84,8 @@ function mousemove(e, state, context) { if (do_draw) { window.requestAnimationFrame(() => draw(state, context)); } + + return false; } function mouseup(e, state, context) { @@ -321,4 +333,43 @@ function touchend(e, state, context) { state.touch.moving = 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; } \ No newline at end of file diff --git a/client/webgl_shaders.js b/client/webgl_shaders.js index 41deb6c..88d59eb 100644 --- a/client/webgl_shaders.js +++ b/client/webgl_shaders.js @@ -112,47 +112,6 @@ function init_webgl(state, context) { '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) => { // https://www.khronos.org/webgl/wiki/HandlingHighDPI const entry = entries[0];