Skip to content

Commit

Permalink
Automatically update textures when necessary.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lakuna committed Nov 12, 2022
1 parent 63733e9 commit 718d66f
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lakuna/umbra.js",
"version": "10.1.6",
"version": "10.2.0",
"description": "A lightweight visual application framework for WebGL.",
"keywords": [
"front-end",
Expand Down
1 change: 1 addition & 0 deletions src/types/MeasuredIterable.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/** An iterable with known size. */
export default interface MeasuredIterable<T> extends Iterable<T>, ArrayLike<T> { }
100 changes: 86 additions & 14 deletions src/webgl/Texture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export default abstract class Texture {
const texture: WebGLTexture | null = gl.createTexture();
if (!texture) { throw new Error("Failed to create a texture."); }
this.texture = texture;

this.needsUpdate = true;
}

/** The rendering context of this texture. */
Expand All @@ -41,13 +43,27 @@ export default abstract class Texture {
}

/** Updates the texels of this texture. */
public abstract update(): void;
public update(): void {
this.updateInternal();
this.needsUpdate = false;
}

/** Updates the texels of this texture. */
protected abstract updateInternal(): void;

/** Generates a mipmap for this texture. */
public generateMipmap(): void {
this.bind();
this.gl.generateMipmap(this.target);
}

/** Whether this texture needs to be updated. */
protected needsUpdate: boolean;

/** Updates this texture if necessary. */
public updateIfNeeded(): void {
if (this.needsUpdate) { this.update(); }
}
}

/** Pixel sources for 2D textures. */
Expand Down Expand Up @@ -123,13 +139,13 @@ export class Texture2D extends Texture {
wrapTFunction
}: Texture2DParameters) {
super(gl, target);
this.lod = lod;
this.internalFormat = internalFormat;
this.width = width;
this.height = height;
this.format = format;
this.type = type;
this.pixels = pixels;
this.lodPrivate = lod;
this.internalFormatPrivate = internalFormat;
this.widthPrivate = width;
this.heightPrivate = height;
if (format) { this.format = format; }
if (type) { this.type = type; }
this.pixelsPrivate = pixels;
if (magFilter) { this.magFilter = magFilter; }
if (minFilter) { this.minFilter = minFilter; }
if (wrapSFunction) { this.wrapSFunction = wrapSFunction; }
Expand All @@ -138,16 +154,56 @@ export class Texture2D extends Texture {
}

/** The level of detail of this texture. */
public lod: number;
private lodPrivate: number;

/** The level of detail of this texture. */
public get lod(): number {
return this.lodPrivate;
}

public set lod(value: number) {
this.lodPrivate = value;
this.needsUpdate = true;
}

/** The format of the color components in this texture. */
public internalFormat: TextureFormat;
private internalFormatPrivate: TextureFormat;

/** The format of the color components in this texture. */
public get internalFormat(): TextureFormat {
return this.internalFormatPrivate;
}

public set internalFormat(value: TextureFormat) {
this.internalFormatPrivate = value;
this.needsUpdate = true;
}

/** The width of this texture. */
public width: number | undefined;
private widthPrivate: number | undefined;

/** The width of this texture. */
public get width(): number | undefined {
return this.widthPrivate;
}

public set width(value: number | undefined) {
this.widthPrivate = value;
this.needsUpdate = true;
}

/** The height of this texture. */
private heightPrivate: number | undefined;

/** The height of this texture. */
public height: number | undefined;
public get height(): number | undefined {
return this.heightPrivate;
}

public set height(value: number | undefined) {
this.heightPrivate = value;
this.needsUpdate = true;
}

/** The format of the texel data. */
private formatPrivate: TextureFormat | undefined;
Expand Down Expand Up @@ -204,6 +260,7 @@ export class Texture2D extends Texture {

public set format(value: TextureFormat | undefined) {
this.formatPrivate = value;
this.needsUpdate = true;
}

/** The data type of the components in this texture. */
Expand Down Expand Up @@ -253,10 +310,21 @@ export class Texture2D extends Texture {

public set type(value: TextureDataType | undefined) {
this.typePrivate = value;
this.needsUpdate = true;
}

/** The pixel source for this texture. */
public pixels: Texture2DPixelSource;
private pixelsPrivate: Texture2DPixelSource;

/** The pixel source for this texture. */
public get pixels(): Texture2DPixelSource {
return this.pixelsPrivate;
}

public set pixels(value: Texture2DPixelSource) {
this.pixelsPrivate = value;
this.needsUpdate = true;
}

/** The magnification filter for this texture. */
public get magFilter(): TextureFilter {
Expand All @@ -267,6 +335,7 @@ export class Texture2D extends Texture {
public set magFilter(value: TextureFilter) {
this.bind();
this.gl.texParameteri(this.target, TEXTURE_MAG_FILTER, value);
this.needsUpdate = true;
}

/** The minification filter for this texture. */
Expand All @@ -278,6 +347,7 @@ export class Texture2D extends Texture {
public set minFilter(value: TextureFilter) {
this.bind();
this.gl.texParameteri(this.target, TEXTURE_MIN_FILTER, value);
this.needsUpdate = true;
}

/** The wrapping function of this texture in the S direction. */
Expand All @@ -289,6 +359,7 @@ export class Texture2D extends Texture {
public set wrapSFunction(value: TextureWrapFunction) {
this.bind();
this.gl.texParameteri(this.target, TEXTURE_WRAP_S, value);
this.needsUpdate = true;
}

/** The wrapping function of this texture in the T direction. */
Expand All @@ -300,10 +371,11 @@ export class Texture2D extends Texture {
public set wrapTFunction(value: TextureWrapFunction) {
this.bind();
this.gl.texParameteri(this.target, TEXTURE_WRAP_T, value);
this.needsUpdate = true;
}

/** Updates the texels of this texture. */
public update(): void {
protected updateInternal(): void {
this.bind();

if (this.width && this.height) {
Expand Down
4 changes: 3 additions & 1 deletion src/webgl/Uniform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,16 @@ export class SamplerUniform extends SingleValuedUniform {
public arraySetter(value: MeasuredIterable<Texture>): void {
const textureUnits: Int32Array = new Int32Array(value.length);
for (let i = 0; i < value.length; i++) { textureUnits[i] = (this.textureUnit) + i; }
this.gl.uniform1iv(this.location, textureUnits, this.sourceOffset, this.sourceLength);
for (let i = 0; i < value.length; i++) {
(value[i] as Texture).updateIfNeeded();
(value[i] as Texture).assign(textureUnits[i] as number);
}
this.gl.uniform1iv(this.location, textureUnits, this.sourceOffset, this.sourceLength);
}

/** The setter method for this uniform. */
public setter(value: Texture): void {
value.updateIfNeeded();
value.assign(this.textureUnit);
this.gl.uniform1i(this.location, this.textureUnit);
}
Expand Down

0 comments on commit 718d66f

Please sign in to comment.