Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ProjectBackup/C#/TSEngine/Core/Graphics/texture.ts
2022-09-04 12:45:01 +02:00

94 lines
3.0 KiB
TypeScript

namespace TSE {
const LEVEL: number = 0;
const BORDER: number = 0;
const TEMP_IMAGE_DATA: Uint8Array = new Uint8Array([255, 255, 255, 255]);
export class Texture implements IMessageHanlder {
private _name: string;
private _handle: WebGLTexture;
private _isLoaded: boolean = false;
private _width: number;
private _height: number;
public constructor(name: string, width: number = 1, height: number = 1) {
this._name = name;
this._width = width;
this._height = height;
this._handle = gl.createTexture();
Message.subscribe(MESSAGE_ASSET_LOADER_ASSET_LOADED + this._name, this);
this.bind();
gl.texImage2D(gl.TEXTURE_2D, LEVEL, gl.RGBA, 1, 1, BORDER, gl.RGBA, gl.UNSIGNED_BYTE, TEMP_IMAGE_DATA);
let asset = AssetManager.getAsset(this._name) as ImageAsset;
if (asset !== undefined) {
this.loadTextureFromAsset(asset);
}
}
public onMessage(message: Message): void {
if (message.code === MESSAGE_ASSET_LOADER_ASSET_LOADED + this._name) {
this.loadTextureFromAsset(message.context as ImageAsset);
}
}
public get name(): string { return this._name; }
public get isLoaded(): boolean { return this._isLoaded; }
public get width(): number { return this._width; }
public get height(): number { return this._height; }
public activateAndBind(textureUnit: number = 0): void {
gl.activeTexture(gl.TEXTURE0 + textureUnit);
this.bind();
}
public bind(): void {
gl.bindTexture(gl.TEXTURE_2D, this._handle);
}
public unbind(): void {
gl.bindTexture(gl.TEXTURE_2D, undefined);
}
public destroy(): void {
gl.deleteTexture(this._handle);
}
private loadTextureFromAsset(asset: ImageAsset): void {
this._width = asset.width;
this._height = asset.height;
this.bind();
gl.texImage2D(gl.TEXTURE_2D, LEVEL, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, asset.data);
if (this.isPowerOf2()) {
gl.generateMipmap(gl.TEXTURE_2D);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
this._isLoaded = true;
}
private isPowerOf2(): boolean {
return (this.isValuePowerOf2(this.width) && this.isValuePowerOf2(this.height));
}
private isValuePowerOf2(value: number): boolean {
return (value & (value - 1)) == 0;
}
}
}