Skip to content

Commit c8e4859

Browse files
committed
Fix screenshot feature in shader-recorder.html
1 parent ee2762d commit c8e4859

1 file changed

Lines changed: 51 additions & 12 deletions

File tree

‎shader-recorder.html‎

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,9 @@ <h3>Shader Controls</h3>
310310

311311
// Initialize WebGL
312312
const canvas = document.getElementById("canvas")
313-
const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl")
313+
const gl =
314+
canvas.getContext("webgl", { preserveDrawingBuffer: true }) ||
315+
canvas.getContext("experimental-webgl", { preserveDrawingBuffer: true })
314316

315317
if (!gl) {
316318
alert("WebGL not supported")
@@ -409,6 +411,8 @@ <h3>Shader Controls</h3>
409411

410412
// Animation loop
411413
let startTime = Date.now()
414+
let animationId
415+
412416
function render() {
413417
const currentTime = (Date.now() - startTime) / 1000
414418

@@ -420,7 +424,7 @@ <h3>Shader Controls</h3>
420424

421425
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)
422426

423-
requestAnimationFrame(render)
427+
animationId = requestAnimationFrame(render)
424428
}
425429

426430
render()
@@ -504,16 +508,51 @@ <h3>Shader Controls</h3>
504508

505509
// Screenshot functionality
506510
screenshotBtn.addEventListener("click", () => {
507-
canvas.toBlob((blob) => {
508-
const url = URL.createObjectURL(blob)
509-
const a = document.createElement("a")
510-
a.href = url
511-
a.download = `shader_screenshot_${new Date().getTime()}.png`
512-
a.click()
513-
URL.revokeObjectURL(url)
514-
statusDiv.textContent = "Screenshot saved!"
515-
setTimeout(() => (statusDiv.textContent = ""), 3000)
516-
}, "image/png")
511+
// Force a render before taking screenshot
512+
render()
513+
514+
// Use a small delay to ensure the frame is fully rendered
515+
setTimeout(() => {
516+
// Alternative method: read pixels directly
517+
const width = canvas.width
518+
const height = canvas.height
519+
const pixels = new Uint8Array(width * height * 4)
520+
521+
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
522+
523+
// Create a new canvas to draw the pixels (flipped vertically)
524+
const tempCanvas = document.createElement("canvas")
525+
tempCanvas.width = width
526+
tempCanvas.height = height
527+
const tempCtx = tempCanvas.getContext("2d")
528+
const imageData = tempCtx.createImageData(width, height)
529+
530+
// Flip vertically while copying pixels
531+
for (let y = 0; y < height; y++) {
532+
for (let x = 0; x < width; x++) {
533+
const srcIdx = ((height - y - 1) * width + x) * 4
534+
const dstIdx = (y * width + x) * 4
535+
imageData.data[dstIdx] = pixels[srcIdx]
536+
imageData.data[dstIdx + 1] = pixels[srcIdx + 1]
537+
imageData.data[dstIdx + 2] = pixels[srcIdx + 2]
538+
imageData.data[dstIdx + 3] = pixels[srcIdx + 3]
539+
}
540+
}
541+
542+
tempCtx.putImageData(imageData, 0, 0)
543+
544+
// Convert to blob and download
545+
tempCanvas.toBlob((blob) => {
546+
const url = URL.createObjectURL(blob)
547+
const a = document.createElement("a")
548+
a.href = url
549+
a.download = `shader_screenshot_${new Date().getTime()}.png`
550+
a.click()
551+
URL.revokeObjectURL(url)
552+
statusDiv.textContent = "Screenshot saved!"
553+
setTimeout(() => (statusDiv.textContent = ""), 3000)
554+
}, "image/png")
555+
}, 100)
517556
})
518557
</script>
519558
</body>

0 commit comments

Comments
 (0)