@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
199 lines • 14.8 kB
JavaScript
import { TgdEvent } from "./../event/index.js";
import { isWebglImage } from "./../types/index.js";
import { webglTextureParametersSet, } from "./../webgl/index.js";
export class TgdTexture2D {
constructor(context, storage) {
this.eventChange = new TgdEvent();
this._texture = null;
this._width = 0;
this._height = 0;
const { gl } = context;
this.gl = gl;
this.name = `Texture2D/${TgdTexture2D.counter++}`;
const texture = gl.createTexture();
if (!texture)
throw new Error("Unable to create a WebGLTexture!");
this._texture = texture;
this.setParams({
magFilter: "LINEAR",
minFilter: "LINEAR",
wrapS: "REPEAT",
wrapT: "REPEAT",
wrapR: "REPEAT",
});
this.storage = Object.assign({ width: 1, height: 1, internalFormat: "RGBA8", levels: 1, flipY: false }, storage);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.storage.flipY);
if (typeof (storage === null || storage === void 0 ? void 0 : storage.width) === "number" &&
typeof (storage === null || storage === void 0 ? void 0 : storage.height) === "number") {
this.resize(storage === null || storage === void 0 ? void 0 : storage.width, storage === null || storage === void 0 ? void 0 : storage.height);
}
}
delete() {
this.gl.deleteTexture(this.glTexture);
}
get width() {
return this._width;
}
get height() {
return this._height;
}
resize(width, height) {
if (width === this.width && height === this.height)
return;
const { gl, storage } = this;
this._width = storage.width = width;
this._height = 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.texStorage2D(gl.TEXTURE_2D, levels, gl[internalFormat], width, height);
}
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);
}
loadBitmap(bmp, options = {}) {
if (!bmp)
return this;
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.texImage2D(gl.TEXTURE_2D, level, gl[storage.internalFormat], gl[figureOutCompatibleFormat(storage.internalFormat)], gl.UNSIGNED_BYTE, bmp);
this.eventChange.dispatch(this);
return this;
}
loadData(data, options) {
const { level = 0, width, height,
// internalFormat,
// format,
// offset = 0,
} = options;
const { gl } = this;
this.bind();
gl.texImage2D(gl.TEXTURE_2D, level, gl.RGB, //gl[internalFormat],
width, height, 0, gl.RGB, // gl[format],
gl.UNSIGNED_BYTE, data
// offset
);
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 hold 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);
return this;
}
setParams(parameters) {
this.bind();
webglTextureParametersSet(this.gl, parameters);
return this;
}
set textureBaseLevel(value) {
const { gl } = this;
this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, value);
}
get textureBaseLevel() {
const { gl } = this;
this.bind();
return gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL);
}
set textureMaxLevel(value) {
const { gl } = this;
this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, value);
}
get textureMaxLevel() {
const { gl } = this;
this.bind();
return gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL);
}
getParameter(parameter) {
const { gl, glTexture } = this;
gl.bindTexture(gl.TEXTURE_2D, glTexture);
const value = gl.getTexParameter(gl.TEXTURE_2D, gl[parameter]);
return 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"!`);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dHVyZTJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RleHR1cmUvdGV4dHVyZTJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFckMsT0FBTyxFQUFFLFlBQVksRUFBaUMsTUFBTSxZQUFZLENBQUE7QUFDeEUsT0FBTyxFQUdILHlCQUF5QixHQUM1QixNQUFNLFlBQVksQ0FBQTtBQTJDbkIsTUFBTSxPQUFPLFlBQVk7SUFZckIsWUFDSSxPQUF1QyxFQUN2QyxPQUFzQztRQVgxQixnQkFBVyxHQUFHLElBQUksUUFBUSxFQUFnQixDQUFBO1FBRXpDLGFBQVEsR0FBd0IsSUFBSSxDQUFBO1FBQzdDLFdBQU0sR0FBRyxDQUFDLENBQUE7UUFDVixZQUFPLEdBQUcsQ0FBQyxDQUFBO1FBU2YsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQTtRQUN0QixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQTtRQUNaLElBQUksQ0FBQyxJQUFJLEdBQUcsYUFBYSxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQTtRQUNqRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUE7UUFDbEMsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7UUFFakUsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUE7UUFDdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNYLFNBQVMsRUFBRSxRQUFRO1lBQ25CLFNBQVMsRUFBRSxRQUFRO1lBQ25CLEtBQUssRUFBRSxRQUFRO1lBQ2YsS0FBSyxFQUFFLFFBQVE7WUFDZixLQUFLLEVBQUUsUUFBUTtTQUNsQixDQUFDLENBQUE7UUFDRixJQUFJLENBQUMsT0FBTyxtQkFDUixLQUFLLEVBQUUsQ0FBQyxFQUNSLE1BQU0sRUFBRSxDQUFDLEVB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