webgpu embedding
This commit is contained in:
parent
47bd4da0e3
commit
a879c834c7
4 changed files with 86 additions and 4 deletions
|
|
@ -54,6 +54,7 @@ function stub(name) {
|
|||
"wgpuRegisterMeshBLAS", "wgpuRegisterMeshBLASDeviceAabbs", "wgpuRefitMeshBLASDeviceAabbs",
|
||||
"wgpuLoadRTPipeline", "wgpuDispatchRT", "wgpuBuildTLAS",
|
||||
"wgpuLoadComputePipeline", "wgpuDispatchCompute",
|
||||
"wgpuSetCanvasMount",
|
||||
]) {
|
||||
// Read-write ints don't need a stub-throw; return 0 for the size queries.
|
||||
e[n] = n.endsWith("Width") || n.endsWith("Height")
|
||||
|
|
@ -85,6 +86,11 @@ canvas.style.cssText = "position:fixed;inset:0;width:100vw;height:100vh;display:
|
|||
document.body.style.margin = "0";
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
// Optional mount target set via wgpuSetCanvasMount() (below). When null the
|
||||
// canvas is a full-viewport fixed layer (the original, unchanged default);
|
||||
// when set, the canvas is reparented into that element and sized to it.
|
||||
let mountEl = null;
|
||||
|
||||
function syncCanvasSize() {
|
||||
// Canvas pixel size = CSS size × devicePixelRatio so the GPU draws
|
||||
// at physical pixel resolution on HiDPI displays — otherwise the
|
||||
|
|
@ -98,8 +104,18 @@ function syncCanvasSize() {
|
|||
// share the physical-pixel coordinate space with window.width/.height.
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
window.crafter_dpr = dpr;
|
||||
const w = Math.max(1, Math.round(window.innerWidth * dpr));
|
||||
const h = Math.max(1, Math.round(window.innerHeight * dpr));
|
||||
// Mounted → track the host element's box; unmounted → the viewport.
|
||||
let cssW, cssH;
|
||||
if (mountEl) {
|
||||
const r = mountEl.getBoundingClientRect();
|
||||
cssW = r.width;
|
||||
cssH = r.height;
|
||||
} else {
|
||||
cssW = window.innerWidth;
|
||||
cssH = window.innerHeight;
|
||||
}
|
||||
const w = Math.max(1, Math.round(cssW * dpr));
|
||||
const h = Math.max(1, Math.round(cssH * dpr));
|
||||
if (canvas.width !== w) canvas.width = w;
|
||||
if (canvas.height !== h) canvas.height = h;
|
||||
return { w, h };
|
||||
|
|
@ -566,6 +582,40 @@ const env = window.crafter_webbuild_env;
|
|||
env.wgpuGetCanvasWidth = () => canvas.width;
|
||||
env.wgpuGetCanvasHeight = () => canvas.height;
|
||||
|
||||
// Reparent the render canvas into a host DOM element so a Crafter.Graphics
|
||||
// scene can render inline inside an app's own layout instead of as a
|
||||
// full-page layer. `idPtr`/`idLen` is a UTF-8 wasm string:
|
||||
// - non-empty id of an existing element → move the canvas into it,
|
||||
// position it to fill it (absolute inset:0), and size the render
|
||||
// surface to that element's box (syncCanvasSize picks it up per frame).
|
||||
// - empty string → detach back to <body> and hide it (display:none), so
|
||||
// the host page is a plain DOM document again.
|
||||
// The element is made position:relative if it is otherwise static, so the
|
||||
// absolutely-positioned canvas anchors to it. Pointer events pass through
|
||||
// (the inline use cases are non-interactive display surfaces).
|
||||
env.wgpuSetCanvasMount = (idPtr, idLen) => {
|
||||
const id = idLen > 0
|
||||
? new TextDecoder().decode(memU8().subarray(idPtr, idPtr + idLen))
|
||||
: "";
|
||||
if (!id) {
|
||||
mountEl = null;
|
||||
if (canvas.parentNode !== document.body) document.body.appendChild(canvas);
|
||||
canvas.style.cssText = "position:fixed;inset:0;width:100vw;height:100vh;display:none;";
|
||||
return;
|
||||
}
|
||||
const el = document.getElementById(id);
|
||||
if (!el) {
|
||||
console.warn(`[crafter-wgpu] wgpuSetCanvasMount: no element #${id}`);
|
||||
return;
|
||||
}
|
||||
mountEl = el;
|
||||
if (getComputedStyle(el).position === "static") el.style.position = "relative";
|
||||
if (canvas.parentNode !== el) el.appendChild(canvas);
|
||||
canvas.style.cssText =
|
||||
"position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;";
|
||||
ensureSized();
|
||||
};
|
||||
|
||||
env.wgpuCreateBuffer = (byteSize) => {
|
||||
const h = newHandle();
|
||||
const buf = device.createBuffer({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue