diff --git a/index.html b/index.html index 8610584..ccfc5f8 100644 --- a/index.html +++ b/index.html @@ -6,5 +6,13 @@ +
+ + + diff --git a/index.js b/index.js index 5410707..4bcc819 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,8 @@ const runWasm = async () => { const result = rustWasm.de_iavascriptis(0, 1); console.log("Should be undefined: ", rustWasm.add_integer_with_constant); - document.body.textContent = `Gamarjoba! result: ${result}`; + const div = document.querySelector("#textBuf"); + div.textContent = `Gamarjoba! result: ${result}`; const NUMBER = 257; @@ -21,6 +22,57 @@ const runWasm = async () => { wasmMemory[ptr+1] = 15; console.log(rustWasm.read_wasm_mem_buffer_idx_1()); // should be 15 + + const canvasElement = document.querySelector("canvas"); + + // Set up Context and ImageData on the canvas + const canvasContext = canvasElement.getContext("2d"); + const canvasImageData = canvasContext.createImageData( + canvasElement.width, + canvasElement.height + ); + + canvasContext.clearRect(0, 0, canvasElement.width, canvasElement.height); + + const getDarkValue = () => Math.floor(Math.random() * 100); + const getLightValue = () => Math.floor(Math.random() * 127) + 127; + + const drawCheckerBoard = () => { + const checkerBoardSize = 20; + + // Generate a new checkboard in wasm + rustWasm.generate_checkerboard( + getDarkValue(), + getDarkValue(), + getDarkValue(), + getLightValue(), + getLightValue(), + getLightValue() + ); + + // Pull out the RGBA values from Wasm memory + // Starting at the memory index of out output buffer (given by our pointer) + // 20 * 20 * 4 = checkboard max X * checkerboard max Y * number of pixel properties (R,G.B,A) + const outputPointer = rustWasm.get_output_buf_ptr(); + const imageDataArray = wasmMemory.slice( + outputPointer, + outputPointer + checkerBoardSize * checkerBoardSize * 4 + ); + + // Set the values to the canvas image data + canvasImageData.data.set(imageDataArray); + + // Clear the canvas + canvasContext.clearRect(0, 0, canvasElement.width, canvasElement.height); + + // Place the new generated checkerboard onto the canvas + canvasContext.putImageData(canvasImageData, 0, 0); + }; + + drawCheckerBoard(); + setInterval(() => { + drawCheckerBoard(); + }, 300); }; runWasm(); diff --git a/src/lib.rs b/src/lib.rs index 458c246..c67ea4b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,3 +45,53 @@ pub fn read_wasm_mem_buffer_idx_1() -> u8 { }; value } + +// Checkerboard example + +const CHECKERBOARD_SIZE: usize = 20; + +// 20x20 grid, (r,g,b,a) per grid cell +const OUTPUT_BUF_SIZE: usize = CHECKERBOARD_SIZE * CHECKERBOARD_SIZE * 4; +static mut OUTPUT_BUF: [u8; OUTPUT_BUF_SIZE] = [0; OUTPUT_BUF_SIZE]; + +#[wasm_bindgen] +pub fn get_output_buf_ptr() -> *const u8 { + unsafe { + OUTPUT_BUF.as_ptr() as *const u8 + } +} + +#[wasm_bindgen] +pub fn generate_checkerboard(dark_red: u8, dark_green: u8, dark_blue: u8, light_red: u8, light_green: u8, light_blue: u8) { + for y in 0..CHECKERBOARD_SIZE { + for x in 0..CHECKERBOARD_SIZE { + + let dark_square = { + let mut b = y % 2 == 0; + if x % 2 == 0 { + b = !b; + } + b + }; + + // Now that we determined if we are dark or light, + // Let's set our square value + let square_value_red = if dark_square { dark_red } else { light_red }; + let square_value_green = if dark_square { dark_green } else { light_green }; + let square_value_blue = if dark_square { dark_blue } else { light_blue }; + + // Let's calculate our index, using our 2d -> 1d mapping. + // And then multiple by 4, for each pixel property (r,g,b,a). + let square_number: usize = y * CHECKERBOARD_SIZE + x; + let rgba_index: usize = square_number * 4; + + // Finally store the values. + unsafe { + OUTPUT_BUF[rgba_index + 0] = square_value_red; + OUTPUT_BUF[rgba_index + 1] = square_value_green; + OUTPUT_BUF[rgba_index + 2] = square_value_blue; + OUTPUT_BUF[rgba_index + 3] = 255; // Alpha (Always Opaque) + } + } + } +}