UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

296 lines 23.2 kB
import { TgdEvent } from "./../event/index.js"; import { tgdLoadImage } from "./../loader/image.js"; import { isWebglImage } from "./../types/index.js"; import { webglLookup } from "./../utils/index.js"; import { webglTextureParametersSet, } from "./../webgl/index.js"; export class TgdTexture2D { constructor(context, storage) { this.context = context; this.eventChange = new TgdEvent(); this._texture = null; this._width = -1; this._height = -1; this.params = { magFilter: "LINEAR", minFilter: "LINEAR", wrapS: "REPEAT", wrapT: "REPEAT", wrapR: "REPEAT", }; const { gl } = context; this.gl = gl; this.name = `Texture2D/${TgdTexture2D.counter++}`; this.storage = Object.assign({ width: 0, height: 0, internalFormat: "RGBA8", levels: 1, flipY: false, premultipliedAlpha: false }, storage); const width = storage === null || storage === void 0 ? void 0 : storage.width; const height = storage === null || storage === void 0 ? void 0 : storage.height; if (typeof width == "number" && typeof height === "number") { this.resize(width, height); } else { this.createTexture(); } } delete() { if (this._texture) this.gl.deleteTexture(this._texture); this._texture = null; } get width() { return this._width; } get height() { return this._height; } createTexture() { this.delete(); const { gl } = this; const texture = gl.createTexture(); if (!texture) throw new Error("Unable to create a WebGLTexture!"); this._texture = texture; this.bind(); this.setParams(this.params); } resize(width, height) { if (width === this.width && height === this.height) return; const { gl, storage } = this; this.createTexture(); this._width = width; this._height = height; storage.width = width; storage.height = height; const { internalFormat, levels } = this.storage; if (internalFormat.startsWith("COMPRESSED_")) { // We need to load an extension for that. const extension = gl.getExtension("WEBGL_compressed_texture_etc"); if (!extension) throw new Error('Your browser does not support extension "WEBGL_compressed_texture_etc" on this device!'); } this.bind(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.storage.flipY); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.storage.premultipliedAlpha); gl.texStorage2D(gl.TEXTURE_2D, levels, gl[internalFormat], width, height); this.checkError(`resize(${width}, ${height}) gl.texStorage2D( gl.TEXTURE_2D, ${levels}, gl.${internalFormat}, ${width}, ${height} )`); this.unbind(); } checkError(caption) { const { gl } = this; const error = gl.getError(); if (error !== gl.NO_ERROR) { console.error(`[TgdTexture2D::${this.name}] Error in ${caption}:`, webglLookup(error), this); } } get glTexture() { if (this._texture) return this._texture; throw new Error(`Texture "${this.name}" has been deleted!`); } bind() { this.gl.bindTexture(this.gl.TEXTURE_2D, this.glTexture); } unbind() { this.gl.bindTexture(this.gl.TEXTURE_2D, null); } loadBitmap(bmp, options = {}) { var _a, _b, _c; if (!bmp) return this; if (typeof bmp === "string") { return this.loadBitmap(tgdLoadImage(bmp), options); } if (!isWebglImage(bmp)) { bmp.then(data => this.loadBitmap(data)).catch(error => console.error("Unable to load texture BMP:", error)); return this; } const { storage, gl } = this; const { level = 0 } = options; this._width = bmp.width; this._height = bmp.height; this.bind(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.storage.flipY); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.storage.premultipliedAlpha); gl.texImage2D(gl.TEXTURE_2D, level, gl[storage.internalFormat], gl[figureOutCompatibleFormat(storage.internalFormat)], gl.UNSIGNED_BYTE, bmp); this.checkError(`loadBitmap(${JSON.stringify({ width: bmp.width, height: bmp.height, })})\ngl.texImage2D(gl.TEXTURE_2D, ${level}, gl.${storage.internalFormat}, gl.${figureOutCompatibleFormat(storage.internalFormat)}, gl.UNSIGNED_BYTE, bmp)`); if (options.generateMipmap) { this.generateMipmap(); this.checkError(`loadBitmap(${JSON.stringify({ width: bmp.width, height: bmp.height, })})\ngl.texImage2D(gl.TEXTURE_2D, ${level}, gl.${storage.internalFormat}, gl.${figureOutCompatibleFormat(storage.internalFormat)}, gl.UNSIGNED_BYTE, bmp)\ngenerateMipmap()`); } this.unbind(); (_b = (_a = this.context).paint) === null || _b === void 0 ? void 0 : _b.call(_a); (_c = options.onLoad) === null || _c === void 0 ? void 0 : _c.call(options); this.eventChange.dispatch(this); return this; } loadData(data, options) { const { level = 0, width, height, internalFormat = "RGB", format = "RGB", // offset = 0, } = options; const { gl } = this; this.bind(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.storage.flipY); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.storage.premultipliedAlpha); gl.texImage2D(gl.TEXTURE_2D, level, gl[internalFormat], width, height, 0, gl[format], gl.UNSIGNED_BYTE, data // offset ); this.checkError(`loadData(${printArray(data)}, ${JSON.stringify(options)})`); this.unbind(); this.eventChange.dispatch(this); return this; } /** * * @param unit Unit to link the texture to * @param program The program that owns the uniform to update * @param uniformName The uniform that holds the texture */ activate(unit, program, uniformName) { const { gl } = this; gl.activeTexture(gl.TEXTURE0 + unit); this.bind(); if (program && uniformName) { program.uniform1i(uniformName, unit); } return this; } generateMipmap() { const { gl } = this; this.bind(); gl.generateMipmap(gl.TEXTURE_2D); this.unbind(); return this; } setParams(parameters) { this.bind(); webglTextureParametersSet(this.gl, parameters); this.params = Object.assign(Object.assign({}, this.params), parameters); this.unbind(); return this; } set textureBaseLevel(value) { const { gl } = this; this.bind(); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, value); this.unbind(); } get textureBaseLevel() { const { gl } = this; this.bind(); const value = gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL); this.unbind(); return value; } set textureMaxLevel(value) { const { gl } = this; this.bind(); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, value); this.unbind(); } get textureMaxLevel() { const { gl } = this; this.bind(); const value = gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL); this.unbind(); return value; } getParameter(parameter) { const { gl } = this; this.bind(); const value = gl.getTexParameter(gl.TEXTURE_2D, gl[parameter]); this.unbind(); return value; } debug(title) { var _a; console.log((_a = title !== null && title !== void 0 ? title : this.name) !== null && _a !== void 0 ? _a : "TgdTexture2D", " ", this.width, "×", this.height); const parameters = [ "TEXTURE_MAG_FILTER", "TEXTURE_MIN_FILTER", "TEXTURE_WRAP_R", "TEXTURE_WRAP_S", "TEXTURE_WRAP_T", "TEXTURE_MAX_LEVEL", "TEXTURE_MAX_LOD", "TEXTURE_MIN_LOD", "TEXTURE_BASE_LEVEL", "TEXTURE_COMPARE_FUNC", "TEXTURE_COMPARE_MODE", "TEXTURE_IMMUTABLE_FORMAT", "TEXTURE_IMMUTABLE_LEVELS", ]; for (const name of parameters) { const value = this.getParameter(name); console.log(">", name, "=", value, typeof value === "number" ? `(${webglLookup(value)})` : " "); } } } TgdTexture2D.counter = 0; const COMPATIBLE_FORMATS = [ [ "RGB", new Set([ "RGB", "RGB8", "RGB565", "SRGB8", "RGB8_SNORM", "RGB565", "R11F_G11F_B10F", "RGB9_E5", "RGB16F", "R11F_G11F_B10F", "RGB9_E5", "RGB32F", "RGB16F", "R11F_G11F_B10F", "RGB9_E5", ]), ], [ "RGBA", new Set([ "RGBA", "RGBA8", "RGB5_A1", "RGBA4", "SRGB8_ALPHA8", "RGBA8_SNORM", "RGBA4", "RGB5_A1", "RGB10_A2", "RGB5_A1", "RGBA16F", "RGBA32F", "RGBA16F", ]), ], ["RG", new Set(["RG8"])], ["RED", new Set(["R8"])], ]; function figureOutCompatibleFormat(internalFormat) { for (const [format, internalFormats] of COMPATIBLE_FORMATS) { if (internalFormats.has(internalFormat)) return format; } throw new Error(`There is no compatible format for internalFormat "${internalFormat}" and type "UNSIGNED_BYTE"!`); } function printArray(data) { if (data.length > 10) { return `[${data.slice(0, 10).join(", ")}, ...] (${data.length} elements)`; } return JSON.stringify(data); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dHVyZTJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RleHR1cmUvdGV4dHVyZTJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDckMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRWhELE9BQU8sRUFBRSxZQUFZLEVBQWlDLE1BQU0sWUFBWSxDQUFBO0FBQ3hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDeEMsT0FBTyxFQUdILHlCQUF5QixHQUM1QixNQUFNLFlBQVksQ0FBQTtBQWdEbkIsTUFBTSxPQUFPLFlBQVk7SUFtQnJCLFlBQ3FCLE9BR2hCLEVBQ0QsT0FBc0M7UUFKckIsWUFBTyxHQUFQLE9BQU8sQ0FHdkI7UUFwQlcsZ0JBQVcsR0FBRyxJQUFJLFFBQVEsRUFBZ0IsQ0FBQTtRQUVsRCxhQUFRLEdBQXdCLElBQUksQ0FBQTtRQUNwQyxXQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDWCxZQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFFWixXQUFNLEdBQTJCO1lBQ3JDLFNBQVMsRUFBRSxRQUFRO1lBQ25CLFNBQVMsRUFBRSxRQUFRO1lBQ25CLEtBQUssRUFBRSxRQUFRO1lBQ2YsS0FBSyxFQUFFLFFBQVE7WUFDZixLQUFLLEVBQUUsUUFBUTtTQUNsQixDQUFBO1FBV0csTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQTtRQUN0QixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQTtRQUNaLElBQUksQ0FBQyxJQUFJLEdBQUcsYUFBYSxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQTtRQUNqRCxJQUFJLENBQUMsT0FBTyxtQkFDUixLQUFLLEVBQUUsQ0FBQyxFQUNSLE1BQU0sRUFBRSxDQUFDLEVBQ1QsY0FBYyxFQUFFLE9BQU8sRUFDdkIsTUFBTSxFQUFFLENB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