mirror of
https://github.com/muerwre/muerwre.github.io.git
synced 2025-04-25 02:46:39 +07:00
added webgl basics
This commit is contained in:
parent
509e2b9406
commit
189028c533
4 changed files with 381 additions and 0 deletions
|
@ -0,0 +1,68 @@
|
|||
Rendering items on #canvas in main loop ==might cause interface freezes==, preventing render process from executing properly by flooding execution stack with operations.
|
||||
|
||||
To handle it properly, we can start separate #worker thread, that will handle rendering in its own event loop, so that won't affect the source tab's event loop.
|
||||
|
||||
Workers can have access to [Transferrable Objects](https://developer.mozilla.org/en-US/docs/Glossary/Transferable_objects) from main thread by receiving memory address. ==That's a lot faster than cloning==. In this case [ImageBitmap](https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap) is transferrable.
|
||||
|
||||
Code for the main thread component:
|
||||
|
||||
```typescript
|
||||
// main.ts
|
||||
const instance = new Worker('./render-worker.ts');
|
||||
const canvas = document.getElementById('view');
|
||||
|
||||
// attaching event listener to worker
|
||||
instance.onmessage = (event: MessageEvent) => {
|
||||
const ctx = canvas?.getContext("2d");
|
||||
if (!ctx) {
|
||||
throw new Error(`Can't get 2D context`);
|
||||
}
|
||||
|
||||
ctx.drawImage(event.data as ImageBitmap, 0, 0);
|
||||
}
|
||||
|
||||
// sending canvas contents to worker
|
||||
const renderInCanvas = () => {
|
||||
if (!canvas.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
createImageBitmap(canvas.current).then(image => {
|
||||
instance.postMessage(image, { transfer: [image] })
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
Worker code:
|
||||
|
||||
```typescript
|
||||
// render-worker.ts
|
||||
export default () => {
|
||||
self.onmessage = (message: MessageEvent) => {
|
||||
const data = message.data;
|
||||
|
||||
if (!(data instanceof ImageBitmap)) {
|
||||
throw new Error('Received unknown data')
|
||||
}
|
||||
|
||||
// OffscreenCanvas can be set up inside workers
|
||||
const canvas = new OffscreenCanvas(data.width, data.height);
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
if (!ctx) {
|
||||
throw new Error(`Can't get 2D context`);
|
||||
}
|
||||
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
// That will block execution inside worker for
|
||||
// a couple of seconds
|
||||
doHardRenderingStuffHere(ctx, data.width, data.height);
|
||||
|
||||
// Sending resulting image back to main thread
|
||||
createImageBitmap(canvas).then((image) => {
|
||||
self.postMessage(image, { transfer: [image] });
|
||||
});
|
||||
};
|
||||
};
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue