@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
106 lines (82 loc) • 3.46 kB
JavaScript
import { sampler2d_channel_linear_transform } from "./sampler2d_channel_linear_transform.js";
function compute_gradient_and_intercept_uint8(ctor) {
let gradient = 1;
let intercept = 0;
switch (ctor) {
case Uint16Array:
gradient = 0.0038910505836575876;
break;
case Uint32Array:
gradient = 5.937181414556033e-8;
break;
case Int8Array:
gradient = 1;
intercept = 127;
break
case Int16Array:
gradient = 0.0038910505836575876;
intercept = 127;
break;
case Int32Array:
gradient = 5.937181414556033e-8;
intercept = 127;
break
case Float32Array:
case Float64Array:
gradient = 255;
break;
default:
// do nothing;
}
return {
gradient, intercept
}
}
/**
* Many applications work with 8bit RGBA images, this utility function converts a given input to that format
* @param {Sampler2D} input
* @param {Sampler2D} output
*/
export function sampler2d_to_uint8_RGBA(output, input) {
if (
input.width !== output.width
|| input.height !== output.height
) {
throw new Error('Dimensions of source and destination are incompatible');
}
if (output.itemSize !== 4) {
throw new Error(`Destination must have 4 channels exactly, instead got '${output.itemSize}'`);
}
const { gradient, intercept } = compute_gradient_and_intercept_uint8(input.data.constructor);
const source_item_size = input.itemSize;
if (intercept === 0 && gradient === 1 && source_item_size === 4) {
// already in the right format, use shortcut
output.data.set(input.data);
return;
}
if (source_item_size === 1) {
// grayscale
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 1, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 2, 0, gradient, intercept);
output.channelFill(3, 255);
} else if (source_item_size === 2) {
// grayscale with alpha
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 1, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 2, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 3, 1, gradient, intercept);
} else if (source_item_size === 3) {
// RGB
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 1, 1, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 2, 2, gradient, intercept);
output.channelFill(3, 255);
} else if (source_item_size === 4) {
// RGBA
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 1, 1, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 2, 2, gradient, intercept);
sampler2d_channel_linear_transform(output, input, 3, 3, gradient, intercept);
}
}