UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

119 lines (89 loc) 2.95 kB
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); }