From 666d0393d882612e9f44c8c1cd94d7a5199cf61c Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sun, 24 Nov 2024 23:39:55 +0300 Subject: [PATCH] Resurrect image handles --- client/aux.js | 6 ++++ client/webgl_draw.js | 68 +++++++++++++++------------------------- client/webgl_geometry.js | 52 ++++++++++++++++-------------- client/webgl_shaders.js | 1 + 4 files changed, 62 insertions(+), 65 deletions(-) diff --git a/client/aux.js b/client/aux.js index 67eb18f..e7f18a1 100644 --- a/client/aux.js +++ b/client/aux.js @@ -142,6 +142,12 @@ function tv_create_on(class_name, capacity, buffer, offset) { }; } +function tv_wrap(view) { + const result = tv_create_on(view.constructor, view.length, view.buffer, 0); + result.size = view.length; + return result; +} + function tv_data(tv) { return tv.data.subarray(0, tv.size); } diff --git a/client/webgl_draw.js b/client/webgl_draw.js index 783df61..143469a 100644 --- a/client/webgl_draw.js +++ b/client/webgl_draw.js @@ -61,7 +61,7 @@ function upload_square_rgba16ui_texture(gl, serializer, texture_size) { // Upload last row if (last_row > 0) { const last_row_upload = last_row * bpp; - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, rows_uploaded, last_row, 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, whole_upload, last_row_upload)); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, rows_uploaded, last_row, 1, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, new Uint16Array(serializer.buffer, whole_upload, last_row_upload / 2)); } serializer.gpu_upload_from = serializer.offset; @@ -105,6 +105,7 @@ function draw_strokes(state, width, height, programs, gl, lod_levels, segment_co vbo, ebo, stroke_texture, + stroke_texture_size, stroke_data, stroke_count, ) { @@ -143,7 +144,7 @@ function draw_strokes(state, width, height, programs, gl, lod_levels, segment_co // Per-stroke data (base width, color) gl.bindTexture(gl.TEXTURE_2D, stroke_texture); - upload_square_rgba16ui_texture(gl, stroke_data, config.stroke_texture_size); + upload_square_rgba16ui_texture(gl, stroke_data, stroke_texture_size); gl.uniform2f(pr.locations['u_res'], width, height); gl.uniform2f(pr.locations['u_scale'], state.canvas.zoom, state.canvas.zoom); @@ -414,6 +415,7 @@ async function draw(state, context, animate, ts) { buffers['b_strokes_static'], buffers['i_strokes_static'], textures['stroke_data'], + config.stroke_texture_size, context.stroke_data, state.events.length, // not really ); @@ -435,6 +437,7 @@ async function draw(state, context, animate, ts) { buffers['b_strokes_dynamic'], buffers['i_strokes_dynamic'], textures['dynamic_stroke_data'], + config.stroke_texture_size, context.dynamic_stroke_data, context.dynamic_stroke_count, ); @@ -442,50 +445,31 @@ async function draw(state, context, animate, ts) { // HUD: resize handles, etc if (state.active_image !== null) { - const pr = programs['main']; // same as static + gl.clear(gl.DEPTH_BUFFER_BIT); + const handles = geometry_generate_handles(state, context, state.active_image); const ui_segments = 7 * 4 - 1; // each square = 4, each line = 1, square->line = 1, line->square = 1 + const hud_batches = tv_create(Uint32Array, 4); - gl.bindBuffer(gl.ARRAY_BUFFER, buffers['b_hud']); - gl.bufferData(gl.ARRAY_BUFFER, handles.points.byteLength + handles.ids.byteLength + handles.pressures.byteLength, gl.STREAM_DRAW); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, handles.points); - gl.bufferSubData(gl.ARRAY_BUFFER, handles.points.byteLength, handles.ids); - gl.bufferSubData(gl.ARRAY_BUFFER, handles.points.byteLength + handles.ids.byteLength, handles.pressures); - - gl.bindTexture(gl.TEXTURE_2D, textures['ui']); - upload_square_rgba16ui_texture(gl, handles.stroke_data, config.ui_texture_size); + tv_add(hud_batches, 0); + tv_add(hud_batches, compute_circle_lod(state.canvas.zoom * 2)); + tv_add(hud_batches, ui_segments); + tv_add(hud_batches, -1); - 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.uniform1i(pr.locations['u_stroke_count'], 8); - gl.uniform1i(pr.locations['u_debug_mode'], 0); - gl.uniform1i(pr.locations['u_stroke_data'], 0); - gl.uniform1i(pr.locations['u_stroke_texture_size'], config.ui_texture_size); - - gl.enableVertexAttribArray(pr.locations['a_a']); - gl.enableVertexAttribArray(pr.locations['a_b']); - gl.enableVertexAttribArray(pr.locations['a_stroke_id']); - gl.enableVertexAttribArray(pr.locations['a_pressure']); - - gl.vertexAttribPointer(pr.locations['a_a'], 2, gl.FLOAT, false, 2 * 4, 0); - gl.vertexAttribPointer(pr.locations['a_b'], 2, gl.FLOAT, false, 2 * 4, 2 * 4); - gl.vertexAttribIPointer(pr.locations['a_stroke_id'], 1, gl.INT, 4, handles.points.byteLength); - gl.vertexAttribPointer(pr.locations['a_pressure'], 2, gl.UNSIGNED_BYTE, true, 1, handles.points.byteLength + handles.ids.byteLength); - - gl.vertexAttribDivisor(pr.locations['a_a'], 1); - gl.vertexAttribDivisor(pr.locations['a_b'], 1); - gl.vertexAttribDivisor(pr.locations['a_stroke_id'], 1); - gl.vertexAttribDivisor(pr.locations['a_pressure'], 1); - - gl.drawArraysInstanced(gl.TRIANGLES, 0, 32 * 3 + 6 + 32 * 3, ui_segments); - - // I don't really know why I need to do this, but it - // makes background patter drawcall work properly - gl.vertexAttribDivisor(pr.locations['a_a'], 0); - gl.vertexAttribDivisor(pr.locations['a_b'], 0); - gl.vertexAttribDivisor(pr.locations['a_stroke_id'], 0); - gl.vertexAttribDivisor(pr.locations['a_pressure'], 0); + draw_strokes(state, context.canvas.width, context.canvas.height, programs, gl, lod_levels, ui_segments, + total_lod_floats, + total_lod_indices, + hud_batches, + handles.points, + handles.ids, + handles.pressures, + buffers['b_hud'], + buffers['i_hud'], + textures['ui'], + config.ui_texture_size, + handles.stroke_data, + 8 + ); } if (config.draw_bvh) { diff --git a/client/webgl_geometry.js b/client/webgl_geometry.js index 1bde4c7..ebfb8b7 100644 --- a/client/webgl_geometry.js +++ b/client/webgl_geometry.js @@ -128,25 +128,10 @@ function recompute_dynamic_data(state, context) { ser_u16(context.dynamic_stroke_data, b); ser_u16(context.dynamic_stroke_data, stroke.width); - let lod; const perceptual_width = stroke.width * state.canvas.zoom; - // Copypaste from the WASM version @lod - if (perceptual_width < 1.9) { - lod = 0; - } else if (perceptual_width < 4.56) { - lod = 1; - } else if (perceptual_width < 6.12) { - lod = 2; - } else if (perceptual_width < 25.08) { - lod = 3; - } else if (perceptual_width < 122.74) { - lod = 4; - } else if (perceptual_width < 1710.0) { - lod = 5; - } else { - lod = 6; - } + const lod = compute_circle_lod(perceptual_width); + // Copypaste from the WASM version @lod if (batch_size > 0 && lod !== last_lod) { tv_add(context.dynamic_instance_batches, batch_size); tv_add(context.dynamic_instance_batches, last_lod); @@ -178,6 +163,28 @@ function recompute_dynamic_data(state, context) { } } +function compute_circle_lod(perceptual_width) { + let lod; + + if (perceptual_width < 1.9) { + lod = 0; + } else if (perceptual_width < 4.56) { + lod = 1; + } else if (perceptual_width < 6.12) { + lod = 2; + } else if (perceptual_width < 25.08) { + lod = 3; + } else if (perceptual_width < 122.74) { + lod = 4; + } else if (perceptual_width < 1710.0) { + lod = 5; + } else { + lod = 6; + } + + return lod; +} + function geometry_start_prestroke(state, player_id) { if (!state.online) return; @@ -480,7 +487,6 @@ function geometry_generate_handles(state, context, active_image) { } } - const x1 = image.at.x; const y1 = image.at.y; const x2 = image.at.x + image.width; @@ -562,13 +568,13 @@ function geometry_generate_handles(state, context, active_image) { ser_u16(stroke_data, 34); ser_u16(stroke_data, 139); ser_u16(stroke_data, 230); - ser_u16(stroke_data, 0); + ser_u16(stroke_data, 2); } - + return { - 'points': points, - 'ids': ids, - 'pressures': pressures, + 'points': tv_wrap(points), + 'ids': tv_wrap(ids), + 'pressures': tv_wrap(pressures), 'stroke_data': stroke_data, }; } diff --git a/client/webgl_shaders.js b/client/webgl_shaders.js index 0ec0773..dfe78f8 100644 --- a/client/webgl_shaders.js +++ b/client/webgl_shaders.js @@ -363,6 +363,7 @@ function init_webgl(state, context) { 'b_instance_grid': gl.createBuffer(), 'b_dot': gl.createBuffer(), 'b_hud': gl.createBuffer(), + 'i_hud': gl.createBuffer(), 'b_iquads': gl.createBuffer(), };