@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
99 lines (74 loc) • 3.04 kB
JavaScript
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;