framebuffer tga download
This commit is contained in:
parent
c9a65e3bcf
commit
717e73d32d
@ -9,7 +9,7 @@ function makeSliders()
|
||||
const sliders = {
|
||||
subpixelOptions: new RowHeader("global options"),
|
||||
mode: new Select("mode", ["supersampling", "subpixel"]),
|
||||
scale: new Slider("scale", 0.0, 0.01),
|
||||
scale: new Slider("scale", 0.0, 0.05),
|
||||
translateX: new Slider("translate x", -1, 1),
|
||||
translateY: new Slider("translate y", -1, 1),
|
||||
multisampleCount: new Slider("multisampleCount", 1, 4, 1),
|
||||
|
||||
@ -65,6 +65,11 @@
|
||||
font: 0.8rem sans-serif;
|
||||
}
|
||||
|
||||
input[type="button"] {
|
||||
width: calc(100% - 1.1em);
|
||||
grid-column: 1 / span 3;
|
||||
}
|
||||
|
||||
input[type="range"], input[type="text"] {
|
||||
height: 1rem;
|
||||
}
|
||||
@ -100,6 +105,10 @@
|
||||
<control-root>
|
||||
<control-main>
|
||||
<control-grid id="control-parent">
|
||||
<row>
|
||||
<input id="download-framebuffer" type="button" value="download framebuffer"></input>
|
||||
</row>
|
||||
<row-separator></row-separator>
|
||||
</control-grid>
|
||||
</control-main>
|
||||
</control-root>
|
||||
|
||||
130
index.js
130
index.js
@ -56,6 +56,7 @@ module.memory = memory;
|
||||
|
||||
var depthTexture = undefined;
|
||||
var multisampleTexture = undefined;
|
||||
var copyTexture = undefined;
|
||||
|
||||
const eyeValueX = document.getElementById("eye-value-x");
|
||||
const eyeValueY = document.getElementById("eye-value-y");
|
||||
@ -64,6 +65,9 @@ const eyeValueZ = document.getElementById("eye-value-z");
|
||||
const yawValue = document.getElementById("yaw");
|
||||
const pitchValue = document.getElementById("pitch");
|
||||
|
||||
var downloadFramebufferPending = false;
|
||||
var tempBuffer = undefined;
|
||||
|
||||
function recreateDepth(canvasTexture, sampleCount)
|
||||
{
|
||||
const depthResized = depthTexture === undefined || canvasTexture.width != depthTexture.width || canvasTexture.height != depthTexture.height;
|
||||
@ -81,6 +85,33 @@ function recreateDepth(canvasTexture, sampleCount)
|
||||
});
|
||||
}
|
||||
|
||||
const tempBufferSize = canvasTexture.width * canvasTexture.height * 4;
|
||||
const tempResized = tempBuffer === undefined || tempBufferSize != tempBuffer.size;
|
||||
if (tempResized) {
|
||||
if (tempBuffer !== undefined) {
|
||||
tempBuffer.destroy();
|
||||
}
|
||||
tempBuffer = device.createBuffer({
|
||||
label: "temp buffer",
|
||||
size: tempBufferSize,
|
||||
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
}
|
||||
|
||||
const copyResized = copyTexture === undefined || canvasTexture.width !== copyTexture.width || canvasTexture.height !== copyTexture.height;
|
||||
if (copyResized) {
|
||||
if (copyTexture !== undefined) {
|
||||
copyTexture.destroy();
|
||||
}
|
||||
|
||||
copyTexture = device.createTexture({
|
||||
format: canvasTexture.format,
|
||||
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
|
||||
size: [canvasTexture.width, canvasTexture.height],
|
||||
sampleCount: 1,
|
||||
});
|
||||
}
|
||||
|
||||
if (sampleCount > 1) {
|
||||
const multisampleResized = multisampleTexture === undefined || canvasTexture.width !== multisampleTexture.width || canvasTexture.height !== multisampleTexture.height;
|
||||
if (multisampleResized || multisampleTexture.sampleCount !== sampleCount) {
|
||||
@ -177,9 +208,18 @@ function handleKeyup(e)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDownloadButton(e)
|
||||
{
|
||||
downloadFramebufferPending = true;
|
||||
console.log("download framebuffer");
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', handleKeydown, false);
|
||||
window.addEventListener('keyup', handleKeyup, false);
|
||||
|
||||
const downloadFramebufferButton = document.getElementById("download-framebuffer");
|
||||
downloadFramebufferButton.addEventListener("click", handleDownloadButton, false);
|
||||
|
||||
function updateView()
|
||||
{
|
||||
const lu = keyState[KEY.W] === true;
|
||||
@ -260,7 +300,30 @@ canvas.addEventListener("mousemove", onMouseMove);
|
||||
var canRender = false;
|
||||
var frameNumber = 0;
|
||||
|
||||
var tempBuffer = undefined;
|
||||
function tgaBlob(texture, mappedRange)
|
||||
{
|
||||
const tgaHeaderSize = 18;
|
||||
const tgaBuffer = new ArrayBuffer(mappedRange.byteLength + tgaHeaderSize);
|
||||
const tgaView = new DataView(tgaBuffer);
|
||||
tgaView.setUint8(0, 0); // idLength
|
||||
tgaView.setUint8(1, 0); // colorMapType
|
||||
tgaView.setUint8(2, 2); // imageTypeCode: 2 uncompressed RGB
|
||||
tgaView.setUint16(3, 0, true); // colorMap origin
|
||||
tgaView.setUint16(5, 0, true); // colorMap length
|
||||
tgaView.setUint8(7, 0); // colorMap depth
|
||||
tgaView.setUint16(8, 0, true); // xOrigin
|
||||
tgaView.setUint16(10, 0, true); // yOrigin
|
||||
tgaView.setUint16(12, texture.width, true); // width
|
||||
tgaView.setUint16(14, texture.height, true); // height
|
||||
tgaView.setUint8(16, 32); // bits per pixel
|
||||
const descriptor = ((8 << 0) | // number of attribute bits
|
||||
(1 << 5) | // origin in upper left
|
||||
(0 << 6)); // non-interleaved
|
||||
tgaView.setUint8(17, descriptor); // descriptor
|
||||
const tgaU8 = new Uint8Array(tgaBuffer);
|
||||
tgaU8.set(new Uint8Array(mappedRange), 18);
|
||||
return new Blob([tgaBuffer]);
|
||||
}
|
||||
|
||||
function render2()
|
||||
{
|
||||
@ -281,16 +344,19 @@ function render2()
|
||||
|
||||
updateView();
|
||||
|
||||
const clearValue = { r: 0.2, g: 0.2, b: 0.4, a: 1.0 };
|
||||
//const clearValue = ;
|
||||
const clearValue = (downloadFramebufferPending) ? { r: 0.0, g: 0.0, b: 0.0, a: 0.0 } : { r: 0.2, g: 0.2, b: 0.4, a: 1.0 };
|
||||
|
||||
const viewTexture = (downloadFramebufferPending) ? copyTexture : canvasTexture;
|
||||
|
||||
const attachment0 = (sampleCount == 1) ? {
|
||||
view: canvasTexture.createView(),
|
||||
view: viewTexture.createView(),
|
||||
loadOp: "clear",
|
||||
clearValue: clearValue,
|
||||
storeOp: "store",
|
||||
} : {
|
||||
view: multisampleTexture.createView(),
|
||||
resolveTarget: canvasTexture.createView(),
|
||||
resolveTarget: viewTexture.createView(),
|
||||
loadOp: "clear",
|
||||
clearValue: clearValue,
|
||||
storeOp: "store",
|
||||
@ -318,44 +384,40 @@ function render2()
|
||||
|
||||
renderPass.end();
|
||||
|
||||
/*
|
||||
encoder.copyTextureToBuffer({
|
||||
texture: multisampleTexture,
|
||||
}, {
|
||||
buffer: tempBuffer,
|
||||
bytesPerRow: canvasTexture.width * 4 * 4,
|
||||
}, {
|
||||
width: canvasTexture.width,
|
||||
height: canvasTexture.height,
|
||||
depthOrArrayLayers: 1,
|
||||
if (downloadFramebufferPending) {
|
||||
encoder.copyTextureToBuffer({
|
||||
texture: copyTexture,
|
||||
}, {
|
||||
buffer: tempBuffer,
|
||||
bytesPerRow: canvasTexture.width * 4,
|
||||
}, {
|
||||
width: copyTexture.width,
|
||||
height: copyTexture.height,
|
||||
depthOrArrayLayers: 1,
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
const commandBuffer = encoder.finish();
|
||||
device.queue.submit([commandBuffer]);
|
||||
|
||||
frameNumber = (frameNumber + 1) % 2;
|
||||
|
||||
/*
|
||||
tempBuffer.mapAsync(GPUMapMode.READ).then(() => {
|
||||
const readBuffer = tempBuffer.getMappedRange(); // arraybuffer
|
||||
//console.log(mousePositionClick);
|
||||
const x = mousePositionClick[0];
|
||||
const y = mousePositionClick[1];
|
||||
const f32ReadBuffer = new Float32Array(readBuffer);
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const a = f32ReadBuffer[((y + i) * canvasTexture.width + x) * 4 + 0];
|
||||
const b = f32ReadBuffer[((y + i) * canvasTexture.width + x) * 4 + 1];
|
||||
const c = f32ReadBuffer[((y + i) * canvasTexture.width + x) * 4 + 2];
|
||||
const d = f32ReadBuffer[((y + i) * canvasTexture.width + x) * 4 + 3];
|
||||
//console.log(a, b, c, d);
|
||||
}
|
||||
|
||||
tempBuffer.unmap();
|
||||
requestAnimationFrame(render2);
|
||||
if (downloadFramebufferPending) {
|
||||
tempBuffer.mapAsync(GPUMapMode.READ).then(() => {
|
||||
const mappedRange = tempBuffer.getMappedRange(); // arraybuffer
|
||||
const blob = tgaBlob(copyTexture, mappedRange);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.setAttribute("href", url);
|
||||
a.setAttribute("download", "framebuffer.tga");
|
||||
a.click();
|
||||
tempBuffer.unmap();
|
||||
requestAnimationFrame(render2);
|
||||
});
|
||||
*/
|
||||
requestAnimationFrame(render2);
|
||||
downloadFramebufferPending = false;
|
||||
} else {
|
||||
requestAnimationFrame(render2);
|
||||
}
|
||||
} else {
|
||||
requestAnimationFrame(render2);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user