Add textures
This commit is contained in:
parent
5723b91b32
commit
7bfad8711b
25 changed files with 407 additions and 104 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { Texture } from '../texture/texture';
|
||||
import { UniversalRenderingContext } from '../universal-rendering-context';
|
||||
|
||||
/** @internal */
|
||||
|
|
@ -13,13 +14,10 @@ export abstract class FrameBuffer {
|
|||
|
||||
constructor(protected readonly gl: UniversalRenderingContext) {}
|
||||
|
||||
public bindAndClear(inputTextures: Array<WebGLTexture>) {
|
||||
public bindAndClear(inputTextures: Array<Texture>) {
|
||||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.frameBuffer);
|
||||
|
||||
inputTextures.forEach((t, i) => {
|
||||
this.gl.activeTexture(this.gl.TEXTURE0 + i);
|
||||
this.gl.bindTexture(this.gl.TEXTURE_2D, t);
|
||||
});
|
||||
inputTextures.forEach((t) => t.bind());
|
||||
|
||||
this.gl.viewport(0, 0, this.size.x, this.size.y);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
import { vec3, vec4 } from 'gl-matrix';
|
||||
import { UniversalRenderingContext } from './universal-rendering-context';
|
||||
|
||||
/** @internal */
|
||||
export class PaletteTexture {
|
||||
private texture: WebGLTexture;
|
||||
|
||||
constructor(
|
||||
private readonly gl: UniversalRenderingContext,
|
||||
private readonly paletteSize: number
|
||||
) {
|
||||
this.texture = gl.createTexture()!;
|
||||
this.bind();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public get colorTexture(): WebGLTexture {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
private bind() {
|
||||
this.gl.activeTexture(this.gl.TEXTURE1);
|
||||
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
|
||||
}
|
||||
|
||||
public setPalette(colors: Array<vec3 | vec4>) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = this.paletteSize;
|
||||
canvas.height = 1;
|
||||
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
const imageData = ctx.createImageData(this.paletteSize, 1);
|
||||
|
||||
colors.forEach((c, i) => {
|
||||
imageData.data[4 * i + 0] = c[0] * 255;
|
||||
imageData.data[4 * i + 1] = c[1] * 255;
|
||||
imageData.data[4 * i + 2] = c[2] * 255;
|
||||
imageData.data[4 * i + 3] = c.length == 4 ? c[3] * 255 : 255;
|
||||
});
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
this.setImage(canvas);
|
||||
}
|
||||
|
||||
public setImage(image: TexImageSource) {
|
||||
this.bind();
|
||||
|
||||
this.gl.texImage2D(
|
||||
this.gl.TEXTURE_2D,
|
||||
0,
|
||||
this.gl.RGBA,
|
||||
this.gl.RGBA,
|
||||
this.gl.UNSIGNED_BYTE,
|
||||
image
|
||||
);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.gl.deleteTexture(this.texture);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,10 +16,10 @@ export class FragmentShaderOnlyProgram extends Program {
|
|||
|
||||
public async initialize(
|
||||
sources: [string, string],
|
||||
substitutions: { [name: string]: string },
|
||||
compiler: ParallelCompiler
|
||||
compiler: ParallelCompiler,
|
||||
substitutions: { [name: string]: string } = {}
|
||||
): Promise<void> {
|
||||
await super.initialize(sources, substitutions, compiler);
|
||||
await super.initialize(sources, compiler, substitutions);
|
||||
this.prepareScreenQuad('vertexPosition');
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ export class FragmentShaderOnlyProgram extends Program {
|
|||
}
|
||||
}
|
||||
|
||||
public draw(uniforms: { [name: string]: any }) {
|
||||
public draw(uniforms: { [name: string]: any } = {}) {
|
||||
super.draw(uniforms);
|
||||
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ export default abstract class Program implements IProgram {
|
|||
|
||||
public async initialize(
|
||||
[vertexShaderSource, fragmentShaderSource]: [string, string],
|
||||
substitutions: { [name: string]: string },
|
||||
compiler: ParallelCompiler
|
||||
compiler: ParallelCompiler,
|
||||
substitutions: { [name: string]: string } = {}
|
||||
): Promise<void> {
|
||||
substitutions = { ...substitutions };
|
||||
|
||||
|
|
|
|||
29
src/graphics/graphics-library/texture/palette-texture.ts
Normal file
29
src/graphics/graphics-library/texture/palette-texture.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { vec3, vec4 } from 'gl-matrix';
|
||||
import { UniversalRenderingContext } from '../universal-rendering-context';
|
||||
import { Texture } from './texture';
|
||||
|
||||
/** @internal */
|
||||
export class PaletteTexture extends Texture {
|
||||
constructor(gl: UniversalRenderingContext, private readonly paletteSize: number) {
|
||||
super(gl, 1);
|
||||
}
|
||||
|
||||
public setPalette(colors: Array<vec3 | vec4>) {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = this.paletteSize;
|
||||
canvas.height = 1;
|
||||
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
const imageData = ctx.createImageData(this.paletteSize, 1);
|
||||
|
||||
colors.forEach((c, i) => {
|
||||
imageData.data[4 * i + 0] = c[0] * 255;
|
||||
imageData.data[4 * i + 1] = c[1] * 255;
|
||||
imageData.data[4 * i + 2] = c[2] * 255;
|
||||
imageData.data[4 * i + 3] = c.length == 4 ? c[3] * 255 : 255;
|
||||
});
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
this.setImage(canvas);
|
||||
}
|
||||
}
|
||||
22
src/graphics/graphics-library/texture/texture-options.ts
Normal file
22
src/graphics/graphics-library/texture/texture-options.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export enum WrapOptions {
|
||||
CLAMP_TO_EDGE = 'CLAMP_TO_EDGE',
|
||||
REPEAT = 'REPEAT',
|
||||
MIRRORED_REPEAT = 'MIRRORED_REPEAT',
|
||||
}
|
||||
|
||||
export enum FilteringOptions {
|
||||
LINEAR = 'LINEAR',
|
||||
NEAREST = 'NEAREST',
|
||||
}
|
||||
|
||||
export interface TextureOptions {
|
||||
wrapS: WrapOptions;
|
||||
wrapT: WrapOptions;
|
||||
minFilter: FilteringOptions;
|
||||
maxFilter: FilteringOptions;
|
||||
}
|
||||
|
||||
export type TextureWithOptions = {
|
||||
source: TexImageSource;
|
||||
overrides: Partial<TextureOptions>;
|
||||
};
|
||||
62
src/graphics/graphics-library/texture/texture.ts
Normal file
62
src/graphics/graphics-library/texture/texture.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { UniversalRenderingContext } from '../universal-rendering-context';
|
||||
import { FilteringOptions, TextureOptions, WrapOptions } from './texture-options';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class Texture {
|
||||
protected texture: WebGLTexture;
|
||||
|
||||
constructor(
|
||||
protected readonly gl: UniversalRenderingContext,
|
||||
private textureUnitId: number,
|
||||
textureOptionOverrides: Partial<TextureOptions> = {}
|
||||
) {
|
||||
const defaultTextureOptions: TextureOptions = {
|
||||
wrapS: WrapOptions.CLAMP_TO_EDGE,
|
||||
wrapT: WrapOptions.CLAMP_TO_EDGE,
|
||||
minFilter: FilteringOptions.NEAREST,
|
||||
maxFilter: FilteringOptions.NEAREST,
|
||||
};
|
||||
|
||||
const textureOptions = {
|
||||
...defaultTextureOptions,
|
||||
...textureOptionOverrides,
|
||||
};
|
||||
|
||||
this.texture = gl.createTexture()!;
|
||||
|
||||
this.bind();
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl[textureOptions.wrapS]);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl[textureOptions.wrapT]);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl[textureOptions.minFilter]);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl[textureOptions.maxFilter]);
|
||||
}
|
||||
|
||||
public get colorTexture(): WebGLTexture {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public bind() {
|
||||
this.gl.activeTexture(this.gl.TEXTURE0 + this.textureUnitId);
|
||||
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
|
||||
}
|
||||
|
||||
public setImage(image: TexImageSource) {
|
||||
this.bind();
|
||||
|
||||
this.gl.texImage2D(
|
||||
this.gl.TEXTURE_2D,
|
||||
0,
|
||||
this.gl.RGBA,
|
||||
this.gl.RGBA,
|
||||
this.gl.UNSIGNED_BYTE,
|
||||
image
|
||||
);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.gl.deleteTexture(this.texture);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue