ris-framework 0.1.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/assets/_ris-ktx2-node-module-stub-DwDS30PT.js +1 -0
- package/dist/assets/cat.jpg +0 -0
- package/dist/assets/index-BmeGit54.css +1 -0
- package/dist/assets/index-qyn4pzGw.js +151 -0
- package/dist/assets/libktx-Cjh8w7XG-Ci1Fm_MH.js +1 -0
- package/dist/assets/test.png +0 -0
- package/dist/index.html +16 -0
- package/dist/vite.svg +1 -0
- package/package.json +37 -0
- package/shaders/glsl/inspect_texture_mips_fs.glsl +18 -0
- package/shaders/glsl/inspect_texture_mips_vs.glsl +25 -0
- package/shaders/glsl/main_render_target_flip_y_fs.glsl +9 -0
- package/shaders/glsl/main_render_target_flip_y_vs.glsl +9 -0
- package/shaders/glsl/sprite_fs.glsl +14 -0
- package/shaders/glsl/sprite_vs.glsl +20 -0
- package/shaders/glsl/unlit_material_fs.glsl +19 -0
- package/shaders/glsl/unlit_material_vs.glsl +25 -0
- package/src/TextureFormat.ts +0 -0
- package/src/VertexFormat.ts +17 -0
- package/src/common/sampler-enums.ts +21 -0
- package/src/common/vertex-step-mode.ts +12 -0
- package/src/content/ShaderModuleContent.ts +47 -0
- package/src/core/Framework.ts +240 -0
- package/src/core/FrameworkConfig.ts +31 -0
- package/src/core/buffers/buffers-factory-interface.ts +0 -0
- package/src/core/buffers/vertex-buffer-interface.ts +0 -0
- package/src/core/content/ContentManager.ts +86 -0
- package/src/core/dependency-injection/register-services-interface.ts +15 -0
- package/src/core/framework-interface.ts +0 -0
- package/src/core/input/InputManager.ts +115 -0
- package/src/core/renderer/enums.ts +20 -0
- package/src/core/renderer/renderer-interface.ts +92 -0
- package/src/core/renderer/rendering-limits.ts +20 -0
- package/src/core/rendering/AGraphicsDevice.ts +119 -0
- package/src/core/rendering/ARenderer.ts +247 -0
- package/src/core/rendering/blending/blend-component-descriptor.ts +33 -0
- package/src/core/rendering/blending/blend-state-descriptor.ts +51 -0
- package/src/core/rendering/blending/enums.ts +50 -0
- package/src/core/rendering/enums.ts +22 -0
- package/src/core/rendering/primitive/PrimitiveStateDescriptor.ts +32 -0
- package/src/core/rendering/primitive/enums.ts +68 -0
- package/src/core/rendering/render-pass/render-pass-descriptor.ts +0 -0
- package/src/core/rendering/render-pass/render-pass-interface.ts +17 -0
- package/src/core/rendering/sampler/sampler-descriptor.ts +33 -0
- package/src/core/rendering/texture/texture.ts +146 -0
- package/src/core/rendering/vertex-attribute.ts +20 -0
- package/src/core/rendering/vertex-buffer-layout.ts +84 -0
- package/src/core/shader/shader-loader.ts +27 -0
- package/src/core/shader/shader-module-interface.ts +1 -0
- package/src/core/sprite-batch/SpriteBatch.ts +216 -0
- package/src/core/sprite-batch/SpriteBatchDrawable.ts +146 -0
- package/src/core/sprite-batch/SpriteBatchMesh.ts +243 -0
- package/src/core/window/window-manager.ts +76 -0
- package/src/counter.ts +9 -0
- package/src/geometry/BaseGeometry.ts +148 -0
- package/src/geometry/GeometryBuilder.ts +58 -0
- package/src/geometry/GeometryFormat.ts +37 -0
- package/src/main.ts +97 -0
- package/src/style.css +96 -0
- package/src/typescript.svg +1 -0
- package/src/webgl/WebGLGraphicsDeviceFeatures.ts +57 -0
- package/src/webgl/WebGlGpuInfo.ts +76 -0
- package/src/webgl/WebGlGraphicsDevice.ts +129 -0
- package/src/webgl/WebGlRenderer.ts +31 -0
- package/src/webgl/blending/webgl-blend-state.ts +59 -0
- package/src/webgl/buffers/WebGlBuffersFactory.ts +75 -0
- package/src/webgl/buffers/WebGlUniformBuffer.ts +87 -0
- package/src/webgl/buffers/WebGlVertexBuffer.ts +100 -0
- package/src/webgl/buffers/webgl-index-buffer.ts +110 -0
- package/src/webgl/cast/cast.ts +100 -0
- package/src/webgl/primitive/WebGlPrimitiveState.ts +60 -0
- package/src/webgl/render-pass/WebGlRenderPass.ts +186 -0
- package/src/webgl/render-pipelines/AWebGlRenderPipeline.ts +129 -0
- package/src/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.ts +95 -0
- package/src/webgl/render-pipelines/WebGlRenderPipelineFactory.ts +75 -0
- package/src/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.ts +200 -0
- package/src/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.ts +197 -0
- package/src/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.ts +148 -0
- package/src/webgl/rendering/webgl-vertex-attribute.ts +16 -0
- package/src/webgl/rendering/webgl-vertex-buffer-layout.ts +64 -0
- package/src/webgl/sampler/webgl-sampler.ts +110 -0
- package/src/webgl/shader/WebGlShaderModule.ts +110 -0
- package/src/webgl/shader/WebGlShaderModuleLoader.ts +40 -0
- package/src/webgl/swap-chain/WebGlSwapChain.ts +56 -0
- package/src/webgl/texture/WebGlTexture2D.ts +133 -0
- package/src/webgl/texture/WebGlTextureFactory.ts +184 -0
- package/src/webgl/utilities/WebGlBufferUtilities.ts +124 -0
- package/src/webgl/utilities/WebGlConverter.ts +391 -0
- package/src/webgl/utilities/WebGlFrameBufferUtilities.ts +240 -0
- package/src/webgl/utilities/WebGlSamplerUtilities.ts +81 -0
- package/src/webgl/utilities/WebGlShaderUtilities.ts +48 -0
- package/src/webgl/utilities/WebGlTextureUtilities.ts +162 -0
- package/src/webgl/utilities/WebGlUtilities.ts +71 -0
- package/src/webgl/utilities/spector-js-utilities.ts +13 -0
- package/src/webgl/utilities/webgl-blending-utilities.ts +85 -0
- package/src/webgl/utilities/webgl-culling-utilities.ts +23 -0
- package/src/webgl/utilities/webgl-filter-anisotropic-utilities.ts +37 -0
- package/src/webgl/utilities/webgl-program-utilities.ts +29 -0
- package/src/webgl/utilities/webgl-render-buffer-utilities.ts +23 -0
- package/src/webgl/utilities/webgl-renderbuffer-utilities.ts +35 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { WebGlUtilities } from "../utilities/WebGlUtilities.ts";
|
|
2
|
+
import type { WebGlGraphicsDevice } from "../WebGlGraphicsDevice.ts";
|
|
3
|
+
import {AlignUtilities, type BufferUsage, type IFramework, type IUniformBuffer} from "ris-framework-api";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The WebGL implementation of the uniform buffer.
|
|
7
|
+
*/
|
|
8
|
+
export class WebGlUniformBuffer implements IUniformBuffer {
|
|
9
|
+
|
|
10
|
+
private readonly _gl: WebGL2RenderingContext;
|
|
11
|
+
private _byteSize: number = 0;
|
|
12
|
+
private _data: Float32Array;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The constructor.
|
|
16
|
+
* @param framework The framework.
|
|
17
|
+
* @param dataOrByteSize The data or it's byte size.
|
|
18
|
+
* @param bufferUsage The buffer usage.
|
|
19
|
+
* @param label The label to use.
|
|
20
|
+
*/
|
|
21
|
+
public constructor(framework: IFramework,
|
|
22
|
+
dataOrByteSize: ArrayLike<number> | number,
|
|
23
|
+
bufferUsage: BufferUsage,
|
|
24
|
+
label?: string) {
|
|
25
|
+
|
|
26
|
+
this._gl = (framework.renderer.graphicsDevice as WebGlGraphicsDevice).gl;
|
|
27
|
+
this.usage = bufferUsage;
|
|
28
|
+
this.label = label;
|
|
29
|
+
|
|
30
|
+
if(typeof dataOrByteSize === "number") {
|
|
31
|
+
this._data = new Float32Array(dataOrByteSize);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this._data = new Float32Array(AlignUtilities.alignArray(dataOrByteSize, 4));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this._byteSize = this._data.byteLength;
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The native WebGL buffer object that is used to store the uniform data.
|
|
44
|
+
*/
|
|
45
|
+
public glBuffer: WebGLBuffer | null = null;
|
|
46
|
+
|
|
47
|
+
/** @inheritdoc */
|
|
48
|
+
public readonly label?: string;
|
|
49
|
+
|
|
50
|
+
/** @inheritdoc */
|
|
51
|
+
public get byteSize(): number {
|
|
52
|
+
return this._byteSize;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** @inheritdoc */
|
|
56
|
+
public readonly usage: BufferUsage;
|
|
57
|
+
|
|
58
|
+
/** @inheritdoc */
|
|
59
|
+
public initialize(): void {
|
|
60
|
+
|
|
61
|
+
this.glBuffer = WebGlUtilities.buffer.createUniformBuffer(
|
|
62
|
+
this._gl, this._data, this.usage, this.label);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/** @inheritdoc */
|
|
67
|
+
public update(data: number[], offset?: number, length?: number): void {
|
|
68
|
+
this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, this.glBuffer);
|
|
69
|
+
|
|
70
|
+
offset = offset ?? 0;
|
|
71
|
+
length = length ?? this._data.length;
|
|
72
|
+
for(let i = offset; i < length; i++)
|
|
73
|
+
{
|
|
74
|
+
this._data[i] = data[i];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset ?? 0, this._data);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @inheritdoc */
|
|
81
|
+
public dispose(): void {
|
|
82
|
+
if (this.glBuffer) {
|
|
83
|
+
this._gl.deleteBuffer(this.glBuffer);
|
|
84
|
+
this.glBuffer = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {WebGlUtilities} from "../utilities/WebGlUtilities.ts";
|
|
2
|
+
import type {WebGlGraphicsDevice} from "../WebGlGraphicsDevice.ts";
|
|
3
|
+
import {BufferUsage, type IFramework, type IVertexBuffer} from "ris-framework-api";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The WebGL implementation of the vertex buffer.
|
|
7
|
+
* This class is responsible for managing a vertex buffer in WebGL,
|
|
8
|
+
* including creating the buffer, uploading data to the buffer,
|
|
9
|
+
* and providing information about the buffer such as its size and stride.
|
|
10
|
+
*/
|
|
11
|
+
export class WebGlVertexBuffer implements IVertexBuffer {
|
|
12
|
+
|
|
13
|
+
private readonly _graphicsDevice: WebGlGraphicsDevice;
|
|
14
|
+
private readonly _gl: WebGL2RenderingContext;
|
|
15
|
+
private _vertexCount = 0;
|
|
16
|
+
private _byteSize = 0;
|
|
17
|
+
private _data: Float32Array;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The constructor.
|
|
21
|
+
* @param _framework
|
|
22
|
+
* @param dataOrVertexCount
|
|
23
|
+
* @param _byteStride
|
|
24
|
+
* @param _bufferUsage
|
|
25
|
+
* @param _label
|
|
26
|
+
*/
|
|
27
|
+
constructor(private readonly _framework: IFramework,
|
|
28
|
+
dataOrVertexCount: ArrayLike<number> | number,
|
|
29
|
+
private readonly _byteStride: number,
|
|
30
|
+
private readonly _bufferUsage: BufferUsage,
|
|
31
|
+
private readonly _label?: string) {
|
|
32
|
+
this._graphicsDevice = this._framework.renderer.graphicsDevice as WebGlGraphicsDevice;
|
|
33
|
+
this._gl = this._graphicsDevice.gl;
|
|
34
|
+
|
|
35
|
+
if (typeof dataOrVertexCount === "number") {
|
|
36
|
+
this._vertexCount = dataOrVertexCount;
|
|
37
|
+
this._byteSize = dataOrVertexCount * this._byteStride;
|
|
38
|
+
this._data = new Float32Array(dataOrVertexCount);
|
|
39
|
+
}
|
|
40
|
+
// Is iterable
|
|
41
|
+
else {
|
|
42
|
+
this._data = new Float32Array(dataOrVertexCount);
|
|
43
|
+
this._byteSize = dataOrVertexCount.length * Float32Array.BYTES_PER_ELEMENT;
|
|
44
|
+
this._vertexCount = this._byteSize / this._byteStride;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The WebGL buffer object that represents the vertex buffer in WebGL.
|
|
50
|
+
*/
|
|
51
|
+
public buffer: WebGLBuffer | null = null;
|
|
52
|
+
|
|
53
|
+
/** @inheritdoc */
|
|
54
|
+
public get label(): string | undefined {
|
|
55
|
+
return this._label;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @inheritdoc */
|
|
59
|
+
public get vertexCount(): number {
|
|
60
|
+
return this._vertexCount;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @inheritdoc */
|
|
64
|
+
public get byteSize(): number {
|
|
65
|
+
return this._byteSize;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @inheritdoc */
|
|
69
|
+
public get byteStride(): number {
|
|
70
|
+
return this._byteStride;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** @inheritdoc */
|
|
74
|
+
public get usage(): BufferUsage {
|
|
75
|
+
return this._bufferUsage;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** @inheritdoc */
|
|
79
|
+
public initialize(): void {
|
|
80
|
+
this.buffer = WebGlUtilities.buffer.createVertexBuffer(this._gl, this._data, this._bufferUsage);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** @inheritdoc */
|
|
84
|
+
public update(data: number[], offset: number = 0, length: number = 0): void {
|
|
85
|
+
|
|
86
|
+
length = length > 0 ? length : data.length;
|
|
87
|
+
|
|
88
|
+
for (let i = offset; i < length; ++i) {
|
|
89
|
+
this._data[i] = data[i];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
WebGlUtilities.buffer.updateVertexBuffer(this._gl, this.buffer!, this._data, 0, offset, length);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** @inheritDoc */
|
|
96
|
+
public dispose(): void {
|
|
97
|
+
this._gl.deleteBuffer(this.buffer);
|
|
98
|
+
this.buffer = null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type {IFramework} from "ris-framework-api";
|
|
2
|
+
import {asWebGLGraphicsDevice} from "../cast/cast";
|
|
3
|
+
import {WebGlUtilities} from "../utilities/WebGlUtilities.ts";
|
|
4
|
+
import {BufferUsage, type IIndexBuffer, IndexBufferType} from "ris-framework-api";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The WebGLIndexBuffer class is an implementation of the IIndexBuffer interface for WebGL.
|
|
8
|
+
* It represents a buffer that holds index data for rendering in a WebGL context. The class provides properties to access the type, size, and count of indices, as well as a method to initialize the buffer with index data. It also implements the IDisposable interface, allowing it to be disposed of to free resources when it is no longer needed.
|
|
9
|
+
*/
|
|
10
|
+
export class WebGLIndexBuffer implements IIndexBuffer {
|
|
11
|
+
|
|
12
|
+
private readonly _gl: WebGL2RenderingContext;
|
|
13
|
+
private readonly _label?: string;
|
|
14
|
+
|
|
15
|
+
private _type = IndexBufferType.UINT_16;
|
|
16
|
+
private _elementByteSize = 0;
|
|
17
|
+
private _indicesCount = 0;
|
|
18
|
+
private _byteSize = 0;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The constructor.
|
|
22
|
+
* @param framework The framework.
|
|
23
|
+
* @param label An optional label for the index buffer, which can be used for debugging purposes.
|
|
24
|
+
*/
|
|
25
|
+
constructor(framework: IFramework, label?: string) {
|
|
26
|
+
this._gl = asWebGLGraphicsDevice(framework.renderer.graphicsDevice).gl;
|
|
27
|
+
this._label = label;
|
|
28
|
+
this.usage = BufferUsage.INDEX;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @inheritdoc */
|
|
32
|
+
public readonly usage: BufferUsage = BufferUsage.INDEX;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The WebGL buffer object that represents the index buffer in WebGL.
|
|
36
|
+
* This buffer is used to store the index data on the GPU and is bound to the appropriate target when rendering.
|
|
37
|
+
*/
|
|
38
|
+
public buffer: WebGLBuffer | null = null;
|
|
39
|
+
|
|
40
|
+
/** @inheritdoc */
|
|
41
|
+
public get type(): IndexBufferType {
|
|
42
|
+
return this._type;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** @inheritdoc */
|
|
46
|
+
public get elementByteSize(): number {
|
|
47
|
+
return this._elementByteSize;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @inheritdoc */
|
|
51
|
+
public get label(): string {
|
|
52
|
+
return this._label ?? "";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** @inheritdoc */
|
|
56
|
+
public get indicesCount(): number {
|
|
57
|
+
return this._indicesCount;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @inheritdoc */
|
|
61
|
+
public get byteSize(): number {
|
|
62
|
+
return this._byteSize;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private _canUseUint16(values: ArrayLike<number>): boolean {
|
|
66
|
+
let max = 0;
|
|
67
|
+
|
|
68
|
+
for (let i = 0; i < values.length; i++) {
|
|
69
|
+
const v = values[i];
|
|
70
|
+
if (v < 0 || v > 0xFFFF) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (v > max) {
|
|
74
|
+
max = v;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return max <= 0xFFFF;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** @inheritdoc */
|
|
82
|
+
public initialize(data: ArrayLike<number>): void {
|
|
83
|
+
|
|
84
|
+
const typedData = this._canUseUint16(data) ? new Uint16Array(data) : new Uint32Array(data);
|
|
85
|
+
|
|
86
|
+
if (typedData instanceof Uint16Array) {
|
|
87
|
+
this._type = IndexBufferType.UINT_16;
|
|
88
|
+
this._elementByteSize = Uint16Array.BYTES_PER_ELEMENT;
|
|
89
|
+
} else if (typedData instanceof Uint32Array) {
|
|
90
|
+
this._type = IndexBufferType.UINT_32;
|
|
91
|
+
this._elementByteSize = Uint32Array.BYTES_PER_ELEMENT;
|
|
92
|
+
} else {
|
|
93
|
+
throw new Error("Invalid data type for index buffer. Expected Uint16Array or Uint32Array.");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this._indicesCount = data.length;
|
|
97
|
+
this._byteSize = this._indicesCount * this._elementByteSize;
|
|
98
|
+
this.buffer = WebGlUtilities.buffer.createIndexBuffer(this._gl, typedData, BufferUsage.INDEX, this._label);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/** @inheritdoc */
|
|
103
|
+
public dispose(): void {
|
|
104
|
+
|
|
105
|
+
if (this.buffer) {
|
|
106
|
+
this._gl.deleteBuffer(this.buffer);
|
|
107
|
+
this.buffer = null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type {IBlendState, IIndexBuffer, ITexture2D, IUniformBuffer, IVertexBuffer} from "ris-framework-api";
|
|
2
|
+
import type { ITempRenderer } from "../../core/renderer/renderer-interface";
|
|
3
|
+
import { WebGlBlendState } from "../blending/webgl-blend-state";
|
|
4
|
+
import { WebGLIndexBuffer } from "../buffers/webgl-index-buffer";
|
|
5
|
+
import { WebGlUniformBuffer } from "../buffers/WebGlUniformBuffer.ts";
|
|
6
|
+
import { WebGlVertexBuffer } from "../buffers/WebGlVertexBuffer.ts";
|
|
7
|
+
import { WebGlTexture2D } from "../texture/WebGlTexture2D.ts";
|
|
8
|
+
import { WebGlGraphicsDevice } from "../WebGlGraphicsDevice.ts";
|
|
9
|
+
import { WebGlRenderer } from "../WebGlRenderer.ts";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Casts the given renderer to a WebGLRenderer. If the renderer is not a WebGLRenderer, an error is thrown.
|
|
13
|
+
* @param renderer The renderer to cast.
|
|
14
|
+
* @returns The given renderer casted to a WebGLRenderer.
|
|
15
|
+
*/
|
|
16
|
+
export function asWebGLRenderer(renderer: ITempRenderer): WebGlRenderer {
|
|
17
|
+
if (renderer instanceof WebGlRenderer) {
|
|
18
|
+
return renderer;
|
|
19
|
+
} else {
|
|
20
|
+
throw new Error("Renderer is not a WebGLRenderer.");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Casts the given texture to a WebGLTexture2D. If the texture is not a WebGLTexture2D, an error is thrown.
|
|
26
|
+
* @param texture The texture to cast.
|
|
27
|
+
* @returns The given texture casted to a WebGLTexture2D.
|
|
28
|
+
*/
|
|
29
|
+
export function asWebGLTexture2D(texture: ITexture2D): WebGlTexture2D {
|
|
30
|
+
if (texture instanceof WebGlTexture2D) {
|
|
31
|
+
return texture;
|
|
32
|
+
} else {
|
|
33
|
+
throw new Error("Texture is not a WebGLTexture2D.");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Casts the given vertex buffer to a WebGLVertexBuffer. If the vertex buffer is not a WebGLVertexBuffer, an error is thrown.
|
|
39
|
+
* @param vertexBuffer The vertex buffer to cast.
|
|
40
|
+
* @returns The given vertex buffer casted to a WebGLVertexBuffer.
|
|
41
|
+
*/
|
|
42
|
+
export function asWebGLVertexBuffer(vertexBuffer: IVertexBuffer): WebGlVertexBuffer {
|
|
43
|
+
if (vertexBuffer instanceof WebGlVertexBuffer) {
|
|
44
|
+
return vertexBuffer;
|
|
45
|
+
} else {
|
|
46
|
+
throw new Error("Vertex buffer is not a WebGLVertexBuffer.");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Casts the given index buffer to a WebGLIndexBuffer. If the index buffer is not a WebGLIndexBuffer, an error is thrown.
|
|
52
|
+
* @param indexBuffer The index buffer to cast.
|
|
53
|
+
* @returns The given index buffer cast to a WebGLIndexBuffer.
|
|
54
|
+
*/
|
|
55
|
+
export function asWebGLIndexBuffer(indexBuffer: IIndexBuffer): WebGLIndexBuffer {
|
|
56
|
+
if (indexBuffer instanceof WebGLIndexBuffer) {
|
|
57
|
+
return indexBuffer;
|
|
58
|
+
} else {
|
|
59
|
+
throw new Error("Index buffer is not a WebGLIndexBuffer.");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Casts the given uniform buffer to a WebGLUniformBuffer. If the uniform buffer is not a WebGLUniformBuffer, an error is thrown.
|
|
65
|
+
* @param uniformBuffer The uniform buffer to cast.
|
|
66
|
+
* @returns The given uniform buffer casted to a WebGLUniformBuffer.
|
|
67
|
+
*/
|
|
68
|
+
export function asWebGLUniformBuffer(uniformBuffer: IUniformBuffer): WebGlUniformBuffer {
|
|
69
|
+
if (uniformBuffer instanceof WebGlUniformBuffer) {
|
|
70
|
+
return uniformBuffer;
|
|
71
|
+
} else {
|
|
72
|
+
throw new Error("Uniform buffer is not a WebGLUniformBuffer.");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Casts the given graphics device to a WebGLGraphicsDevice. If the graphics device is not a WebGLGraphicsDevice, an error is thrown.
|
|
78
|
+
* @param graphicsDevice The graphics device to cast.
|
|
79
|
+
* @returns The given graphics device casted to a WebGLGraphicsDevice.
|
|
80
|
+
*/
|
|
81
|
+
export function asWebGLGraphicsDevice(graphicsDevice: ITempRenderer["graphicsDevice"]): WebGlGraphicsDevice {
|
|
82
|
+
if (graphicsDevice instanceof WebGlGraphicsDevice ) {
|
|
83
|
+
return graphicsDevice as WebGlGraphicsDevice;
|
|
84
|
+
} else {
|
|
85
|
+
throw new Error("Graphics device is not a WebGL graphics device.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Casts the given blend state to a WebGLBlendState. If the blend state is not a WebGLBlendState, an error is thrown.
|
|
91
|
+
* @param blendState The blend state to cast.
|
|
92
|
+
* @returns The given blend state casted to a WebGLBlendState.
|
|
93
|
+
*/
|
|
94
|
+
export function asWebGLBlendState(blendState: IBlendState): WebGlBlendState {
|
|
95
|
+
if (blendState instanceof WebGlBlendState) {
|
|
96
|
+
return blendState as WebGlBlendState;
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error("Blend state is not a WebGL blend state.");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type PrimitiveTopology, CullMode, type FrontFace } from "../../core/rendering/primitive/enums";
|
|
2
|
+
import type { PrimitiveStateDescriptor } from "../../core/rendering/primitive/PrimitiveStateDescriptor.ts";
|
|
3
|
+
import type { IPrimitiveState } from "ris-framework-api";
|
|
4
|
+
import { WebGlConverter } from "../utilities/WebGlConverter.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The WebGL implementation of a primitive state.
|
|
8
|
+
*/
|
|
9
|
+
export class WebGlPrimitiveState implements IPrimitiveState {
|
|
10
|
+
private readonly _cullingEnabled: boolean;
|
|
11
|
+
private readonly _glPrimitiveType: number;
|
|
12
|
+
private readonly _glCullFace: number;
|
|
13
|
+
private readonly _glFrontFace: number;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The constructor.
|
|
17
|
+
* @param _gl The WebGL2 Rendering Context.
|
|
18
|
+
* @param descriptor The descriptor of the primitive state.
|
|
19
|
+
*/
|
|
20
|
+
public constructor(_gl: WebGL2RenderingContext, descriptor: PrimitiveStateDescriptor) {
|
|
21
|
+
this.topology = descriptor.topology;
|
|
22
|
+
this.cullFace = descriptor.cullFace;
|
|
23
|
+
this.frontFace = descriptor.frontFace;
|
|
24
|
+
|
|
25
|
+
this._cullingEnabled = this.cullFace != CullMode.NONE;
|
|
26
|
+
|
|
27
|
+
this._glPrimitiveType = WebGlConverter.convertPrimitiveType(this.topology);
|
|
28
|
+
this._glCullFace = WebGlConverter.convertCullFace(this.cullFace);
|
|
29
|
+
this._glFrontFace = WebGlConverter.convertFrontFace(this.frontFace);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** @inheritdoc */
|
|
33
|
+
public readonly topology: PrimitiveTopology;
|
|
34
|
+
|
|
35
|
+
/** @inheritdoc */
|
|
36
|
+
public readonly cullFace: CullMode;
|
|
37
|
+
|
|
38
|
+
/** @inheritdoc */
|
|
39
|
+
public readonly frontFace: FrontFace;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The primitive type to draw.
|
|
43
|
+
*/
|
|
44
|
+
public get glPrimitiveType() {
|
|
45
|
+
return this._glPrimitiveType;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** @inheritdoc */
|
|
49
|
+
public apply(gl: WebGL2RenderingContext) {
|
|
50
|
+
if (this._cullingEnabled) {
|
|
51
|
+
gl.enable(gl.CULL_FACE);
|
|
52
|
+
gl.cullFace(this._glCullFace);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
gl.disable(gl.CULL_FACE);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
gl.frontFace(this._glFrontFace);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { IRenderPass } from "../../core/rendering/render-pass/render-pass-interface";
|
|
2
|
+
import { asWebGLTexture2D } from "../cast/cast";
|
|
3
|
+
import { WebGlUtilities } from "../utilities/WebGlUtilities.ts";
|
|
4
|
+
import type { WebGlGraphicsDevice } from "../WebGlGraphicsDevice.ts";
|
|
5
|
+
import {
|
|
6
|
+
Color,
|
|
7
|
+
LoadAction,
|
|
8
|
+
RenderPassColorAttachment, RenderPassDepthStencilAttachment,
|
|
9
|
+
RenderPassDescriptor,
|
|
10
|
+
StoreAction,
|
|
11
|
+
TextureFormat
|
|
12
|
+
} from "ris-framework-api"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The WeGL implementation of the IRenderPass interface.
|
|
16
|
+
*/
|
|
17
|
+
export class WebGlRenderPass implements IRenderPass {
|
|
18
|
+
|
|
19
|
+
private readonly _gl: WebGL2RenderingContext;
|
|
20
|
+
|
|
21
|
+
private _colorAttachmentsCount = 0;
|
|
22
|
+
private _clearColors: Color[] = [];
|
|
23
|
+
private _frameBuffer: WebGLFramebuffer | null = null;
|
|
24
|
+
private _depthStencilRenderBuffer: WebGLRenderbuffer | null = null;
|
|
25
|
+
private _clearBufferMask: GLbitfield = 0;
|
|
26
|
+
private _enableDepthTest = false;
|
|
27
|
+
private _enableStencilTest = false;
|
|
28
|
+
private _clearDepth = 0;
|
|
29
|
+
private _clearStencil = 0;
|
|
30
|
+
private _discardAttachments: GLenum[] = [];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The constructor.
|
|
34
|
+
* @param graphicsDevice The graphics device.
|
|
35
|
+
* @param descriptor The render pass descriptor.
|
|
36
|
+
*/
|
|
37
|
+
public constructor(graphicsDevice: WebGlGraphicsDevice, descriptor: RenderPassDescriptor) {
|
|
38
|
+
this._gl = graphicsDevice.gl;
|
|
39
|
+
|
|
40
|
+
this._setupFrameBuffer(descriptor.colorAttachments ?? []);
|
|
41
|
+
if (descriptor.depthStencilAttachment) {
|
|
42
|
+
this._setupDepthStencilAttachment(descriptor.depthStencilAttachment, descriptor.colorAttachments);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private _setupFrameBuffer(colorAttachments: RenderPassColorAttachment[]): void {
|
|
47
|
+
this._colorAttachmentsCount = colorAttachments.length;
|
|
48
|
+
this._clearColors = [];
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < this._colorAttachmentsCount; i++) {
|
|
51
|
+
const colorAttachment = colorAttachments[i];
|
|
52
|
+
this._clearColors.push(colorAttachment.clearColor);
|
|
53
|
+
if (colorAttachment.loadAction == LoadAction.CLEAR) {
|
|
54
|
+
this._clearBufferMask |= this._gl.COLOR_BUFFER_BIT;
|
|
55
|
+
}
|
|
56
|
+
if (colorAttachment.storeAction == StoreAction.DISCARD) {
|
|
57
|
+
this._discardAttachments.push(this._gl.COLOR_ATTACHMENT0 + i);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// If the color attachment is a swapchain, we don't need to create a framebuffer,
|
|
61
|
+
// as we'll be rendering directly to the default framebuffer.
|
|
62
|
+
if (colorAttachment.swapChain) {
|
|
63
|
+
this._frameBuffer = null; // Default framebuffer
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
var glColorAttachments = []
|
|
69
|
+
for (let i = 0; i < this._colorAttachmentsCount; i++) {
|
|
70
|
+
var colorAttachment = colorAttachments[i];
|
|
71
|
+
var texture = asWebGLTexture2D(colorAttachment.texture!);
|
|
72
|
+
if (!texture) {
|
|
73
|
+
throw new Error("Texture must be provided for non-swapchain color attachments.");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
glColorAttachments[i] = texture.glTexture;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// TODO : pass label
|
|
80
|
+
this._frameBuffer = WebGlUtilities.framebuffer.create(this._gl, glColorAttachments)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private _setupDepthStencilAttachment(depthStencilAttachment?: RenderPassDepthStencilAttachment, colorAttachments: RenderPassColorAttachment[] = []): void {
|
|
84
|
+
|
|
85
|
+
if (!depthStencilAttachment) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// DEPTH
|
|
90
|
+
this._clearDepth = depthStencilAttachment.depthClearValue;
|
|
91
|
+
if (depthStencilAttachment.depthLoadAction == LoadAction.CLEAR) {
|
|
92
|
+
this._clearBufferMask |= this._gl.DEPTH_BUFFER_BIT;
|
|
93
|
+
this._enableDepthTest = true;
|
|
94
|
+
}
|
|
95
|
+
if (depthStencilAttachment.depthStoreAction == StoreAction.DISCARD) {
|
|
96
|
+
this._discardAttachments.push(this._gl.DEPTH_ATTACHMENT);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// STENCIL
|
|
100
|
+
this._clearStencil = depthStencilAttachment.stencilClearValue;
|
|
101
|
+
if (depthStencilAttachment.stencilLoadAction == LoadAction.CLEAR) {
|
|
102
|
+
this._clearBufferMask |= this._gl.STENCIL_BUFFER_BIT;
|
|
103
|
+
this._enableStencilTest = true;
|
|
104
|
+
}
|
|
105
|
+
if (depthStencilAttachment.stencilStoreAction == StoreAction.DISCARD) {
|
|
106
|
+
this._discardAttachments.push(this._gl.STENCIL_ATTACHMENT);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
var texture = depthStencilAttachment.texture;
|
|
110
|
+
|
|
111
|
+
// We do allow depth-stencil attachment to be null, in which case the framebuffer will be created with renderbuffers instead of textures.
|
|
112
|
+
// This is useful for intermediate render passes that don't need to sample from the depth-stencil attachment.
|
|
113
|
+
if (!texture) {
|
|
114
|
+
if (this._enableDepthTest || this._enableStencilTest) {
|
|
115
|
+
var format = TextureFormat.DEPTH_24_STENCIL_8;
|
|
116
|
+
|
|
117
|
+
if (!this._enableDepthTest) {
|
|
118
|
+
// TODO: Implement this.
|
|
119
|
+
throw new Error("Not implemented");
|
|
120
|
+
}
|
|
121
|
+
else if (!this._enableStencilTest) {
|
|
122
|
+
format = TextureFormat.DEPTH_32_FLOAT;
|
|
123
|
+
}
|
|
124
|
+
var colorTex = colorAttachments[0].texture!;
|
|
125
|
+
this._depthStencilRenderBuffer = WebGlUtilities.renderBuffer.create(this._gl, format, colorTex.width, colorTex.height, null);
|
|
126
|
+
WebGlUtilities.framebuffer.attachDepthStencilRenderBuffer(this._gl, this._frameBuffer!, this._depthStencilRenderBuffer, format);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Otherwise, we attach the provided depth-stencil texture to the framebuffer.
|
|
130
|
+
else {
|
|
131
|
+
var glTexture = asWebGLTexture2D(texture);
|
|
132
|
+
WebGlUtilities.framebuffer.attachDepthStencilTexture(this._gl, this._frameBuffer!, glTexture.glTexture, glTexture.textureFormat);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** @inheritdoc */
|
|
137
|
+
public beginPass(): void {
|
|
138
|
+
const gl = this._gl;
|
|
139
|
+
|
|
140
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
|
|
141
|
+
|
|
142
|
+
// COLOR
|
|
143
|
+
gl.clear(this._clearBufferMask);
|
|
144
|
+
|
|
145
|
+
if (this._enableDepthTest) {
|
|
146
|
+
gl.enable(gl.DEPTH_TEST);
|
|
147
|
+
gl.clearDepth(this._clearDepth);
|
|
148
|
+
gl.depthFunc(gl.LEQUAL);
|
|
149
|
+
} else {
|
|
150
|
+
gl.disable(gl.DEPTH_TEST);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (this._enableStencilTest) {
|
|
154
|
+
gl.enable(gl.STENCIL_TEST);
|
|
155
|
+
gl.clearStencil(this._clearStencil);
|
|
156
|
+
gl.stencilFunc(gl.ALWAYS, 0, 0xFF);
|
|
157
|
+
} else {
|
|
158
|
+
gl.disable(gl.STENCIL_TEST);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < this._colorAttachmentsCount; i++) {
|
|
162
|
+
gl.clearBufferfv(gl.COLOR, i, this._clearColors[i]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** @inheritdoc */
|
|
167
|
+
public endPass(): void {
|
|
168
|
+
|
|
169
|
+
const gl = this._gl;
|
|
170
|
+
if (this._discardAttachments.length > 0) {
|
|
171
|
+
gl.invalidateFramebuffer(gl.FRAMEBUFFER, this._discardAttachments);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** @inheritdoc */
|
|
176
|
+
public dispose(): void {
|
|
177
|
+
if (this._frameBuffer) {
|
|
178
|
+
this._gl.deleteFramebuffer(this._frameBuffer);
|
|
179
|
+
this._frameBuffer = null!;
|
|
180
|
+
}
|
|
181
|
+
if (this._depthStencilRenderBuffer) {
|
|
182
|
+
this._gl.deleteRenderbuffer(this._depthStencilRenderBuffer);
|
|
183
|
+
this._depthStencilRenderBuffer = null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|