Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 9 additions & 20 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,69 +13,58 @@ <h1>Olive.c Demos</h1>
<div id="sec-triangle">
<h2 id="demo-triangle"><a href="#demo-triangle">Triangle</a></h2>
<p>Rainbow triangle together with a transparent circle. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangle.c">demos/triangle.c</a></p>
<canvas id="app-triangle"></canvas>
<olivec-canvas src="./wasm/triangle.wasm" />
</div>

<div id="sec-dots3d">
<h2 id="demo-dots3d"><a href="#demo-dots3d">Dots 3D</a></h2>
<p>A bunch of 3D dots projected onto your 2D screen plus a text with a builtin monospaced font. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/dots3d.c">demos/dots3d.c</a></p>
<canvas id="app-dots3d"></canvas>
<olivec-canvas src="./wasm/dots3d.wasm" />
</div>

<div id="sec-squish">
<h2 id="demo-squish"><a href="#demo-squish">Squish</a></h2>
<p>Resizing images on the fly. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/squish.c">demos/squish.c</a></p>
<canvas id="app-squish"></canvas>
<olivec-canvas src="./wasm/squish.wasm" />
</div>

<div id="sec-triangle3d">
<h2 id="demo-triangle3d"><a href="#demo-triangle3d">Triangle 3D</a></h2>
<p>Rotating rainbow triangle in 3D. Unlike <a href="#demo-3d">3D dots above</a> this is a solid shape. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangle3d.c">demos/triangle3d.c</a></p>
<canvas id="app-triangle3d"></canvas>
<olivec-canvas src="./wasm/triangle3d.wasm" />
</div>

<div id="sec-triangleTex">
<h2 id="demo-triangleTex"><a href="#demo-triangleTex">Rotating 2D Textures</a></h2>
<p>Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangleTex.c">demos/triangleTex.c</a></p>
<canvas id="app-triangleTex"></canvas>
<olivec-canvas src="./wasm/triangleTex.wasm" />
</div>

<div id="sec-triangle3dTex">
<h2 id="demo-triangle3dTex"><a href="#demo-triangle3dTex">Rotating 3D Textures</a></h2>
<p>Textures by <a href="https://opengameart.org/content/handpainted-stone-texture">MELLE</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangle3dTex.c">demos/triangle3dTex.c</a></p>
<canvas id="app-triangle3dTex"></canvas>
<olivec-canvas src="./wasm/triangle3dTex.wasm" />
</div>

<div id="sec-cup3d">
<h2 id="demo-cup3d"><a href="#demo-cup3d">Cup 3D</a></h2>
<p>Design by <a href="https://github.com/rexim">rexim</a>. 3D model by <a href="https://github.com/kolumb">kolumb</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/cup3d.c">demos/cup3d.c</a></p>
<canvas id="app-cup3d"></canvas>
<olivec-canvas src="./wasm/cup3d.wasm" />
</div>

<div id="sec-teapot3d">
<h2 id="demo-teapot3d"><a href="#demo-teapot3d">Utah Teapot</a></h2>
<p>Famous <a href="https://en.wikipedia.org/wiki/Utah_teapot">Utah Teapot</a>. Model by <a href="https://graphics.stanford.edu/courses/cs148-10-summer/as3/code/as3/teapot.obj">Standford University</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/teapot3d.c">demos/teapot3d.c</a></p>
<p>(I have no idea why it runs with a reasonable FPS)</p>
<canvas id="app-teapot3d"></canvas>
<olivec-canvas src="./wasm/teapot3d.wasm" />
</div>

<div id="sec-penger3d">
<h2 id="demo-penger3d"><a href="#demo-penger3d">Penger</a></h2>
<p><a href="https://penger.neocities.org/">Penger</a> - The Mascot of Tsoding Discord Community. The character design by <a href="https://github.com/LainLayer">LainLayer</a>. The model by <a href="https://github.com/Max-Kawula">Max-Kawula</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/penger3d.c">demos/penger3d.c</a></p>
<canvas id="app-penger3d"></canvas>
<olivec-canvas src="./wasm/penger3d.wasm" />
</div>

<script src="js/vc.js"></script>
<script>
startDemo("triangle", "./wasm/triangle.wasm");
startDemo("dots3d", "./wasm/dots3d.wasm");
startDemo("squish", "./wasm/squish.wasm");
startDemo("triangle3d", "./wasm/triangle3d.wasm");
startDemo("triangleTex", "./wasm/triangleTex.wasm");
startDemo("triangle3dTex", "./wasm/triangle3dTex.wasm");
startDemo("cup3d", "./wasm/cup3d.wasm");
startDemo("teapot3d", "./wasm/teapot3d.wasm");
startDemo("penger3d", "./wasm/penger3d.wasm");
</script>
</body>
</html>
63 changes: 45 additions & 18 deletions js/vc.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,11 @@ function readCanvasFromMemory(memory_buffer, canvas_ptr)
};
}

async function startDemo(elementId, wasmPath) {
const app = document.getElementById(`app-${elementId}`);
if (app === null) {
console.error(`Could not find element app-${elementId}. Skipping demo ${wasmPath}...`);
return;
}
const sec = document.getElementById(`sec-${elementId}`);
if (sec === null) {
console.error(`Could not find element sec-${elementId}. Skipping demo ${wasmPath}...`);
return;
}

let paused = true;
sec.addEventListener("mouseenter", () => paused = false);
sec.addEventListener("mouseleave", () => paused = true);

/**
* @param {HTMLCanvasElement} app
* @param {string} wasmPath
*/
async function startDemo(app, wasmPath) {
const ctx = app.getContext("2d");
const w = await WebAssembly.instantiateStreaming(fetch(wasmPath), {
"env": make_environment(libm)
Expand All @@ -67,7 +56,7 @@ async function startDemo(elementId, wasmPath) {
const buffer = w.instance.exports.memory.buffer;
w.instance.exports.vc_render(heap_base, dt*0.001);
const canvas = readCanvasFromMemory(buffer, heap_base);
if (canvas.width != canvas.stride) {
if (canvas.width !== canvas.stride) {
// TODO: maybe we can preallocate a Uint8ClampedArray on JavaScript side and just copy the canvas data there to bring width and stride to the same value?
console.error(`Canvas width (${canvas.width}) is not equal to its stride (${canvas.stride}). Unfortunately we can't easily support that in a browser because ImageData simply does not accept stride. Welcome to 2022.`);
return;
Expand All @@ -87,8 +76,46 @@ async function startDemo(elementId, wasmPath) {
function loop(timestamp) {
const dt = timestamp - prev;
prev = timestamp;
if (!paused) render(dt);
if (app.dataset['visible'] === 'true') render(dt);
window.requestAnimationFrame(loop);
}
window.requestAnimationFrame(first);
}

class OliveCanvas extends HTMLElement {
constructor() {
super();
}

connectedCallback() {
const wasmPath = this.getAttribute('src');
if (!wasmPath) {
console.error(`Should define a src attribute on olive-canvas`)
return;
}

const canvas = document.createElement("canvas");
this.appendChild(canvas);

// Create an observer that monitors entering/exiting the viewport
this.observer = new IntersectionObserver(
([entry]) => {
canvas.dataset['visible'] = String(entry.isIntersecting);
},
{
root: null,
rootMargin: '0px',
threshold: 0,
}
);

this.observer.observe(canvas);
startDemo(canvas, wasmPath);
}

disconnectedCallback() {
this.observer.disconnect();
}
}

customElements.define("olivec-canvas", OliveCanvas);