ris-framework 0.1.0-dev.9 → 0.2.0-dev.11

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.
Files changed (217) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +15 -4
  3. package/dist/Framework.d.ts +9 -3
  4. package/dist/Framework.d.ts.map +1 -1
  5. package/dist/api/IFramework.d.ts +7 -6
  6. package/dist/api/IFramework.d.ts.map +1 -1
  7. package/dist/api/_export.d.ts +2 -0
  8. package/dist/api/_export.d.ts.map +1 -1
  9. package/dist/api/camera/CameraFactory.d.ts +3 -2
  10. package/dist/api/camera/CameraFactory.d.ts.map +1 -1
  11. package/dist/api/camera/ICamera.d.ts +5 -0
  12. package/dist/api/camera/ICamera.d.ts.map +1 -1
  13. package/dist/api/camera/ICameraFactory.d.ts +5 -6
  14. package/dist/api/camera/ICameraFactory.d.ts.map +1 -1
  15. package/dist/api/camera/OrthographicCamera.d.ts +7 -0
  16. package/dist/api/camera/OrthographicCamera.d.ts.map +1 -1
  17. package/dist/api/camera/PerspectiveCamera.d.ts +30 -6
  18. package/dist/api/camera/PerspectiveCamera.d.ts.map +1 -1
  19. package/dist/api/content/ContentManager.d.ts +67 -2
  20. package/dist/api/content/ContentManager.d.ts.map +1 -1
  21. package/dist/api/content/IContentManager.d.ts +32 -1
  22. package/dist/api/content/IContentManager.d.ts.map +1 -1
  23. package/dist/api/content/ShaderModuleContent.d.ts.map +1 -1
  24. package/dist/api/data/Color.d.ts +5 -0
  25. package/dist/api/data/Color.d.ts.map +1 -1
  26. package/dist/api/geometry/BaseGeometry.d.ts +9 -0
  27. package/dist/api/geometry/BaseGeometry.d.ts.map +1 -1
  28. package/dist/api/geometry/GeometryBuilder.d.ts +3 -1
  29. package/dist/api/geometry/GeometryBuilder.d.ts.map +1 -1
  30. package/dist/api/geometry/IGeometryBuilder.d.ts +24 -0
  31. package/dist/api/geometry/IGeometryBuilder.d.ts.map +1 -1
  32. package/dist/api/geometry/_export-geometry.d.ts +1 -0
  33. package/dist/api/geometry/_export-geometry.d.ts.map +1 -1
  34. package/dist/api/input/InputManager.d.ts +4 -0
  35. package/dist/api/input/InputManager.d.ts.map +1 -1
  36. package/dist/api/lights/AmbientLight.d.ts +35 -0
  37. package/dist/api/lights/AmbientLight.d.ts.map +1 -0
  38. package/dist/api/lights/DirectionalLight.d.ts +40 -0
  39. package/dist/api/lights/DirectionalLight.d.ts.map +1 -0
  40. package/dist/api/lights/LightFactory.d.ts +18 -0
  41. package/dist/api/lights/LightFactory.d.ts.map +1 -0
  42. package/dist/api/lights/LightId.d.ts +6 -0
  43. package/dist/api/lights/LightId.d.ts.map +1 -0
  44. package/dist/api/lights/LightsBuffer.d.ts +70 -0
  45. package/dist/api/lights/LightsBuffer.d.ts.map +1 -0
  46. package/dist/api/lights/PointLight.d.ts +59 -0
  47. package/dist/api/lights/PointLight.d.ts.map +1 -0
  48. package/dist/api/lights/_export.d.ts +6 -0
  49. package/dist/api/lights/_export.d.ts.map +1 -0
  50. package/dist/api/loaders/ObjGeometryMapper.d.ts +19 -0
  51. package/dist/api/loaders/ObjGeometryMapper.d.ts.map +1 -0
  52. package/dist/api/loaders/_export.d.ts +1 -0
  53. package/dist/api/loaders/_export.d.ts.map +1 -1
  54. package/dist/api/loaders/obj/ObjLoader.d.ts +29 -0
  55. package/dist/api/loaders/obj/ObjLoader.d.ts.map +1 -0
  56. package/dist/api/loaders/obj/ObjTypes.d.ts +103 -0
  57. package/dist/api/loaders/obj/ObjTypes.d.ts.map +1 -0
  58. package/dist/api/loaders/obj/index.d.ts +3 -0
  59. package/dist/api/loaders/obj/index.d.ts.map +1 -0
  60. package/dist/api/material/ForwardBlinnPhongMaterial.d.ts +127 -0
  61. package/dist/api/material/ForwardBlinnPhongMaterial.d.ts.map +1 -0
  62. package/dist/api/material/IMaterial.d.ts +15 -6
  63. package/dist/api/material/IMaterial.d.ts.map +1 -1
  64. package/dist/api/material/IMaterialFactory.d.ts +17 -2
  65. package/dist/api/material/IMaterialFactory.d.ts.map +1 -1
  66. package/dist/api/material/InspectTextureMipsMaterial.d.ts +16 -7
  67. package/dist/api/material/InspectTextureMipsMaterial.d.ts.map +1 -1
  68. package/dist/api/material/MaterialFactory.d.ts +6 -0
  69. package/dist/api/material/MaterialFactory.d.ts.map +1 -1
  70. package/dist/api/material/SpriteMaterial.d.ts +51 -0
  71. package/dist/api/material/SpriteMaterial.d.ts.map +1 -0
  72. package/dist/api/material/UnlitMaterial.d.ts +28 -10
  73. package/dist/api/material/UnlitMaterial.d.ts.map +1 -1
  74. package/dist/api/material/_export.d.ts +2 -0
  75. package/dist/api/material/_export.d.ts.map +1 -1
  76. package/dist/api/meshes/IMesh.d.ts +35 -5
  77. package/dist/api/meshes/IMesh.d.ts.map +1 -1
  78. package/dist/api/meshes/IMeshFactory.d.ts +25 -4
  79. package/dist/api/meshes/IMeshFactory.d.ts.map +1 -1
  80. package/dist/api/meshes/Mesh.d.ts +58 -6
  81. package/dist/api/meshes/Mesh.d.ts.map +1 -1
  82. package/dist/api/meshes/MeshFactory.d.ts +7 -3
  83. package/dist/api/meshes/MeshFactory.d.ts.map +1 -1
  84. package/dist/api/meshes/QuadMesh.d.ts +5 -1
  85. package/dist/api/meshes/QuadMesh.d.ts.map +1 -1
  86. package/dist/api/meshes/SubMesh.d.ts +47 -0
  87. package/dist/api/meshes/SubMesh.d.ts.map +1 -0
  88. package/dist/api/meshes/_export.d.ts +1 -0
  89. package/dist/api/meshes/_export.d.ts.map +1 -1
  90. package/dist/api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.d.ts +56 -0
  91. package/dist/api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.d.ts.map +1 -0
  92. package/dist/api/rendering/render-pipelines/IRenderPipeline.d.ts +3 -0
  93. package/dist/api/rendering/render-pipelines/IRenderPipeline.d.ts.map +1 -1
  94. package/dist/api/rendering/render-pipelines/IRenderPipelineFactory.d.ts +29 -0
  95. package/dist/api/rendering/render-pipelines/IRenderPipelineFactory.d.ts.map +1 -1
  96. package/dist/api/rendering/render-pipelines/_export-render-pipelines.d.ts +1 -0
  97. package/dist/api/rendering/render-pipelines/_export-render-pipelines.d.ts.map +1 -1
  98. package/dist/api/scene/Scene.d.ts +104 -0
  99. package/dist/api/scene/Scene.d.ts.map +1 -0
  100. package/dist/api/shader/IShaderModuleLoader.d.ts +4 -1
  101. package/dist/api/shader/IShaderModuleLoader.d.ts.map +1 -1
  102. package/dist/api/shader/{shader-loader.d.ts → ShaderLoader.d.ts} +1 -1
  103. package/dist/api/shader/ShaderLoader.d.ts.map +1 -0
  104. package/dist/api/sprites/SpriteBatchDrawable.d.ts +1 -1
  105. package/dist/api/sprites/SpriteBatchDrawable.d.ts.map +1 -1
  106. package/dist/api/sprites/SpriteBatchMesh.d.ts +14 -1
  107. package/dist/api/sprites/SpriteBatchMesh.d.ts.map +1 -1
  108. package/dist/api/utilities/GeometryUtilities.d.ts.map +1 -1
  109. package/dist/api/window/WindowManager.d.ts +4 -0
  110. package/dist/api/window/WindowManager.d.ts.map +1 -1
  111. package/dist/core/rendering/vertex-buffer-layout.d.ts +1 -0
  112. package/dist/core/rendering/vertex-buffer-layout.d.ts.map +1 -1
  113. package/dist/index.js +2252 -260
  114. package/dist/webgl/WebGlGraphicsDevice.d.ts.map +1 -1
  115. package/dist/webgl/lights/WebGlAmbientLightFactory.d.ts +17 -0
  116. package/dist/webgl/lights/WebGlAmbientLightFactory.d.ts.map +1 -0
  117. package/dist/webgl/lights/WebGlLightsBuffer.d.ts +55 -0
  118. package/dist/webgl/lights/WebGlLightsBuffer.d.ts.map +1 -0
  119. package/dist/webgl/render-pipelines/AWebGlRenderPipeline.d.ts +3 -1
  120. package/dist/webgl/render-pipelines/AWebGlRenderPipeline.d.ts.map +1 -1
  121. package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts +3 -0
  122. package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts.map +1 -1
  123. package/dist/webgl/render-pipelines/WebGlRenderPipelineFactory.d.ts +3 -1
  124. package/dist/webgl/render-pipelines/WebGlRenderPipelineFactory.d.ts.map +1 -1
  125. package/dist/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.d.ts +3 -1
  126. package/dist/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.d.ts.map +1 -1
  127. package/dist/webgl/render-pipelines/material/WebGlBlinnPhongRenderPipeline.d.ts +88 -0
  128. package/dist/webgl/render-pipelines/material/WebGlBlinnPhongRenderPipeline.d.ts.map +1 -0
  129. package/dist/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.d.ts +3 -1
  130. package/dist/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.d.ts.map +1 -1
  131. package/dist/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.d.ts +3 -1
  132. package/dist/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.d.ts.map +1 -1
  133. package/dist/webgl/shader/WebGlShaderModule.d.ts +4 -1
  134. package/dist/webgl/shader/WebGlShaderModule.d.ts.map +1 -1
  135. package/dist/webgl/shader/WebGlShaderModuleLoader.d.ts +16 -5
  136. package/dist/webgl/shader/WebGlShaderModuleLoader.d.ts.map +1 -1
  137. package/dist/webgl/texture/WebGlTexture2D.d.ts +8 -1
  138. package/dist/webgl/texture/WebGlTexture2D.d.ts.map +1 -1
  139. package/dist/webgl/utilities/webgl-filter-anisotropic-utilities.d.ts +0 -1
  140. package/dist/webgl/utilities/webgl-filter-anisotropic-utilities.d.ts.map +1 -1
  141. package/package.json +4 -4
  142. package/shaders/glsl/forward_blinn_phong_material_fs.glsl +110 -0
  143. package/shaders/glsl/forward_blinn_phong_material_vs.glsl +32 -0
  144. package/shaders/glsl/sprite_fs.glsl +1 -1
  145. package/shaders/glsl/unlit_material_fs.glsl +1 -1
  146. package/src/Framework.ts +37 -13
  147. package/src/api/IFramework.ts +8 -6
  148. package/src/api/_export.ts +2 -0
  149. package/src/api/camera/CameraFactory.ts +6 -6
  150. package/src/api/camera/ICamera.ts +6 -0
  151. package/src/api/camera/ICameraFactory.ts +5 -10
  152. package/src/api/camera/OrthographicCamera.ts +23 -1
  153. package/src/api/camera/PerspectiveCamera.ts +60 -15
  154. package/src/api/content/ContentManager.ts +201 -5
  155. package/src/api/content/IContentManager.ts +33 -1
  156. package/src/api/content/ShaderModuleContent.ts +9 -0
  157. package/src/api/data/Color.ts +7 -1
  158. package/src/api/geometry/BaseGeometry.ts +23 -0
  159. package/src/api/geometry/GeometryBuilder.ts +14 -2
  160. package/src/api/geometry/IGeometryBuilder.ts +31 -1
  161. package/src/api/geometry/_export-geometry.ts +2 -1
  162. package/src/api/input/InputManager.ts +14 -5
  163. package/src/api/lights/AmbientLight.ts +53 -0
  164. package/src/api/lights/DirectionalLight.ts +60 -0
  165. package/src/api/lights/LightFactory.ts +21 -0
  166. package/src/api/lights/LightId.ts +9 -0
  167. package/src/api/lights/LightsBuffer.ts +87 -0
  168. package/src/api/lights/PointLight.ts +91 -0
  169. package/src/api/lights/_export.ts +5 -0
  170. package/src/api/loaders/ObjGeometryMapper.ts +28 -0
  171. package/src/api/loaders/_export.ts +2 -1
  172. package/src/api/loaders/obj/ObjLoader.ts +270 -0
  173. package/src/api/loaders/obj/ObjTypes.ts +124 -0
  174. package/src/api/loaders/obj/index.ts +5 -0
  175. package/src/api/material/ForwardBlinnPhongMaterial.ts +302 -0
  176. package/src/api/material/IMaterial.ts +16 -6
  177. package/src/api/material/IMaterialFactory.ts +19 -2
  178. package/src/api/material/InspectTextureMipsMaterial.ts +63 -24
  179. package/src/api/material/MaterialFactory.ts +12 -0
  180. package/src/api/material/SpriteMaterial.ts +83 -0
  181. package/src/api/material/UnlitMaterial.ts +101 -29
  182. package/src/api/material/_export.ts +3 -1
  183. package/src/api/meshes/IMesh.ts +45 -6
  184. package/src/api/meshes/IMeshFactory.ts +27 -4
  185. package/src/api/meshes/Mesh.ts +163 -41
  186. package/src/api/meshes/MeshFactory.ts +30 -6
  187. package/src/api/meshes/QuadMesh.ts +6 -2
  188. package/src/api/meshes/SubMesh.ts +71 -0
  189. package/src/api/meshes/_export.ts +1 -0
  190. package/src/api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.ts +66 -0
  191. package/src/api/rendering/render-pipelines/IRenderPipeline.ts +4 -0
  192. package/src/api/rendering/render-pipelines/IRenderPipelineFactory.ts +39 -0
  193. package/src/api/rendering/render-pipelines/_export-render-pipelines.ts +2 -1
  194. package/src/api/scene/Scene.ts +264 -0
  195. package/src/api/shader/IShaderModuleLoader.ts +2 -1
  196. package/src/api/sprites/SpriteBatchDrawable.ts +12 -16
  197. package/src/api/sprites/SpriteBatchMesh.ts +23 -4
  198. package/src/api/utilities/GeometryUtilities.ts +2 -0
  199. package/src/api/window/WindowManager.ts +22 -2
  200. package/src/core/rendering/vertex-buffer-layout.ts +32 -1
  201. package/src/main.ts +0 -1
  202. package/src/webgl/WebGlGraphicsDevice.ts +0 -1
  203. package/src/webgl/lights/WebGlAmbientLightFactory.ts +35 -0
  204. package/src/webgl/lights/WebGlLightsBuffer.ts +215 -0
  205. package/src/webgl/render-pipelines/AWebGlRenderPipeline.ts +7 -1
  206. package/src/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.ts +3 -0
  207. package/src/webgl/render-pipelines/WebGlRenderPipelineFactory.ts +24 -2
  208. package/src/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.ts +16 -6
  209. package/src/webgl/render-pipelines/material/WebGlBlinnPhongRenderPipeline.ts +300 -0
  210. package/src/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.ts +16 -6
  211. package/src/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.ts +11 -7
  212. package/src/webgl/shader/WebGlShaderModule.ts +11 -4
  213. package/src/webgl/shader/WebGlShaderModuleLoader.ts +29 -10
  214. package/src/webgl/texture/WebGlTexture2D.ts +19 -5
  215. package/src/webgl/utilities/webgl-filter-anisotropic-utilities.ts +9 -6
  216. package/dist/api/shader/shader-loader.d.ts.map +0 -1
  217. /package/src/api/shader/{shader-loader.ts → ShaderLoader.ts} +0 -0
@@ -1,5 +1,6 @@
1
1
  import type {vec2, vec3} from "gl-matrix";
2
2
  import {BufferUsage, type Color, type IFramework, Mesh} from "../index.ts";
3
+ import type {SpriteMaterial} from "../material/SpriteMaterial.ts";
3
4
 
4
5
  /**
5
6
  * The sprite batch mesh.
@@ -15,14 +16,26 @@ export class SpriteBatchMesh extends Mesh {
15
16
  /** The total number of floats in a sprite. 4 for each vertex * 9 floats per vertex (xyz rgba uv). */
16
17
  static readonly TOTAL_FLOATS_IN_SPRITE = 4 * this.TOTAL_FLOATS_PER_VERTEX;
17
18
 
19
+ private readonly _spriteMaterial: SpriteMaterial;
18
20
  private _maxInstances = 0;
19
21
  private _lastIndex = -1;
20
22
 
23
+ /** The offset of the first index to draw. Defaults to 0. */
24
+ public indicesOffset = 0;
25
+
26
+ /** The number of indices to draw. If -1 draws all indices. */
27
+ public indicesCount = -1;
28
+
21
29
  /**
22
30
  * The constructor for the batch sprite mesh.
31
+ * @param framework - The framework.
32
+ * @param material - The material.
33
+ * @param numberOfInstances - The number of instances.
23
34
  */
24
- public constructor(framework: IFramework, numberOfInstances: number) {
25
- super(framework);
35
+ public constructor(framework: IFramework, material: SpriteMaterial, numberOfInstances: number) {
36
+ // Drawn by the sprite batch, not by a scene.
37
+ super(framework, null, material);
38
+ this._spriteMaterial = material;
26
39
  this._maxInstances = numberOfInstances;
27
40
 
28
41
  this._vertexData = new Array(this.maxInstances * SpriteBatchMesh.TOTAL_FLOATS_IN_SPRITE);
@@ -48,6 +61,13 @@ export class SpriteBatchMesh extends Mesh {
48
61
  this._indices = indices;
49
62
  }
50
63
 
64
+ /**
65
+ * Draws the mesh with its sprite material, using {@link indicesCount} and {@link indicesOffset}.
66
+ */
67
+ public draw(): void {
68
+ this._spriteMaterial.render(this._vertexBuffer!, this._indexBuffer!, this.indicesCount, this.indicesOffset);
69
+ }
70
+
51
71
  /** The maximum number of instances that can be batched. */
52
72
  public get maxInstances() {
53
73
  return this._maxInstances;
@@ -233,8 +253,7 @@ export class SpriteBatchMesh extends Mesh {
233
253
  /** @inheritDoc */
234
254
  public override applyChanges(): void {
235
255
 
236
- if(this._lastIndex <= 0)
237
- {
256
+ if (this._lastIndex <= 0) {
238
257
  return;
239
258
  }
240
259
 
@@ -13,6 +13,8 @@ export class GeometryUtilities {
13
13
  switch (geometryFormat) {
14
14
  case GeometryFormat.POS3_COLOR4_TEXTURECOORDS2:
15
15
  return (3 + 4 + 2) * Float32Array.BYTES_PER_ELEMENT;
16
+ case GeometryFormat.POS3_COLOR4_TEXTURECOORDS2_NORMAL3:
17
+ return (3 + 4 + 2 + 3) * Float32Array.BYTES_PER_ELEMENT;
16
18
  default:
17
19
  throw new Error("Unknown geometryFormat");
18
20
  }
@@ -8,6 +8,9 @@ export class WindowManager implements IWindowManager {
8
8
  private readonly _canvas: HTMLCanvasElement;
9
9
  private readonly _updateCallbacks: Array<() => void> = [];
10
10
  private readonly _renderCallbacks: Array<() => void> = [];
11
+ private readonly _ownsCanvas: boolean;
12
+ private _animationFrame: number | null = null;
13
+ private _disposed = false;
11
14
 
12
15
  /**
13
16
  * The constructor for the WindowManager class.
@@ -15,6 +18,7 @@ export class WindowManager implements IWindowManager {
15
18
  */
16
19
  public constructor(canvas: HTMLCanvasElement | null = null) {
17
20
  this._canvas = canvas ?? document.createElement("canvas");
21
+ this._ownsCanvas = !canvas;
18
22
  if (!canvas) {
19
23
  document.body.appendChild(this._canvas);
20
24
  }
@@ -53,12 +57,28 @@ export class WindowManager implements IWindowManager {
53
57
  initializeForWebGl(): void {
54
58
  throw new Error("Method not implemented.");
55
59
  }
60
+ /** Stops the event loop, drops all callbacks and removes the canvas when this manager created it. */
56
61
  dispose(): void {
57
- throw new Error("Method not implemented.");
62
+ if (this._disposed) {
63
+ return;
64
+ }
65
+ this._disposed = true;
66
+ if (this._animationFrame !== null) {
67
+ cancelAnimationFrame(this._animationFrame);
68
+ this._animationFrame = null;
69
+ }
70
+ this._updateCallbacks.length = 0;
71
+ this._renderCallbacks.length = 0;
72
+ if (this._ownsCanvas) {
73
+ this._canvas.remove();
74
+ }
58
75
  }
59
76
 
60
77
  /** @inheritdoc */
61
78
  runEventLoop(): void {
79
+ if (this._disposed) {
80
+ return;
81
+ }
62
82
  for (const callback of this._updateCallbacks) {
63
83
  callback();
64
84
  }
@@ -66,7 +86,7 @@ export class WindowManager implements IWindowManager {
66
86
  callback();
67
87
  }
68
88
 
69
- requestAnimationFrame(() => this.runEventLoop());
89
+ this._animationFrame = requestAnimationFrame(() => this.runEventLoop());
70
90
  }
71
91
 
72
92
  /** @inheritdoc */
@@ -80,4 +80,35 @@ export class VertexBufferLayout implements IVertexBufferLayout {
80
80
  ]
81
81
  );
82
82
  }
83
- }
83
+
84
+ static createFloat3Float4Float2Float3Layout(): VertexBufferLayout {
85
+ const floatSize = 4;
86
+
87
+ return new VertexBufferLayout(
88
+ (3 + 4 + 2 + 3) * floatSize,
89
+ VertexStepMode.VERTEX,
90
+ [
91
+ {
92
+ format: VertexFormat.FLOAT_32X3,
93
+ offset: 0,
94
+ shaderLocation: 0,
95
+ },
96
+ {
97
+ format: VertexFormat.FLOAT_32X4,
98
+ offset: 3 * floatSize,
99
+ shaderLocation: 1,
100
+ },
101
+ {
102
+ format: VertexFormat.FLOAT_32X2,
103
+ offset: (3 + 4) * floatSize,
104
+ shaderLocation: 2,
105
+ },
106
+ {
107
+ format: VertexFormat.FLOAT_32X3,
108
+ offset: (3 + 4 + 2) * floatSize,
109
+ shaderLocation: 3,
110
+ },
111
+ ]
112
+ );
113
+ }
114
+ }
package/src/main.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import './style.css'
2
- import "reflect-metadata";
3
2
 
4
3
  import typescriptLogo from './typescript.svg'
5
4
  import viteLogo from '/vite.svg'
@@ -82,7 +82,6 @@ export class WebGlGraphicsDevice extends AGraphicsDevice {
82
82
 
83
83
  this._canvas = this._windowManager.canvas;
84
84
 
85
- debugger;
86
85
  const contextOptions: WebGLContextAttributes = {
87
86
  antialias: false,
88
87
  alpha: this._descriptor.alpha,
@@ -0,0 +1,35 @@
1
+ import {
2
+ AmbientLight,
3
+ Color,
4
+ type AmbientLightDescriptor,
5
+ type AmbientLightFactory,
6
+ type IFramework,
7
+ type LightsBuffer,
8
+ type LightsBufferDescriptor,
9
+ type Scene,
10
+ } from "../../api/index.ts";
11
+ import {WebGlLightsBuffer} from "./WebGlLightsBuffer.ts";
12
+
13
+ /** The WebGL implementation of the light factory. */
14
+ export class WebGlAmbientLightFactory implements AmbientLightFactory {
15
+
16
+ /** The colour used when no descriptor is given. */
17
+ public static readonly DEFAULT_COLOR = new Color(0.1, 0.1, 0.1);
18
+
19
+ /**
20
+ * The constructor.
21
+ * @param _framework The framework.
22
+ */
23
+ public constructor(private readonly _framework: IFramework) {
24
+ }
25
+
26
+ /** @inheritDoc */
27
+ public createAmbientLight(desc?: AmbientLightDescriptor, scene?: Scene): AmbientLight {
28
+ return new AmbientLight({...desc, color: desc?.color ?? WebGlAmbientLightFactory.DEFAULT_COLOR}, scene);
29
+ }
30
+
31
+ /** @inheritDoc */
32
+ public __createLightsBuffer(desc?: LightsBufferDescriptor): LightsBuffer {
33
+ return new WebGlLightsBuffer(this._framework, desc);
34
+ }
35
+ }
@@ -0,0 +1,215 @@
1
+ import {
2
+ AmbientLight,
3
+ BufferUsage,
4
+ DirectionalLight,
5
+ PointLight,
6
+ type Color,
7
+ DEFAULT_POINT_LIGHTS_COUNT,
8
+ type IFramework,
9
+ type IUniformBuffer,
10
+ type LightsBuffer,
11
+ type LightsBufferDescriptor,
12
+ DEFAULT_DIRECTIONAL_LIGHTS_COUNT,
13
+ } from "../../api/index.ts";
14
+
15
+ /**
16
+ * The WebGL lights buffer. Owns a std140 uniform buffer for the `LightsBuffer` block.
17
+ * See {@link LightsBuffer} for the layout.
18
+ */
19
+ export class WebGlLightsBuffer implements LightsBuffer {
20
+
21
+ /** Floats for the ambient light: vec3 padded to 16 bytes. */
22
+ public static readonly AMBIENT_FLOAT_COUNT = 4;
23
+
24
+ /** Floats per directional light: two vec3, each padded to 16 bytes. */
25
+ public static readonly DIRECTIONAL_LIGHT_FLOAT_COUNT = 8;
26
+
27
+ /** Floats per point light: vec3 light + float constant, vec3 position + float linear, float quadratic, padded to 48 bytes. */
28
+ public static readonly POINT_LIGHT_FLOAT_COUNT = 12;
29
+
30
+ private _ambientLight!: AmbientLight;
31
+ private readonly _buffer: IUniformBuffer;
32
+ private readonly _data: number[];
33
+ private readonly _uploaded: number[];
34
+ private readonly _directionalLights: DirectionalLight[] = [];
35
+ private readonly _pointLights: PointLight[] = [];
36
+ private _disposed = false;
37
+
38
+ /**
39
+ * The constructor.
40
+ * @param framework The framework, used to create the uniform buffer.
41
+ * @param descriptor The optional initial lights and directional light count.
42
+ */
43
+ public constructor(framework: IFramework, descriptor?: LightsBufferDescriptor) {
44
+ this.ambientLight = descriptor?.ambientLight ?? new AmbientLight();
45
+ this.maxDirectionalLights = descriptor?.maxDirectionalLights ?? DEFAULT_DIRECTIONAL_LIGHTS_COUNT;
46
+ this.maxPointLights = descriptor?.maxPointLights ?? DEFAULT_POINT_LIGHTS_COUNT;
47
+ for (const light of descriptor?.directionalLights ?? []) {
48
+ this.add(light);
49
+ }
50
+ for (const light of descriptor?.pointLights ?? []) {
51
+ this.add(light);
52
+ }
53
+
54
+ const floatCount = WebGlLightsBuffer.AMBIENT_FLOAT_COUNT
55
+ + this.maxDirectionalLights * WebGlLightsBuffer.DIRECTIONAL_LIGHT_FLOAT_COUNT
56
+ + this.maxPointLights * WebGlLightsBuffer.POINT_LIGHT_FLOAT_COUNT;
57
+ this._data = new Array<number>(floatCount).fill(0);
58
+ this._writeData();
59
+ this._uploaded = [...this._data];
60
+ this._buffer = framework.bufferFactory.createUniformBuffer(this._data, BufferUsage.UNIFORM | BufferUsage.COPY_DST);
61
+ }
62
+
63
+ /** @inheritDoc */
64
+ public get ambientLight(): AmbientLight {
65
+ return this._ambientLight;
66
+ }
67
+
68
+ /** @inheritDoc */
69
+ public set ambientLight(ambientLight: AmbientLight) {
70
+ this._ambientLight = ambientLight;
71
+ }
72
+
73
+ /** @inheritDoc */
74
+ public get directionalLights(): readonly DirectionalLight[] {
75
+ return this._directionalLights;
76
+ }
77
+
78
+ /** @inheritDoc */
79
+ public readonly maxDirectionalLights: number;
80
+
81
+ /** @inheritDoc */
82
+ public get pointLights(): readonly PointLight[] {
83
+ return this._pointLights;
84
+ }
85
+
86
+ /** @inheritDoc */
87
+ public add(light: DirectionalLight | PointLight): void {
88
+ const [list, max, kind] = this._listFor(light);
89
+ if (list.includes(light)) {
90
+ return;
91
+ }
92
+ if (list.length >= max) {
93
+ throw new Error(`LightsBuffer: cannot add ${kind} light ${light.id}; all ${max} ${kind} light slots are in use (max${kind === "directional" ? "Directional" : "Point"}Lights = ${max}).`);
94
+ }
95
+ list.push(light);
96
+ }
97
+
98
+ /** @inheritDoc */
99
+ public remove(light: DirectionalLight | PointLight): boolean {
100
+ const [list] = this._listFor(light);
101
+ const index = list.indexOf(light);
102
+ if (index < 0) {
103
+ return false;
104
+ }
105
+ list.splice(index, 1);
106
+ return true;
107
+ }
108
+
109
+ /** @inheritDoc */
110
+ public readonly maxPointLights: number;
111
+
112
+ /** @inheritDoc */
113
+ public get buffer(): IUniformBuffer {
114
+ return this._buffer;
115
+ }
116
+
117
+ /** @inheritDoc */
118
+ public update(): void {
119
+
120
+ // The ambient light (also a newly assigned one) is written with the rest; only changed data is uploaded.
121
+ this._writeData();
122
+ if (!this._hasChanged()) {
123
+ return;
124
+ }
125
+
126
+ this._buffer.update(this._data);
127
+ for (let i = 0; i < this._data.length; i++) {
128
+ this._uploaded[i] = this._data[i];
129
+ }
130
+ }
131
+
132
+ /** @inheritDoc */
133
+ public dispose(): void {
134
+ if (this._disposed) {
135
+ return;
136
+ }
137
+ this._disposed = true;
138
+ this._buffer.dispose();
139
+ }
140
+
141
+ private _writeAmbientLight() {
142
+ this._writeColor(0, this.ambientLight.color, this.ambientLight.intensity);
143
+ this._data[3] = 0; // std140 padding for vec3.
144
+ }
145
+
146
+ private _listFor(light: DirectionalLight | PointLight): [(DirectionalLight | PointLight)[], number, string] {
147
+ if (light instanceof DirectionalLight) {
148
+ return [this._directionalLights, this.maxDirectionalLights, "directional"];
149
+ }
150
+ if (light instanceof PointLight) {
151
+ return [this._pointLights, this.maxPointLights, "point"];
152
+ }
153
+ throw new Error("LightsBuffer: expected a DirectionalLight or PointLight instance.");
154
+ }
155
+
156
+ /** Writes color * intensity as vec3 at offset (the fourth float is left to the caller). */
157
+ private _writeColor(offset: number, color: Color | undefined, intensity: number): void {
158
+ this._data[offset] = color ? color.r * intensity : 0;
159
+ this._data[offset + 1] = color ? color.g * intensity : 0;
160
+ this._data[offset + 2] = color ? color.b * intensity : 0;
161
+ }
162
+
163
+ private _hasChanged(): boolean {
164
+ for (let i = 0; i < this._data.length; i++) {
165
+ if (this._data[i] !== this._uploaded[i]) {
166
+ return true;
167
+ }
168
+ }
169
+ return false;
170
+ }
171
+
172
+ private _writeData(): void {
173
+ // Written every time, so in-place colour and intensity edits are detected by _hasChanged().
174
+ this._writeAmbientLight();
175
+
176
+ for (let i = 0; i < this.maxDirectionalLights; i++) {
177
+ const offset = WebGlLightsBuffer.AMBIENT_FLOAT_COUNT + i * WebGlLightsBuffer.DIRECTIONAL_LIGHT_FLOAT_COUNT;
178
+ const light = this._directionalLights[i];
179
+
180
+ // vec3 light (colour * intensity)
181
+ this._writeColor(offset, light?.color, light?.intensity ?? 0);
182
+ this._data[offset + 3] = 0;
183
+
184
+ // vec3 direction
185
+ this._data[offset + 4] = light ? light.direction[0] : 0;
186
+ this._data[offset + 5] = light ? light.direction[1] : 0;
187
+ this._data[offset + 6] = light ? light.direction[2] : 0;
188
+ this._data[offset + 7] = 0;
189
+ }
190
+
191
+ const pointLightsStart = WebGlLightsBuffer.AMBIENT_FLOAT_COUNT
192
+ + this.maxDirectionalLights * WebGlLightsBuffer.DIRECTIONAL_LIGHT_FLOAT_COUNT;
193
+ for (let i = 0; i < this.maxPointLights; i++) {
194
+ const offset = pointLightsStart + i * WebGlLightsBuffer.POINT_LIGHT_FLOAT_COUNT;
195
+ const light = this._pointLights[i];
196
+
197
+ // vec3 light (colour * intensity), float constant
198
+ this._writeColor(offset, light?.color, light?.intensity ?? 0);
199
+ // An empty slot keeps constant at 1 so the shader never divides by zero.
200
+ this._data[offset + 3] = light ? light.constant : 1;
201
+
202
+ // vec3 position, float linear
203
+ this._data[offset + 4] = light ? light.position[0] : 0;
204
+ this._data[offset + 5] = light ? light.position[1] : 0;
205
+ this._data[offset + 6] = light ? light.position[2] : 0;
206
+ this._data[offset + 7] = light ? light.linear : 0;
207
+
208
+ // float quadratic, then padding to the 16-byte struct size
209
+ this._data[offset + 8] = light ? light.quadratic : 0;
210
+ this._data[offset + 9] = 0;
211
+ this._data[offset + 10] = 0;
212
+ this._data[offset + 11] = 0;
213
+ }
214
+ }
215
+ }
@@ -1,4 +1,7 @@
1
- import type {IBlendState, IFramework, IIndexBuffer, IPrimitiveState, IRenderPipeline, IVertexBuffer} from "../../api/index.ts";
1
+ import {
2
+ GeometryFormat,
3
+ type IBlendState, type IFramework, type IIndexBuffer, type IPrimitiveState, type IRenderPipeline, type IVertexBuffer
4
+ } from "../../api/index.ts";
2
5
  import type {VertexBufferLayout} from '../../core/rendering/vertex-buffer-layout';
3
6
  import type {WebGlBlendState} from '../blending/webgl-blend-state';
4
7
  import type {WebGlPrimitiveState} from '../primitive/WebGlPrimitiveState.ts';
@@ -35,6 +38,9 @@ export abstract class AWebGlRenderPipeline implements IRenderPipeline {
35
38
  this.primitiveState = (primitiveState ?? graphicsDevice.defaultPrimitiveState) as WebGlPrimitiveState;
36
39
  }
37
40
 
41
+ /** @inheritDoc */
42
+ public abstract readonly geometryFormat: GeometryFormat;
43
+
38
44
  /** @inheritDoc */
39
45
  public get blendState(): IBlendState {
40
46
  return this._blendState;
@@ -27,6 +27,9 @@ export class WebGlMainRenderTargetRenderPipeline extends AWebGlRenderPipeline im
27
27
  this._mainRenderTarget = mainRenderTarget as WebGlTexture2D;
28
28
  }
29
29
 
30
+ /** @inheritDoc */
31
+ public readonly geometryFormat = GeometryFormat.POS3_COLOR4_TEXTURECOORDS2;
32
+
30
33
  /** @inheritdoc */
31
34
  protected _provideBuffers(): WebGLBuffer[] {
32
35
  return [this._vertexBuffer.buffer!];
@@ -6,10 +6,13 @@ import type {
6
6
  IMainRenderTargetRenderPipeline, IPrimitiveState, IRenderPipelineFactory,
7
7
  ISpriteRenderPipeline, ITexture2D,
8
8
  IUniformBuffer,
9
- IUnlitRenderPipeline
10
- } from "../../api/index.ts";
9
+ IUnlitRenderPipeline,
10
+ IForwardBlinnPhongRenderPipeline,
11
+ ForwardBlinnPhongRenderPipelineDescriptor,
12
+ } from "../../api";
11
13
  import {WebGlInspectTextureMipsRenderPipeline} from "./inspect/WebGlInspectTextureMipsRenderPipeline.ts";
12
14
  import {WebGlUnlitRenderPipeline} from "./material/WebGlUnlitRenderPipeline.ts";
15
+ import {WebGlForwardBlinnPhongRenderPipeline} from "./material/WebGlBlinnPhongRenderPipeline.ts";
13
16
 
14
17
  /**
15
18
  * The WebGL implementation of the IRenderPipelineFactory interface.
@@ -37,6 +40,25 @@ export class WebGlRenderPipelineFactory implements IRenderPipelineFactory {
37
40
  return pipeline;
38
41
  }
39
42
 
43
+ /** @inheritDoc */
44
+ public createForwardBlinnPhongRenderPipeline(descriptor: ForwardBlinnPhongRenderPipelineDescriptor): IForwardBlinnPhongRenderPipeline {
45
+ const pipeline = new WebGlForwardBlinnPhongRenderPipeline(this._framework,
46
+ descriptor.projectionViewBuffer,
47
+ descriptor.modelBuffer,
48
+ descriptor.materialBuffer,
49
+ descriptor.lightsBuffer,
50
+ descriptor.cameraPositionBuffer,
51
+ descriptor.primitiveState
52
+ );
53
+ if (descriptor.maxDirectionalLights !== undefined || descriptor.maxPointLights !== undefined) {
54
+ pipeline.setLightCounts(
55
+ descriptor.maxDirectionalLights ?? pipeline.maxDirectionalLights,
56
+ descriptor.maxPointLights ?? pipeline.maxPointLights);
57
+ }
58
+ pipeline.initialize();
59
+ return pipeline;
60
+ }
61
+
40
62
  /** @inheritDoc */
41
63
  public createMainFrameBufferPipeline(mainFrameBuffer: ITexture2D): IMainRenderTargetRenderPipeline {
42
64
  const renderPipeline = new WebGlMainRenderTargetRenderPipeline(this._framework, mainFrameBuffer);
@@ -1,9 +1,10 @@
1
- import type {
2
- IFramework, IPrimitiveState,
3
- ISampler,
4
- ITexture2D,
5
- IUniformBuffer,
6
- IVertexBuffer
1
+ import {
2
+ GeometryFormat,
3
+ type IFramework, type IPrimitiveState,
4
+ type ISampler,
5
+ type ITexture2D,
6
+ type IUniformBuffer,
7
+ type IVertexBuffer
7
8
  } from "../../../api/index.ts";
8
9
  import {VertexBufferLayout} from "../../../core/rendering/vertex-buffer-layout";
9
10
  import type {WebGlUniformBuffer} from "../../buffers/WebGlUniformBuffer.ts";
@@ -52,12 +53,18 @@ export class WebGlInspectTextureMipsRenderPipeline extends AWebGlRenderPipeline
52
53
  textureConstantsBuffer: IUniformBuffer,
53
54
  primitiveState? : IPrimitiveState
54
55
  ) {
56
+ // Validated before super(), which touches WebGL.
57
+ if (!modelBuffer) {
58
+ throw new Error("WebGlInspectTextureMipsRenderPipeline: modelBuffer is required (the mesh's model buffer, std140 mat4).");
59
+ }
55
60
  super(framework, primitiveState);
56
61
  this._projectionViewBuffer = projectionViewBuffer as WebGlUniformBuffer;
57
62
  this._modelBuffer = modelBuffer as WebGlUniformBuffer;
58
63
  this._textureConstantsBuffer = textureConstantsBuffer as WebGlUniformBuffer;
59
64
  }
60
65
 
66
+ /** @inheritDoc */
67
+ public readonly geometryFormat = GeometryFormat.POS3_COLOR4_TEXTURECOORDS2;
61
68
 
62
69
  /** @inheritdoc */
63
70
  public get projectionViewBuffer(): IUniformBuffer {
@@ -76,6 +83,9 @@ export class WebGlInspectTextureMipsRenderPipeline extends AWebGlRenderPipeline
76
83
 
77
84
  /** @inheritdoc */
78
85
  public set modelBuffer(value: IUniformBuffer) {
86
+ if (!value) {
87
+ throw new Error("WebGlInspectTextureMipsRenderPipeline: modelBuffer is required (the mesh's model buffer, std140 mat4).");
88
+ }
79
89
  this._modelBuffer = asWebGLUniformBuffer(value);
80
90
  }
81
91