@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
119 lines (89 loc) • 2.95 kB
JavaScript
import { Sampler2D } from "../../../graphics/texture/sampler/Sampler2D.js";
import { assert } from "../../../../core/assert.js";
import { bitmap2sampler_gl } from "./bitmap2sampler_gl.js";
import { fastArrayEquals } from "../../../../core/collection/array/fastArrayEquals.js";
/**
*
* @type {WeakMap<ImageBitmap, Sampler2D>}
*/
const sampler_cache = new WeakMap();
/**
*
* @param {ImageBitmap} bitmap
* @param {WebGL2RenderingContext} ctx
* @returns {Sampler2D}
*/
function obtainSampler(bitmap, ctx) {
// look for materialized data in cache
const existing_sampler = sampler_cache.get(bitmap);
if (existing_sampler !== undefined) {
// found cached data
return existing_sampler;
}
// not found in cache, lets build it
const width = bitmap.width;
const height = bitmap.height;
const sampler = Sampler2D.uint8(4, width, height);
bitmap2sampler_gl(ctx, sampler, bitmap);
// cache the result
sampler_cache.set(bitmap, sampler);
return sampler;
}
/**
* Ref holding webgl context, being weak-ref, allows context to be removed when not in use
* @type {WeakRef<WebGL2RenderingContext>|null}
*/
let ctx_ref = null;
/**
*
* @param {number} width
* @param {number} height
* @returns {WebGL2RenderingContext}
*/
function obtainCanvasCtx(width, height) {
assert.lessThanOrEqual(width, 0xFFFF, 'maximum supported size');
assert.lessThanOrEqual(height, 0xFFFF, 'maximum supported size');
let gl;
if (ctx_ref === null || (gl = ctx_ref.deref()) === undefined) {
const canvas = document.createElement('canvas');
gl = canvas.getContext("webgl2");
gl.activeTexture(gl.TEXTURE0);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
ctx_ref = new WeakRef(gl);
}
return gl;
}
/**
*
* @param {ImageBitmap} bitmap
* @return {Sampler2D}
*/
export function sampler_from_bitmap(bitmap) {
const ctx = obtainCanvasCtx(bitmap.width, bitmap.height);
return obtainSampler(bitmap, ctx);
}
/**
*
* @param {ImageBitmap} a
* @param {ImageBitmap} b
* @returns {boolean}
*/
export function computeImageBitmapEquality(a, b) {
if (a === b) {
// strict equality check, special case
return true;
}
if (a.width !== b.width || a.height !== b.height) {
// check dimensions
return false;
}
// have to draw both to compare
const ctx = obtainCanvasCtx(a.width, a.height);
const a_s = obtainSampler(a, ctx);
const b_s = obtainSampler(b, ctx);
return fastArrayEquals(a_s.data, b_s.data);
}