Archived
Private
Public Access
1
0

Initial commit

This commit is contained in:
2022-09-04 12:45:01 +02:00
commit f4a01d6a69
11601 changed files with 4206660 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
namespace TSE {
export class Color {
public static get white(): Color { return new Color(255, 255, 255, 255); }
public static get black(): Color { return new Color(0, 0, 0, 255) };
public static get red(): Color { return new Color(255, 0, 0, 255) };
public static get green(): Color { return new Color(0, 255, 0, 255) };
public static get blue(): Color { return new Color(0, 0, 255, 255) };
private _red;
private _green;
private _blue;
private _alpha;
public constructor(red: number = 255, green: number = 255, blue: number = 255, alpha: number = 255) {
this._red = red;
this._green = green;
this._blue = blue;
this._alpha = alpha;
}
public get red(): number { return this._red; }
public get green(): number { return this._green; }
public get blue(): number { return this._blue; }
public get alpha(): number { return this._alpha; }
public get redFload(): number { return this._red / 255; }
public get greenFload(): number { return this._green / 255; }
public get blueFload(): number { return this._blue / 255; }
public get alphaFload(): number { return this._alpha / 255; }
public toArray(): number[] { return [this._red, this._green, this._blue, this._alpha] }
public toFloatArray(): number[] { return [this.redFload, this.greenFload, this.blueFload, this.alphaFload]; }
public toFloat32Array(): Float32Array { return new Float32Array(this.toFloatArray()); }
}
}

View File

@@ -0,0 +1,41 @@
namespace TSE {
export class Material {
private _name: string;
private _diffuseTextureName: string;
private _diffuseTexture: Texture;
private _tint: Color;
public constructor(name: string, diffuseTextureName: string, tint: Color = Color.white) {
this._name = name;
this._diffuseTextureName = diffuseTextureName;
this._tint = tint;
if (this._diffuseTextureName !== undefined)
this._diffuseTexture = TextureManager.getTexture(this._diffuseTextureName);
}
public get name(): string { return this._name; }
public get diffuseTextureName(): string { return this._diffuseTextureName; }
public get diffuseTexture(): Texture { return this._diffuseTexture; }
public get tint(): Color { return this._tint; }
public set diffuseTextureName(value: string) {
if (this._diffuseTexture !== undefined)
TextureManager.releaseTexture(this._diffuseTextureName);
if (value === undefined) return;
this.diffuseTextureName = value;
this._diffuseTexture = TextureManager.getTexture(this._diffuseTextureName);
}
public destroy(): void {
TextureManager.releaseTexture(this._diffuseTextureName);
this._diffuseTexture = undefined;
}
}
}

View File

@@ -0,0 +1,45 @@
namespace TSE {
class MaterialReferenceNode {
public material: Material;
public referenceCount: number = 1;
public constructor(material: Material) {
this.material = material;
}
}
export class MaterialManager {
private static _materials: { [name: string]: MaterialReferenceNode } = {};
private constructor() { }
public static registerMaterial(material: Material): void {
if (MaterialManager._materials[material.name] === undefined)
MaterialManager._materials[material.name] = new MaterialReferenceNode(material);
}
public static getMaterial(materialName: string): Material {
if (MaterialManager._materials[materialName] === undefined) return undefined;
MaterialManager._materials[materialName].referenceCount++;
return MaterialManager._materials[materialName].material;
}
public static releaseMaterial(materialName: string): void {
if (MaterialManager._materials[materialName] === undefined) console.warn("Cannot release an undefined Material!");
else {
MaterialManager._materials[materialName].referenceCount--;
if (MaterialManager._materials[materialName].referenceCount < 1) {
MaterialManager._materials[materialName].material.destroy();
delete MaterialManager._materials[materialName];
}
}
}
}
}

View File

@@ -0,0 +1,151 @@
namespace TSE {
export class Sprite {
protected _buffer: GLBuffer;
protected _width: number;
protected _height: number;
protected _name: string;
protected _material: Material;
protected _vertices: Vertex[] = [];
public constructor(name: string, materialName: string, width: number = 100, height: number = 100) {
this._name = name;
this._width = width;
this._height = height;
this._material = MaterialManager.getMaterial(materialName);
}
public load(): void {
this._buffer = new GLBuffer();
this._buffer.addAttributeLocation(new AttributeInfo(0, 3)); //Position
this._buffer.addAttributeLocation(new AttributeInfo(1, 2)); //UVs
this._vertices = [
new Vertex(0, 0, 0, 0, 0),
new Vertex(0, this._height, 0, 0, 1.0),
new Vertex(this._width, this._height, 0, 1.0, 1.0),
new Vertex(this._width, this._height, 0, 1.0, 1.0),
new Vertex(this._width, 0, 0, 1.0, 0),
new Vertex(0, 0, 0, 0, 0)
];
this._buffer.pushBackData(Vertex.vertexArray(this._vertices));
this._buffer.upload();
this._buffer.unbind();
}
public destroy(): void {
this._buffer.destroy();
MaterialManager.releaseMaterial(this._material.name);
delete this._material;
}
public update(time: number): void {
}
public draw(shader: Shader, model: Matrix4x4): void {
let modelLocation = shader.getUniformLocation("u_model");
gl.uniformMatrix4fv(modelLocation, false, model.toFloat32Array());
let colorLocation = shader.getUniformLocation("u_tint");
gl.uniform4fv(colorLocation, this._material.tint.toFloat32Array());
if (this._material.diffuseTexture !== undefined) {
this._material.diffuseTexture.activateAndBind(0);
let diffuseLocation = shader.getUniformLocation("u_diffuse");
gl.uniform1i(diffuseLocation, 0);
}
this._buffer.bind();
this._buffer.draw();
}
public get name(): string { return this._name; }
}
export class AnimatedSprite extends Sprite {
private _frameHeight: number;
private _frameWidth: number;
private _frameCount: number;
private _frameSequence: number[];
private _currentFrame: number = 0;
private currentTime: number = 0;
private _frameTime: number = 300;
private _frameUVs: Vector2[][];
private _loaded: boolean = false;
public constructor(name: string, materialName: string, frameWidth: number = 10, frameHeight: number = 10, frameCount: number = 1, frameSequence: number[] = []) {
super(name, materialName, frameWidth, frameHeight);
this._frameWidth = frameWidth;
this._frameHeight = frameHeight;
this._frameCount = frameCount;
this._frameSequence = frameSequence;
}
public load() {
super.load();
this.calculateUVs();
}
private calculateUVs(): void {
setTimeout(() => {
this._frameUVs = [];
let totalWidth: number = 0;
let totalHeight: number = 0;
for (let i = 0; i < this._frameCount; i++) {
totalWidth += this._frameWidth;
if (totalWidth > this._material.diffuseTexture.width) {
totalWidth = 0;
totalHeight++;
}
const u = (i * this._frameWidth) / this._material.diffuseTexture.width;
const v = (totalHeight * this._frameHeight) / this._material.diffuseTexture.height;
const um = ((i * this._frameWidth) + this._frameWidth) / this._material.diffuseTexture.width;
const vm = ((totalHeight * this._frameHeight) + this._frameHeight) / this._material.diffuseTexture.height;
this._frameUVs.push([new Vector2(u, v), new Vector2(um, vm)]);
}
this._loaded = true;
}, 0);
}
public update(time: number) {
if (!this._loaded) return;
this.currentTime += time;
if (this.currentTime > this._frameTime) {
this._currentFrame++;
this.currentTime = 0;
if (this._currentFrame >= this._frameSequence.length)
this._currentFrame = 0;
const frameUVs = this._frameUVs[this._frameSequence[this._currentFrame]];
this._vertices[0].texCoords.copyFrom(frameUVs[0]);
this._vertices[1].texCoords = new Vector2(frameUVs[0].x, frameUVs[1].y);
this._vertices[2].texCoords.copyFrom(frameUVs[1]);
this._vertices[3].texCoords.copyFrom(frameUVs[1]);
this._vertices[4].texCoords = new Vector2(frameUVs[1].x, frameUVs[0].y);
this._vertices[5].texCoords.copyFrom(frameUVs[0]);
this._buffer.setData(Vertex.vertexArray(this._vertices));
this._buffer.upload();
this._buffer.unbind();
}
super.update(time);
}
}
}

View File

@@ -0,0 +1,94 @@
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;
}
}
}

View File

@@ -0,0 +1,44 @@
namespace TSE {
class TextureReferenceNode {
public texture: Texture;
public referenceCount: number = 1;
public constructor(texture: Texture) {
this.texture = texture;
}
}
export class TextureManager {
private static _textures: { [name: string]: TextureReferenceNode } = {};
private constructor() { }
public static getTexture(textureName: string): Texture {
if (TextureManager._textures[textureName] === undefined)
TextureManager._textures[textureName] = new TextureReferenceNode(new Texture(textureName));
else
TextureManager._textures[textureName].referenceCount++;
return TextureManager._textures[textureName].texture;
}
public static releaseTexture(textureName: string): void {
if (TextureManager._textures[textureName] === undefined) {
console.warn(`A Texture named ${textureName} does not exist and cannot be released!`);
} else {
TextureManager._textures[textureName].referenceCount--;
if (TextureManager._textures[textureName].referenceCount < 1) {
TextureManager._textures[textureName].texture.destroy();
TextureManager._textures[textureName] = undefined;
delete TextureManager._textures[textureName];
}
}
}
}
}

View File

@@ -0,0 +1,30 @@
namespace TSE {
export class Vertex {
public static vertexArray(vertices: Vertex[]): number[] {
let array: number[] = [];
for (let vertex of vertices)
array = array.concat(vertex.toArray());
return array;
}
public position: Vector3;
public texCoords: Vector2;
public constructor(x: number = 0, y: number = 0, z: number = 0, u: number = 0, v: number = 0) {
this.position = new Vector3(x, y, z);
this.texCoords = new Vector2(u, v);
}
public toArray(): number[] {
let array: number[] = [];
array = array.concat(this.position.toArray(), this.texCoords.toArray());
return array;
}
public toFloat32Array(): Float32Array { return new Float32Array(this.toArray()); }
}
}