UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

99 lines (74 loc) 3.04 kB
import { assert } from "../../../../core/assert.js"; import { Sampler2D } from "./Sampler2D.js"; import { sampler2d_write_to_canvas_raw } from "./sampler2d_write_to_canvas_raw.js"; /** * * @param {Sampler2D} sampler * @param {Number} [scale] * @param {Number} [offset] * @param {HTMLCanvasElement} [canvas] if no canvas is supplied, a new one will be created * @returns {HTMLCanvasElement} canvas */ export function sampler2d_to_html_canvas( sampler, scale = 255, offset = 0, canvas = document.createElement("canvas") ) { assert.defined(sampler, 'sampler'); assert.isNumber(scale, 'scale'); assert.notNaN(scale, 'scale'); assert.isNumber(offset, 'offset'); assert.notNaN(offset, 'offset'); assert.defined(canvas, 'canvas'); const source_data = sampler.data; const converted_sampler = Sampler2D.uint8clamped(4, sampler.width, sampler.height); const width = sampler.width; const height = sampler.height; const array = converted_sampler.data; // const source_channel_count = sampler.itemSize; if (source_channel_count === 4 && offset === 0 && scale === 1) { // shortcut or straight forward case array.set(source_data); } else { if (source_channel_count < 4) { //sampler lacks alpha channel, set alpha values to fully opaque const n = width * height * 4; for (let i = 3; i < n; i += 4) { array[i] = 255; } } if (source_channel_count === 1) { let index = 0; for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const texel_address = (y * width + x); const source_value = source_data[texel_address]; const transformed_value = Math.round((source_value + offset) * scale); // write identical RGB for grayscale image array[index + 0] = transformed_value; array[index + 1] = transformed_value; array[index + 2] = transformed_value; index += 4; } } } else { let index = 0; for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const texel_address = (y * width + x) * source_channel_count; for (let i = 0; i < source_channel_count; i++) { const source_value = source_data[texel_address + i]; const transformed_value = Math.round((source_value + offset) * scale); array[index + i] = transformed_value; } index += 4; } } } } sampler2d_write_to_canvas_raw(converted_sampler, canvas); return canvas; } export default sampler2d_to_html_canvas;