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,146 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IFramework,
|
|
3
|
+
ISpriteRenderPipeline,
|
|
4
|
+
ITexture2D,
|
|
5
|
+
IUniformBuffer,
|
|
6
|
+
Color,
|
|
7
|
+
IDisposable, ISampler
|
|
8
|
+
} from "ris-framework-api";
|
|
9
|
+
import {SpriteBatchMesh} from "./SpriteBatchMesh.ts";
|
|
10
|
+
import type {vec2, vec3} from "gl-matrix";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The drawable class for sprite batch.
|
|
14
|
+
*/
|
|
15
|
+
export class SpriteBatchDrawable implements IDisposable {
|
|
16
|
+
|
|
17
|
+
private readonly _framework: IFramework;
|
|
18
|
+
private readonly _texture: ITexture2D;
|
|
19
|
+
private readonly _sampler: ISampler;
|
|
20
|
+
private _maxBatchSize: number;
|
|
21
|
+
private _drawingMesh: SpriteBatchMesh = null!;
|
|
22
|
+
private _renderPipeline: ISpriteRenderPipeline = null!;
|
|
23
|
+
|
|
24
|
+
private _needsResize = false;
|
|
25
|
+
|
|
26
|
+
private _fromInstance = 0;
|
|
27
|
+
private _toInstance = 0;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The constructor.
|
|
31
|
+
* @param framework The framework.
|
|
32
|
+
* @param texture The texture.
|
|
33
|
+
* @param sampler The sampler.
|
|
34
|
+
* @param projectionViewBuffer The projection view buffer.
|
|
35
|
+
* @param maxBatchSize The maximum size of batch.
|
|
36
|
+
*/
|
|
37
|
+
public constructor(
|
|
38
|
+
framework: IFramework,
|
|
39
|
+
texture: ITexture2D,
|
|
40
|
+
sampler: ISampler,
|
|
41
|
+
projectionViewBuffer: IUniformBuffer,
|
|
42
|
+
maxBatchSize: number) {
|
|
43
|
+
this._framework = framework;
|
|
44
|
+
this._texture = texture;
|
|
45
|
+
this._sampler = sampler;
|
|
46
|
+
this._maxBatchSize = maxBatchSize;
|
|
47
|
+
this.projectionViewBuffer = projectionViewBuffer;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The projection view buffer.
|
|
52
|
+
*/
|
|
53
|
+
public readonly projectionViewBuffer: IUniformBuffer;
|
|
54
|
+
|
|
55
|
+
/** Initialize the drawable */
|
|
56
|
+
public initialize(): void {
|
|
57
|
+
this._renderPipeline = this._framework
|
|
58
|
+
.renderPipelineFactory
|
|
59
|
+
.createSpriteRenderPipeline(this.projectionViewBuffer);
|
|
60
|
+
this._renderPipeline.spriteTexture = this._texture;
|
|
61
|
+
this._renderPipeline.textureSampler = this._sampler;
|
|
62
|
+
|
|
63
|
+
this._drawingMesh = new SpriteBatchMesh(this._framework, this._maxBatchSize);
|
|
64
|
+
this._drawingMesh.initialize();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Resets the batch for new draw operation.
|
|
69
|
+
*/
|
|
70
|
+
public reset(): void {
|
|
71
|
+
// Nothing is drawn yet.
|
|
72
|
+
this._fromInstance = 0;
|
|
73
|
+
this._toInstance = 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Writes a sprite to the batch sprite mesh.
|
|
78
|
+
*
|
|
79
|
+
* @param position - The position of the sprite.
|
|
80
|
+
* @param size - The size of the sprite.
|
|
81
|
+
* @param color - The color of the sprite.
|
|
82
|
+
* @param u0 - The minimum U texture coordinate. Defaults to `0`.
|
|
83
|
+
* @param v0 - The minimum V texture coordinate. Defaults to `0`.
|
|
84
|
+
* @param u1 - The maximum U texture coordinate. Defaults to `1`.
|
|
85
|
+
* @param v1 - The maximum V texture coordinate. Defaults to `1`.
|
|
86
|
+
* @param flipY - Whether to vertically flip the texture coordinates. Defaults to `false`.
|
|
87
|
+
*/
|
|
88
|
+
public writeSprite(
|
|
89
|
+
position: vec3, size: vec2, color: Color,
|
|
90
|
+
u0 = 0, v0 = 0, u1 = 1, v1 = 1,
|
|
91
|
+
flipY = false
|
|
92
|
+
): void {
|
|
93
|
+
// We must wait for frame end to resize.
|
|
94
|
+
if (this._toInstance >= this._maxBatchSize) {
|
|
95
|
+
this._needsResize = true;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this._drawingMesh.writeSprite(this._toInstance, position, size, color, u0, v0, u1, v1, flipY);
|
|
100
|
+
|
|
101
|
+
// Write at correct position.
|
|
102
|
+
this._toInstance++;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Draws the mesh */
|
|
106
|
+
public draw(): void {
|
|
107
|
+
// Nothing to draw.
|
|
108
|
+
if (this._toInstance <= 0 || this._fromInstance > this._toInstance) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Clamp instance to max batch size.
|
|
113
|
+
if (this._toInstance >= this._maxBatchSize) {
|
|
114
|
+
this._toInstance = this._maxBatchSize - 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Draw mesh.
|
|
118
|
+
const indicesOffset = this._fromInstance * 6;
|
|
119
|
+
const indicesCount = this._toInstance * 6 - indicesOffset;
|
|
120
|
+
this._drawingMesh.applyChanges();
|
|
121
|
+
this._renderPipeline.render(
|
|
122
|
+
this._drawingMesh.vertexBuffer!,
|
|
123
|
+
this._drawingMesh.indexBuffer!,
|
|
124
|
+
indicesCount,
|
|
125
|
+
indicesOffset);
|
|
126
|
+
this._fromInstance = this._toInstance;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Call on frame end to handle any potential resize request.
|
|
131
|
+
*/
|
|
132
|
+
public frameEnd(): void {
|
|
133
|
+
if (this._needsResize) {
|
|
134
|
+
this._maxBatchSize *= 2;
|
|
135
|
+
this._drawingMesh.resize(this._maxBatchSize);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this._needsResize = false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** @inheritDoc */
|
|
142
|
+
public dispose(): void {
|
|
143
|
+
this._renderPipeline.dispose();
|
|
144
|
+
this._drawingMesh.dispose();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import type {vec2, vec3} from "gl-matrix";
|
|
2
|
+
import {BufferUsage, type Color, type IFramework, Mesh} from "ris-framework-api";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The sprite batch mesh.
|
|
6
|
+
*/
|
|
7
|
+
export class SpriteBatchMesh extends Mesh {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The number of floats components per vertex.
|
|
11
|
+
* 9 since it's build as (xyz rgba uv).
|
|
12
|
+
*/
|
|
13
|
+
static readonly TOTAL_FLOATS_PER_VERTEX = 9;
|
|
14
|
+
|
|
15
|
+
/** The total number of floats in a sprite. 4 for each vertex * 9 floats per vertex (xyz rgba uv). */
|
|
16
|
+
static readonly TOTAL_FLOATS_IN_SPRITE = 4 * this.TOTAL_FLOATS_PER_VERTEX;
|
|
17
|
+
|
|
18
|
+
private _maxInstances = 0;
|
|
19
|
+
private _lastIndex = -1;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The constructor for the batch sprite mesh.
|
|
23
|
+
*/
|
|
24
|
+
public constructor(framework: IFramework, numberOfInstances: number) {
|
|
25
|
+
super(framework);
|
|
26
|
+
this._maxInstances = numberOfInstances;
|
|
27
|
+
|
|
28
|
+
this._vertexData = new Array(this.maxInstances * SpriteBatchMesh.TOTAL_FLOATS_IN_SPRITE);
|
|
29
|
+
|
|
30
|
+
this._setupIndices();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private _setupIndices(): void {
|
|
34
|
+
const indices = [];
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < this.maxInstances; i++) {
|
|
37
|
+
// Indices
|
|
38
|
+
const indicesStartIndex = i * 4;
|
|
39
|
+
|
|
40
|
+
indices.push(indicesStartIndex + 2); // Bottom left.
|
|
41
|
+
indices.push(indicesStartIndex + 3); // Bottom right.
|
|
42
|
+
indices.push(indicesStartIndex + 1); // Top right.
|
|
43
|
+
indices.push(indicesStartIndex + 1); // Top right.
|
|
44
|
+
indices.push(indicesStartIndex + 0); // Top left.
|
|
45
|
+
indices.push(indicesStartIndex + 2); // Bottom left.
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this._indices = indices;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The maximum number of instances that can be batched. */
|
|
52
|
+
public get maxInstances() {
|
|
53
|
+
return this._maxInstances;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** @inheritDoc */
|
|
57
|
+
public override initialize(): void {
|
|
58
|
+
this._vertexBuffer = this._framework.bufferFactory.createVertexBuffer(
|
|
59
|
+
this._vertexData!,
|
|
60
|
+
this.maxInstances * 4,
|
|
61
|
+
BufferUsage.VERTEX | BufferUsage.COPY_DST,
|
|
62
|
+
"SpriteBatchMesh.VertexBuffer");
|
|
63
|
+
|
|
64
|
+
this._indexBuffer = this._framework.bufferFactory.createIndexBuffer(
|
|
65
|
+
this._indices!,
|
|
66
|
+
"SpriteBatchMesh.IndexBuffer");
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Resize the batch sprite mesh so that more instances can be drawn. */
|
|
71
|
+
public resize(newSize: number): void {
|
|
72
|
+
if (newSize == this.maxInstances) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this._maxInstances = newSize;
|
|
77
|
+
|
|
78
|
+
// Create new data.
|
|
79
|
+
const newData = new Array(this._maxInstances * SpriteBatchMesh.TOTAL_FLOATS_IN_SPRITE); // 36 due to 9(xyz rgba uv) * 4 vertices.
|
|
80
|
+
|
|
81
|
+
// Copy to new data.
|
|
82
|
+
newData.push(this._vertexData)
|
|
83
|
+
|
|
84
|
+
// Replace old data.
|
|
85
|
+
this._vertexData = newData;
|
|
86
|
+
|
|
87
|
+
this._setupIndices();
|
|
88
|
+
|
|
89
|
+
// Dispose of buffers.
|
|
90
|
+
this._vertexBuffer?.dispose();
|
|
91
|
+
this._indexBuffer?.dispose();
|
|
92
|
+
|
|
93
|
+
// Assign new buffers.
|
|
94
|
+
this.initialize();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** @inheritDoc */
|
|
98
|
+
public writeSprite(
|
|
99
|
+
instance: number,
|
|
100
|
+
position: vec3, size: vec2, color: Color,
|
|
101
|
+
u0 = 0, v0 = 0, u1 = 1, v1 = 1, flipY = false) {
|
|
102
|
+
if (flipY) {
|
|
103
|
+
v0 = 1;
|
|
104
|
+
v1 = 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let index = instance * SpriteBatchMesh.TOTAL_FLOATS_IN_SPRITE; // 36 due to 9 * 4 vertices.
|
|
108
|
+
|
|
109
|
+
// Top left.
|
|
110
|
+
this._vertexData![index++] = position[0]
|
|
111
|
+
this._vertexData![index++] = position[1];
|
|
112
|
+
this._vertexData![index++] = position[2];
|
|
113
|
+
this._vertexData![index++] = color.r;
|
|
114
|
+
this._vertexData![index++] = color.g;
|
|
115
|
+
this._vertexData![index++] = color.b;
|
|
116
|
+
this._vertexData![index++] = color.a;
|
|
117
|
+
this._vertexData![index++] = u0;
|
|
118
|
+
this._vertexData![index++] = v0;
|
|
119
|
+
|
|
120
|
+
// Top right.
|
|
121
|
+
this._vertexData![index++] = position[0] + size[0];
|
|
122
|
+
this._vertexData![index++] = position[1];
|
|
123
|
+
this._vertexData![index++] = position[2];
|
|
124
|
+
this._vertexData![index++] = color.r;
|
|
125
|
+
this._vertexData![index++] = color.g;
|
|
126
|
+
this._vertexData![index++] = color.b;
|
|
127
|
+
this._vertexData![index++] = color.a;
|
|
128
|
+
this._vertexData![index++] = u1;
|
|
129
|
+
this._vertexData![index++] = v0;
|
|
130
|
+
|
|
131
|
+
// Bottom left.
|
|
132
|
+
this._vertexData![index++] = position[0];
|
|
133
|
+
this._vertexData![index++] = position[1] + size[1];
|
|
134
|
+
this._vertexData![index++] = position[2];
|
|
135
|
+
this._vertexData![index++] = color.r;
|
|
136
|
+
this._vertexData![index++] = color.g;
|
|
137
|
+
this._vertexData![index++] = color.b;
|
|
138
|
+
this._vertexData![index++] = color.a;
|
|
139
|
+
this._vertexData![index++] = u0;
|
|
140
|
+
this._vertexData![index++] = v1;
|
|
141
|
+
|
|
142
|
+
// Bottom right.
|
|
143
|
+
this._vertexData![index++] = position[0] + size[0];
|
|
144
|
+
this._vertexData![index++] = position[1] + size[1];
|
|
145
|
+
this._vertexData![index++] = position[2];
|
|
146
|
+
this._vertexData![index++] = color.r;
|
|
147
|
+
this._vertexData![index++] = color.g;
|
|
148
|
+
this._vertexData![index++] = color.b;
|
|
149
|
+
this._vertexData![index++] = color.a;
|
|
150
|
+
this._vertexData![index++] = u1;
|
|
151
|
+
this._vertexData![index] = v1;
|
|
152
|
+
|
|
153
|
+
this._lastIndex = index;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
public void WriteSprite(int instance,
|
|
158
|
+
Vector3D<float> position,
|
|
159
|
+
Vector2D<float> size,
|
|
160
|
+
Color color,
|
|
161
|
+
float rotation, Vector2D<float> rotationOrigin,
|
|
162
|
+
float u0 = 0, float v0 = 0, float u1 = 1, float v1 = 1)
|
|
163
|
+
{
|
|
164
|
+
int index = instance * TOTAL_FLOATS_IN_SPRITE; // 36 due to 9 * 4 vertices.
|
|
165
|
+
|
|
166
|
+
Vector2D<float> topLeft = new(position.X, position.Y);
|
|
167
|
+
Vector2D<float> topRight = new(position.X + size.X, position.Y);
|
|
168
|
+
Vector2D<float> bottomLeft = new(position.X, position.Y + size.Y);
|
|
169
|
+
Vector2D<float> bottomRight = new(position.X + size.X, position.Y + size.Y);
|
|
170
|
+
|
|
171
|
+
if (rotation != 0)
|
|
172
|
+
{
|
|
173
|
+
Vector2D<float> rotationOriginOffset = new (
|
|
174
|
+
topLeft.X + rotationOrigin.X * size.X,
|
|
175
|
+
topLeft.Y + rotationOrigin.Y * size.Y);
|
|
176
|
+
|
|
177
|
+
topLeft.RotateSelfAroundPointCCW(rotationOriginOffset, rotation);
|
|
178
|
+
topRight.RotateSelfAroundPointCCW(rotationOriginOffset, rotation);
|
|
179
|
+
bottomLeft.RotateSelfAroundPointCCW(rotationOriginOffset, rotation);
|
|
180
|
+
bottomRight.RotateSelfAroundPointCCW(rotationOriginOffset, rotation);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Top left.
|
|
184
|
+
_vertexData[index++] = topLeft.X;
|
|
185
|
+
_vertexData[index++] = topLeft.Y;
|
|
186
|
+
_vertexData[index++] = position.Z;
|
|
187
|
+
_vertexData[index++] = color.R;
|
|
188
|
+
_vertexData[index++] = color.G;
|
|
189
|
+
_vertexData[index++] = color.B;
|
|
190
|
+
_vertexData[index++] = color.A;
|
|
191
|
+
_vertexData[index++] = u0;
|
|
192
|
+
_vertexData[index++] = v0;
|
|
193
|
+
|
|
194
|
+
// Top right.
|
|
195
|
+
_vertexData[index++] = topRight.X;
|
|
196
|
+
_vertexData[index++] = topRight.Y;
|
|
197
|
+
_vertexData[index++] = position.Z;
|
|
198
|
+
_vertexData[index++] = color.R;
|
|
199
|
+
_vertexData[index++] = color.G;
|
|
200
|
+
_vertexData[index++] = color.B;
|
|
201
|
+
_vertexData[index++] = color.A;
|
|
202
|
+
_vertexData[index++] = u1;
|
|
203
|
+
_vertexData[index++] = v0;
|
|
204
|
+
|
|
205
|
+
// Bottom left.
|
|
206
|
+
_vertexData[index++] = bottomLeft.X;
|
|
207
|
+
_vertexData[index++] = bottomLeft.Y;
|
|
208
|
+
_vertexData[index++] = position.Z;
|
|
209
|
+
_vertexData[index++] = color.R;
|
|
210
|
+
_vertexData[index++] = color.G;
|
|
211
|
+
_vertexData[index++] = color.B;
|
|
212
|
+
_vertexData[index++] = color.A;
|
|
213
|
+
_vertexData[index++] = u0;
|
|
214
|
+
_vertexData[index++] = v1;
|
|
215
|
+
|
|
216
|
+
// Bottom right.
|
|
217
|
+
_vertexData[index++] = bottomRight.X;
|
|
218
|
+
_vertexData[index++] = bottomRight.Y;
|
|
219
|
+
_vertexData[index++] = position.Z;
|
|
220
|
+
_vertexData[index++] = color.R;
|
|
221
|
+
_vertexData[index++] = color.G;
|
|
222
|
+
_vertexData[index++] = color.B;
|
|
223
|
+
_vertexData[index++] = color.A;
|
|
224
|
+
_vertexData[index++] = u1;
|
|
225
|
+
_vertexData[index] = v1;
|
|
226
|
+
}
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
/** @inheritDoc */
|
|
230
|
+
public override applyChanges(): void {
|
|
231
|
+
|
|
232
|
+
if(this._lastIndex <= 0)
|
|
233
|
+
{
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// TODO: update is way to large. U
|
|
238
|
+
|
|
239
|
+
// Update only to last index.
|
|
240
|
+
// Increment index by 1, since it's index, not a count.
|
|
241
|
+
this._vertexBuffer!.update(this._vertexData!, 0, this._lastIndex + 1);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { vec2 } from "gl-matrix";
|
|
2
|
+
import {WindowBounds, type IWindowManager} from "ris-framework-api";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The implementation of the IWindowManager interface.
|
|
6
|
+
*/
|
|
7
|
+
export class WindowManager implements IWindowManager {
|
|
8
|
+
private readonly _canvas: HTMLCanvasElement;
|
|
9
|
+
private readonly _updateCallbacks: Array<() => void> = [];
|
|
10
|
+
private readonly _renderCallbacks: Array<() => void> = [];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The constructor for the WindowManager class.
|
|
14
|
+
* @param canvas An optional HTMLCanvasElement to associate with the window manager. If <c>null</c>, window manager will create its own canvas.
|
|
15
|
+
*/
|
|
16
|
+
public constructor(canvas: HTMLCanvasElement | null = null) {
|
|
17
|
+
this._canvas = canvas ?? document.createElement("canvas");
|
|
18
|
+
if (!canvas) {
|
|
19
|
+
document.body.appendChild(this._canvas);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
handleSwapChain = true;
|
|
24
|
+
windowBounds = new WindowBounds();
|
|
25
|
+
title = "";
|
|
26
|
+
addUpdateListener(event: () => void): void {
|
|
27
|
+
this._updateCallbacks.push(event);
|
|
28
|
+
}
|
|
29
|
+
removeUpdateListener(event: () => void): void {
|
|
30
|
+
const index = this._updateCallbacks.indexOf(event);
|
|
31
|
+
if (index >= 0) {
|
|
32
|
+
this._updateCallbacks.splice(index, 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
addRenderListener(event: () => void): void {
|
|
36
|
+
this._renderCallbacks.push(event);
|
|
37
|
+
}
|
|
38
|
+
removeRenderListener(event: () => void): void {
|
|
39
|
+
const index = this._renderCallbacks.indexOf(event);
|
|
40
|
+
if (index >= 0) {
|
|
41
|
+
this._renderCallbacks.splice(index, 1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
addOnResizeListener(_event: (arg1: IWindowManager, arg2: vec2) => void): void {
|
|
45
|
+
throw new Error("Method not implemented.");
|
|
46
|
+
}
|
|
47
|
+
removeOnResizeListener(_event: (arg1: IWindowManager, arg2: vec2) => void): void {
|
|
48
|
+
throw new Error("Method not implemented.");
|
|
49
|
+
}
|
|
50
|
+
initializeForWebGPU(): void {
|
|
51
|
+
throw new Error("Method not implemented.");
|
|
52
|
+
}
|
|
53
|
+
initializeForWebGl(): void {
|
|
54
|
+
throw new Error("Method not implemented.");
|
|
55
|
+
}
|
|
56
|
+
dispose(): void {
|
|
57
|
+
throw new Error("Method not implemented.");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @inheritdoc */
|
|
61
|
+
runEventLoop(): void {
|
|
62
|
+
for (const callback of this._updateCallbacks) {
|
|
63
|
+
callback();
|
|
64
|
+
}
|
|
65
|
+
for (const callback of this._renderCallbacks) {
|
|
66
|
+
callback();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
requestAnimationFrame(() => this.runEventLoop());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @inheritdoc */
|
|
73
|
+
public get canvas(): HTMLCanvasElement {
|
|
74
|
+
return this._canvas;
|
|
75
|
+
}
|
|
76
|
+
}
|
package/src/counter.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function setupCounter(element: HTMLButtonElement) {
|
|
2
|
+
let counter = 0
|
|
3
|
+
const setCounter = (count: number) => {
|
|
4
|
+
counter = count
|
|
5
|
+
element.innerHTML = `count is ${counter}`
|
|
6
|
+
}
|
|
7
|
+
element.addEventListener('click', () => setCounter(counter + 1))
|
|
8
|
+
setCounter(0)
|
|
9
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { GeometryFormat } from "./GeometryFormat.ts";
|
|
2
|
+
import {VertexFormat} from "../VertexFormat.ts";
|
|
3
|
+
import type {IGeometry} from "ris-framework-api";
|
|
4
|
+
|
|
5
|
+
export class BaseGeometry implements IGeometry {
|
|
6
|
+
|
|
7
|
+
/** @inheritdoc */
|
|
8
|
+
public vertexCount: number = 0;
|
|
9
|
+
|
|
10
|
+
/** @inheritdoc */
|
|
11
|
+
public positions?: number[];
|
|
12
|
+
|
|
13
|
+
/** @inheritdoc */
|
|
14
|
+
public positionsFormat: VertexFormat = VertexFormat.FLOAT_32X3;
|
|
15
|
+
|
|
16
|
+
/** @inheritdoc */
|
|
17
|
+
public colors?: number[];
|
|
18
|
+
|
|
19
|
+
/** @inheritdoc */
|
|
20
|
+
public colorFormat: VertexFormat = VertexFormat.FLOAT_32X4;
|
|
21
|
+
|
|
22
|
+
/** @inheritdoc */
|
|
23
|
+
public textureCoords?: number[];
|
|
24
|
+
|
|
25
|
+
/** @inheritdoc */
|
|
26
|
+
public textureFormat: VertexFormat = VertexFormat.FLOAT_32X2;
|
|
27
|
+
|
|
28
|
+
/** @inheritdoc */
|
|
29
|
+
public normals?: number[];
|
|
30
|
+
|
|
31
|
+
/** @inheritdoc */
|
|
32
|
+
public normalsFormat: VertexFormat = VertexFormat.FLOAT_32X3;
|
|
33
|
+
|
|
34
|
+
/** The indices of geometry. */
|
|
35
|
+
public indices?: number[];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Pushes vertex data from source format to destination format.
|
|
39
|
+
* @param index The index of the vertex to push.
|
|
40
|
+
* @param source The source vertex data.
|
|
41
|
+
* @param sourceFormat The vertex format of the source vertex data.
|
|
42
|
+
* @param destination The destination array to push the vertex data to.
|
|
43
|
+
* @param destinationFormat The vertex format of the destination vertex data.
|
|
44
|
+
*/
|
|
45
|
+
private pushFormat(index: number,
|
|
46
|
+
source: number[],
|
|
47
|
+
sourceFormat: VertexFormat,
|
|
48
|
+
destination: number[],
|
|
49
|
+
destinationFormat: VertexFormat) {
|
|
50
|
+
// This simply takes the source format and pushes new vertices to the destination format.
|
|
51
|
+
// If the source format is less than destination, 0 is being pushed in its place.
|
|
52
|
+
let _0 = 0;
|
|
53
|
+
let _1 = 0;
|
|
54
|
+
let _2 = 0;
|
|
55
|
+
let _3 = 0;
|
|
56
|
+
|
|
57
|
+
if (sourceFormat == VertexFormat.FLOAT_32) {
|
|
58
|
+
_0 = source[index];
|
|
59
|
+
}
|
|
60
|
+
else if (sourceFormat == VertexFormat.FLOAT_32X2) {
|
|
61
|
+
_0 = source[index * 2];
|
|
62
|
+
_1 = source[index * 2 + 1];
|
|
63
|
+
}
|
|
64
|
+
else if (sourceFormat == VertexFormat.FLOAT_32X3) {
|
|
65
|
+
_0 = source[index * 3];
|
|
66
|
+
_1 = source[index * 3 + 1];
|
|
67
|
+
_2 = source[index * 3 + 2];
|
|
68
|
+
}
|
|
69
|
+
else if (sourceFormat == VertexFormat.FLOAT_32X4) {
|
|
70
|
+
_0 = source[index * 4];
|
|
71
|
+
_1 = source[index * 4 + 1];
|
|
72
|
+
_2 = source[index * 4 + 2];
|
|
73
|
+
_3 = source[index * 4 + 3];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
destination.push(_0);
|
|
77
|
+
if (destinationFormat >= VertexFormat.FLOAT_32X2) {
|
|
78
|
+
destination.push(_1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (destinationFormat >= VertexFormat.FLOAT_32X3) {
|
|
82
|
+
destination.push(_2);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (destinationFormat >= VertexFormat.FLOAT_32X4) {
|
|
86
|
+
destination.push(_3);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converts the geometry data to interleaved vertex data based on the specified geometry format.
|
|
92
|
+
* @param format The geometry format to convert the geometry data to.
|
|
93
|
+
* @returns The interleaved vertex data as an array of numbers.
|
|
94
|
+
*/
|
|
95
|
+
public toInterleaved(format: GeometryFormat): number[] {
|
|
96
|
+
let interleavedData: number[] = [];
|
|
97
|
+
|
|
98
|
+
switch (format) {
|
|
99
|
+
case GeometryFormat.POS3_TEXTURECOORDS2:
|
|
100
|
+
{
|
|
101
|
+
let count = this.positions!.length / 3;
|
|
102
|
+
|
|
103
|
+
for (let i = 0; i < count; i++) {
|
|
104
|
+
this.pushFormat(i, this.positions!, VertexFormat.FLOAT_32X3, interleavedData, VertexFormat.FLOAT_32X3);
|
|
105
|
+
this.pushFormat(i, this.textureCoords!, VertexFormat.FLOAT_32X2, interleavedData, VertexFormat.FLOAT_32X2);
|
|
106
|
+
}
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case GeometryFormat.POS3_COLOR4_TEXTURECOORDS2:
|
|
110
|
+
{
|
|
111
|
+
let count = this.positions!.length / 3;
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < count; i++) {
|
|
114
|
+
this.pushFormat(i, this.positions!, VertexFormat.FLOAT_32X3, interleavedData, VertexFormat.FLOAT_32X3);
|
|
115
|
+
this.pushFormat(i, this.colors!, VertexFormat.FLOAT_32X4, interleavedData, VertexFormat.FLOAT_32X4);
|
|
116
|
+
this.pushFormat(i, this.textureCoords!, VertexFormat.FLOAT_32X2, interleavedData, VertexFormat.FLOAT_32X2);
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case GeometryFormat.POS3_COLOR4_TEXTURECOORDS2_NORMAL3:
|
|
121
|
+
{
|
|
122
|
+
let count = this.positions!.length / 3;
|
|
123
|
+
|
|
124
|
+
for (let i = 0; i < count; i++) {
|
|
125
|
+
this.pushFormat(i, this.positions!, VertexFormat.FLOAT_32X3, interleavedData, VertexFormat.FLOAT_32X3);
|
|
126
|
+
this.pushFormat(i, this.colors!, VertexFormat.FLOAT_32X4, interleavedData, VertexFormat.FLOAT_32X4);
|
|
127
|
+
this.pushFormat(i, this.textureCoords!, VertexFormat.FLOAT_32X2, interleavedData, VertexFormat.FLOAT_32X2);
|
|
128
|
+
this.pushFormat(i, this.normals!, VertexFormat.FLOAT_32X3, interleavedData, VertexFormat.FLOAT_32X3);
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case GeometryFormat.POS3_COLOR4_TEXTURECOORDS2_ALIGNED:
|
|
133
|
+
{
|
|
134
|
+
let count = this.positions!.length / 3;
|
|
135
|
+
|
|
136
|
+
for (let i = 0; i < count; i++) {
|
|
137
|
+
this.pushFormat(i, this.positions!, VertexFormat.FLOAT_32X3, interleavedData, VertexFormat.FLOAT_32X4);
|
|
138
|
+
this.pushFormat(i, this.colors!, VertexFormat.FLOAT_32X4, interleavedData, VertexFormat.FLOAT_32X4);
|
|
139
|
+
this.pushFormat(i, this.textureCoords!, VertexFormat.FLOAT_32X2, interleavedData, VertexFormat.FLOAT_32X4);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
return interleavedData;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { vec2 } from "gl-matrix"
|
|
2
|
+
import { BaseGeometry } from "./BaseGeometry.ts";
|
|
3
|
+
import type {IGeometry, IGeometryBuilder} from "ris-framework-api";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The GeometryBuilder class provides methods for creating various types of geometries, such as quads, with specified parameters like scale and winding order.
|
|
7
|
+
*/
|
|
8
|
+
export class GeometryBuilder implements IGeometryBuilder {
|
|
9
|
+
|
|
10
|
+
static DEFAULT_SCALE = vec2.fromValues(1,1);
|
|
11
|
+
|
|
12
|
+
/** @inheritdoc */
|
|
13
|
+
public quadGeometry(scale?: vec2 | null, counterClockwise: boolean = true): IGeometry {
|
|
14
|
+
|
|
15
|
+
scale = scale ?? GeometryBuilder.DEFAULT_SCALE;
|
|
16
|
+
|
|
17
|
+
const geometry = new BaseGeometry();
|
|
18
|
+
geometry.vertexCount = 4;
|
|
19
|
+
geometry.positions = [
|
|
20
|
+
-0.5 * scale[0], -0.5 * scale[1], 0.0, // bottom left
|
|
21
|
+
-0.5 * scale[0], 0.5 * scale[1], 0.0, // top left
|
|
22
|
+
0.5 * scale[0], -0.5 * scale[1], 0.0, // bottom right
|
|
23
|
+
0.5 * scale[0], 0.5 * scale[1], 0.0, // top right
|
|
24
|
+
];
|
|
25
|
+
if (counterClockwise) {
|
|
26
|
+
geometry.indices = [
|
|
27
|
+
2, 3, 1, // t1
|
|
28
|
+
1, 0, 2 // t2
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
geometry.indices = [
|
|
33
|
+
1, 3, 2, // t1
|
|
34
|
+
2, 0, 1 // t2
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
geometry.colors = [
|
|
38
|
+
1, 1, 1, 1,
|
|
39
|
+
1, 1, 1, 1,
|
|
40
|
+
1, 1, 1, 1,
|
|
41
|
+
1, 1, 1, 1
|
|
42
|
+
];
|
|
43
|
+
geometry.textureCoords = [
|
|
44
|
+
0, 1, // bottom left
|
|
45
|
+
0, 0, // top left
|
|
46
|
+
1, 1, // bottom right
|
|
47
|
+
1, 0 // top right
|
|
48
|
+
];
|
|
49
|
+
geometry.normals = [
|
|
50
|
+
0, 0, 1,
|
|
51
|
+
0, 0, 1,
|
|
52
|
+
0, 0, 1,
|
|
53
|
+
0, 0, 1,
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
return geometry;
|
|
57
|
+
}
|
|
58
|
+
}
|