From 64e39b8b68fd316eaa614499d4650104c6a77aab Mon Sep 17 00:00:00 2001 From: arjitgeo Date: Wed, 20 Mar 2024 17:50:41 +0530 Subject: [PATCH] Added C language demo to the 'reading-and-writing-graphics' example --- .../demo/C/README.md | 4 + .../demo/C/index.html | 15 ++++ .../demo/C/index.js | 75 ++++++++++++++++++ .../demo/C/index.wasm | Bin 0 -> 755 bytes .../demo/C/main.c | 74 +++++++++++++++++ .../demo/C/makefile | 2 + 6 files changed, 170 insertions(+) create mode 100644 examples/reading-and-writing-graphics/demo/C/README.md create mode 100644 examples/reading-and-writing-graphics/demo/C/index.html create mode 100644 examples/reading-and-writing-graphics/demo/C/index.js create mode 100755 examples/reading-and-writing-graphics/demo/C/index.wasm create mode 100644 examples/reading-and-writing-graphics/demo/C/main.c create mode 100644 examples/reading-and-writing-graphics/demo/C/makefile diff --git a/examples/reading-and-writing-graphics/demo/C/README.md b/examples/reading-and-writing-graphics/demo/C/README.md new file mode 100644 index 0000000..417aa79 --- /dev/null +++ b/examples/reading-and-writing-graphics/demo/C/README.md @@ -0,0 +1,4 @@ +# Reading And Writing Graphics (C) +```bash +clang -target wasm32 -O3 -flto -nostdlib -Wl,--no-entry -Wl,--export-all -o index.wasm main.c +``` \ No newline at end of file diff --git a/examples/reading-and-writing-graphics/demo/C/index.html b/examples/reading-and-writing-graphics/demo/C/index.html new file mode 100644 index 0000000..a6b2054 --- /dev/null +++ b/examples/reading-and-writing-graphics/demo/C/index.html @@ -0,0 +1,15 @@ + + + + + Reading and Writing Graphics - C + + + + + + \ No newline at end of file diff --git a/examples/reading-and-writing-graphics/demo/C/index.js b/examples/reading-and-writing-graphics/demo/C/index.js new file mode 100644 index 0000000..5d97b2d --- /dev/null +++ b/examples/reading-and-writing-graphics/demo/C/index.js @@ -0,0 +1,75 @@ +// Imports are from the demo-util folder in the repo +// https://github.com/torch2424/wasm-by-example/blob/master/demo-util/ + +import { wasmBrowserInstantiate } from "/demo-util/instantiateWasm.js"; + +const runWasm = async () => { + // Instantiate our wasm module + const wasmModule = await wasmBrowserInstantiate("./index.wasm"); + + // Get our exports object, with all of our exported Wasm Properties + const exports = wasmModule.instance.exports; + + // Get our memory object from the exports + const memory = exports.memory; + + // Create a Uint8Array to give us access to Wasm Memory + const wasmByteMemoryArray = new Uint8Array(memory.buffer); + + // Get our canvas element from our index.html + 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 + ); + + // Clear the canvas + canvasContext.clearRect(0, 0, canvasElement.width, canvasElement.height); + + const getDarkValue = () => { + return Math.floor(Math.random() * 100); + }; + + const getLightValue = () => { + return Math.floor(Math.random() * 127) + 127; + }; + + const drawCheckerBoard = () => { + const checkerBoardSize = 20; + + // Generate a new checkboard in wasm + exports.generateCheckerBoard( + getDarkValue(), + getDarkValue(), + getDarkValue(), + getLightValue(), + getLightValue(), + getLightValue() + ); + + // Pull out the RGBA values from Wasm memory, the we wrote to in wasm, + // starting at the checkerboard pointer (memory array index) + const startIndex = exports.CHECKERBOARD_BUFFER.valueOf(); // pointer + const endIndex = startIndex + exports.getCheckboardSize(); + + const imageDataArray = wasmByteMemoryArray.slice(startIndex, endIndex); + + // 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(); + }, 1000); +}; +runWasm(); \ No newline at end of file diff --git a/examples/reading-and-writing-graphics/demo/C/index.wasm b/examples/reading-and-writing-graphics/demo/C/index.wasm new file mode 100755 index 0000000000000000000000000000000000000000..f574c70b30820eaf81e08ee9ed875f44b80c40ba GIT binary patch literal 755 zcmZva&u-d45XNV{#s-@drRA2(!l@Mn@mEPJRjr|U@G-{xVu&)Av%viORiJR5x+k3Nkj!_U^_Js)12pN}V$lsR{kh|fjn z21pe{N|6eVp-ZXBd6Ej}k_XW>RVA6L`NEsi!V%|Q5ZNN&wn&g_5}u=2rfYMQnCw%b8Xr|+0%k*iu!CQI@$WI|^pziwL8 zxBigV0L-)$pDC=s3}#4n%!()SRWG09MdCBURCbUI7(K)i_G<ttxl`Uo;MoZcDLW|bxzyeUcWnN zpljplObli?d)4gR;%3#keSi%5z1CUx1-z`JB9@ng&rqc67!##YS+4i4G;>>%Mlo4< IVG}p$Un4QeZvX%Q literal 0 HcmV?d00001 diff --git a/examples/reading-and-writing-graphics/demo/C/main.c b/examples/reading-and-writing-graphics/demo/C/main.c new file mode 100644 index 0000000..ae73738 --- /dev/null +++ b/examples/reading-and-writing-graphics/demo/C/main.c @@ -0,0 +1,74 @@ +#include +#include + +// Define the size of our checkerboard +#define CHECKERBOARD_SIZE 20 + +// Create a buffer to where in memory +// we are storing the pixels. +uint8_t CHECKERBOARD_BUFFER[CHECKERBOARD_SIZE * CHECKERBOARD_SIZE * 4] = { 0 }; + +// Function to generate our checkerboard, pixel by pixel +void +generateCheckerBoard( + uint8_t darkValueRed, + uint8_t darkValueGreen, + uint8_t darkValueBlue, + uint8_t lightValueRed, + uint8_t lightValueGreen, + uint8_t lightValueBlue +) { + // Since Linear memory is a 1 dimensional array, but we want a grid + // we will be doing 2d to 1d mapping + // https://softwareengineering.stackexchange.com/questions/212808/treating-a-1d-data-structure-as-2d-grid + for (int x = 0; x < CHECKERBOARD_SIZE; x++) + { + for (int y = 0; y < CHECKERBOARD_SIZE; y++) + { + + // Set our default case to be dark squares + bool isDarkSquare = true; + + // We should change our default case if + // We are on an odd y + if (y % 2 == 0) + { + isDarkSquare = false; + } + + // Lastly, alternate on our x value + if (x % 2 == 0) + { + isDarkSquare = !isDarkSquare; + } + + // Now that we determined if we are dark or light, + // Let's set our square value + uint8_t squareValueRed = darkValueRed; + uint8_t squareValueGreen = darkValueGreen; + uint8_t squareValueBlue = darkValueBlue; + if (!isDarkSquare) + { + squareValueRed = lightValueRed; + squareValueGreen = lightValueGreen; + squareValueBlue = lightValueBlue; + } + + // Let's calculate our index, using our 2d -> 1d mapping. + // And then multiple by 4, for each pixel property (r,g,b,a). + int squareNumber = (x * CHECKERBOARD_SIZE) + y; + int squareRgbaIndex = squareNumber * 4; + + // Finally store the values. + CHECKERBOARD_BUFFER[squareRgbaIndex + 0] = squareValueRed; + CHECKERBOARD_BUFFER[squareRgbaIndex + 1] = squareValueGreen; + CHECKERBOARD_BUFFER[squareRgbaIndex + 2] = squareValueBlue; + CHECKERBOARD_BUFFER[squareRgbaIndex + 3] = 255; // Alpha (Always opaque) + } + } +} + +uint32_t getCheckboardSize() +{ + return CHECKERBOARD_SIZE * CHECKERBOARD_SIZE * 4; +} \ No newline at end of file diff --git a/examples/reading-and-writing-graphics/demo/C/makefile b/examples/reading-and-writing-graphics/demo/C/makefile new file mode 100644 index 0000000..61fdfa5 --- /dev/null +++ b/examples/reading-and-writing-graphics/demo/C/makefile @@ -0,0 +1,2 @@ +index.wasm: main.c + clang -target wasm32 -O3 -flto -nostdlib -Wl,--no-entry -Wl,--export-all -o index.wasm main.c