Files
2025-07-30 13:39:32 +08:00

62 lines
2.4 KiB
TypeScript

import Size from './utils/Size';
import assert from './utils/assert';
import Program from './Program';
export default class Texture {
public readonly texture: WebGLTexture | null;
public readonly format: GLenum;
private textureIDs: number[];
static create (gl: WebGLRenderingContext, format: number): Texture {
return new Texture(gl, undefined, format);
}
constructor(readonly gl: WebGLRenderingContext, readonly size?: Size, format?: GLenum) {
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
this.format = format ? format : gl.LUMINANCE;
if (size) {
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, size.w, size.h, 0, this.format, gl.UNSIGNED_BYTE, null);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
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);
this.textureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2];
}
public fill(textureData: Uint8Array, useTexSubImage2D?: boolean, w?: number, h?: number): void {
if (typeof w === 'undefined' || typeof h === 'undefined') {
if (!this.size) {
return;
}
w = this.size.w;
h = this.size.h;
}
const gl = this.gl;
assert(textureData.length >= w * h,
'Texture size mismatch, data:' + textureData.length + ', texture: ' + w * h);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
if (useTexSubImage2D) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, w, h, this.format, gl.UNSIGNED_BYTE, textureData);
} else {
// texImage2D seems to be faster, thus keeping it as the default
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, w, h, 0, this.format, gl.UNSIGNED_BYTE, textureData);
}
}
public image2dBuffer (buffer: Uint8Array, width: number, height: number) {
this.fill(buffer, false, width, height);
}
public bind(n: number, program: Program, name: string): void {
const gl = this.gl;
if (!program.program) {
return;
}
gl.activeTexture(this.textureIDs[n]);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.uniform1i(gl.getUniformLocation(program.program, name), n);
}
}