Draw checkerboard

This commit is contained in:
Greg Shuflin 2023-11-19 04:18:46 -08:00
parent 4b73c0d8c2
commit 4c8b52a2ec
3 changed files with 111 additions and 1 deletions

View File

@ -6,5 +6,13 @@
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="textBuf"></div>
<canvas
width="20"
height="20"
style="image-rendering: pixelated; image-rendering: crisp-edges; width: 100%; max-width: 500px;"
>
</canvas>
</body>
</html>

View File

@ -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();

View File

@ -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)
}
}
}
}