ris-framework 0.1.0 → 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
@@ -0,0 +1,300 @@
1
+ import {
2
+ GeometryFormat,
3
+ type IFramework, type IPrimitiveState,
4
+ type ISampler,
5
+ type ITexture2D,
6
+ type IUniformBuffer,
7
+ type IVertexBuffer
8
+ } from "../../../api";
9
+ import {VertexBufferLayout} from "../../../core/rendering/vertex-buffer-layout";
10
+ import type {WebGlUniformBuffer} from "../../buffers/WebGlUniformBuffer.ts";
11
+ import {asWebGLUniformBuffer} from "../../cast/cast";
12
+ import WebGlShaderModule from "../../shader/WebGlShaderModule.ts";
13
+ import {WebGlTexture2D} from "../../texture/WebGlTexture2D.ts";
14
+ import {WebGlVertexBuffer} from '../../buffers/WebGlVertexBuffer.ts';
15
+ import {AWebGlRenderPipeline} from "../AWebGlRenderPipeline.ts";
16
+ import type {WebGLIndexBuffer} from "../../buffers/webgl-index-buffer";
17
+ import {
18
+ type IIndexBuffer,
19
+ IndexBufferType,
20
+ DEFAULT_DIRECTIONAL_LIGHTS_COUNT,
21
+ DEFAULT_POINT_LIGHTS_COUNT
22
+ } from "../../../api";
23
+ import type {WebGlSampler} from "../../sampler/webgl-sampler.ts";
24
+ import type {
25
+ IForwardBlinnPhongRenderPipeline
26
+ } from "../../../api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.ts";
27
+
28
+ /**
29
+ * The WebGL implementation of Blinn-Phong with forward calculated lighting.
30
+ * @internal
31
+ **/
32
+ export class WebGlForwardBlinnPhongRenderPipeline extends AWebGlRenderPipeline implements IForwardBlinnPhongRenderPipeline {
33
+
34
+ private static readonly CAMERA_BINDING_POINT = 0;
35
+ private static readonly MODEL_BINDING_POINT = 1;
36
+ private static readonly MATERIAL_BINDING_POINT = 2;
37
+ private static readonly LIGHTS_BINDING_POINT = 3;
38
+ private static readonly CAMERA_POSITION_BINDING_POINT = 4;
39
+
40
+ private _texture: WebGlTexture2D = null!;
41
+ private _sampler?: WebGlSampler;
42
+ private _projectionViewBuffer: WebGlUniformBuffer;
43
+ private _modelBuffer: WebGlUniformBuffer;
44
+ private _materialBuffer: WebGlUniformBuffer;
45
+ private _lightsBuffer: WebGlUniformBuffer;
46
+ private _cameraBlockIndex = -1;
47
+ private _modelBlockIndex = -1;
48
+ private _materialBlockIndex = -1;
49
+ private _lightsBlockIndex = -1;
50
+ private _cameraPositionBuffer: WebGlUniformBuffer;
51
+ private _cameraPositionBlockIndex = -1;
52
+ private _maxDirectionalLights = DEFAULT_DIRECTIONAL_LIGHTS_COUNT;
53
+ private _maxPointLights = DEFAULT_POINT_LIGHTS_COUNT;
54
+ private _initialized = false;
55
+ private _buffersArray: WebGLBuffer[] = [null!];
56
+ private _lastVertexBuffer: WebGlVertexBuffer | null = null;
57
+
58
+ /**
59
+ * The constructor.
60
+ * @param framework The framework.
61
+ * @param projectionViewBuffer The projection view buffer.
62
+ * @param modelBuffer The model buffer.
63
+ * @param materialBuffer The material buffer.
64
+ * @param lightsBuffer The lights buffer (`LightsBuffer.buffer`). May be set later.
65
+ * @param cameraPositionBuffer The camera position buffer (world-space eye).
66
+ * @param primitiveState The primitive state.
67
+ */
68
+ public constructor(framework: IFramework,
69
+ projectionViewBuffer: IUniformBuffer,
70
+ modelBuffer: IUniformBuffer,
71
+ materialBuffer: IUniformBuffer,
72
+ lightsBuffer: IUniformBuffer | undefined,
73
+ cameraPositionBuffer: IUniformBuffer,
74
+ primitiveState?: IPrimitiveState,
75
+ ) {
76
+ // Validated before super(), which touches WebGL.
77
+ if (!modelBuffer) {
78
+ throw new Error("WebGlForwardBlinnPhongRenderPipeline: modelBuffer is required (the mesh's model buffer, std140 mat4).");
79
+ }
80
+ super(framework, primitiveState);
81
+ this._projectionViewBuffer = projectionViewBuffer as WebGlUniformBuffer;
82
+ this._modelBuffer = modelBuffer as WebGlUniformBuffer;
83
+ this._materialBuffer = materialBuffer as WebGlUniformBuffer;
84
+ this._lightsBuffer = lightsBuffer as WebGlUniformBuffer;
85
+ this._cameraPositionBuffer = cameraPositionBuffer as WebGlUniformBuffer;
86
+ }
87
+
88
+ /** @inheritDoc */
89
+ public readonly geometryFormat = GeometryFormat.POS3_COLOR4_TEXTURECOORDS2_NORMAL3;
90
+
91
+ /** @inheritdoc */
92
+ public get projectionViewBuffer(): IUniformBuffer {
93
+ return this._projectionViewBuffer;
94
+ }
95
+
96
+ /** @inheritdoc */
97
+ public set projectionViewBuffer(value: IUniformBuffer) {
98
+ this._projectionViewBuffer = asWebGLUniformBuffer(value);
99
+ }
100
+
101
+ /** @inheritdoc */
102
+ public get modelBuffer(): IUniformBuffer {
103
+ return this._modelBuffer;
104
+ }
105
+
106
+ /** @inheritdoc */
107
+ public set modelBuffer(value: IUniformBuffer) {
108
+ if (!value) {
109
+ throw new Error("WebGlForwardBlinnPhongRenderPipeline: modelBuffer is required (the mesh's model buffer, std140 mat4).");
110
+ }
111
+ this._modelBuffer = asWebGLUniformBuffer(value);
112
+ }
113
+
114
+ /** @inheritdoc */
115
+ public get materialBuffer(): IUniformBuffer {
116
+ return this._materialBuffer;
117
+ }
118
+
119
+ /** @inheritdoc */
120
+ public set materialBuffer(value: IUniformBuffer) {
121
+ this._materialBuffer = asWebGLUniformBuffer(value);
122
+ }
123
+
124
+ /** @inheritdoc */
125
+ public get lightsBuffer(): IUniformBuffer {
126
+ return this._lightsBuffer;
127
+ }
128
+
129
+ /** @inheritdoc */
130
+ public set lightsBuffer(value: IUniformBuffer) {
131
+ this._lightsBuffer = asWebGLUniformBuffer(value);
132
+ }
133
+
134
+ /** @inheritdoc */
135
+ public get maxDirectionalLights(): number {
136
+ return this._maxDirectionalLights;
137
+ }
138
+
139
+ /** @inheritdoc */
140
+ public get maxPointLights(): number {
141
+ return this._maxPointLights;
142
+ }
143
+
144
+ /** @inheritdoc */
145
+ public setLightCounts(maxDirectionalLights: number, maxPointLights: number): void {
146
+ if (maxDirectionalLights === this._maxDirectionalLights && maxPointLights === this._maxPointLights) {
147
+ return;
148
+ }
149
+ this._maxDirectionalLights = maxDirectionalLights;
150
+ this._maxPointLights = maxPointLights;
151
+ if (this._initialized) {
152
+ // The vertex array object only depends on the vertex layout, so only the program and block bindings change.
153
+ this._loadProgram();
154
+ }
155
+ }
156
+
157
+ /** @inheritdoc */
158
+ public get cameraPositionBuffer(): IUniformBuffer {
159
+ return this._cameraPositionBuffer;
160
+ }
161
+
162
+ /** @inheritdoc */
163
+ public set cameraPositionBuffer(value: IUniformBuffer) {
164
+ this._cameraPositionBuffer = asWebGLUniformBuffer(value);
165
+ }
166
+
167
+ /** @inheritdoc */
168
+ public get diffuseTexture(): ITexture2D {
169
+ return this._texture;
170
+ }
171
+
172
+ /** @inheritdoc */
173
+ public set diffuseTexture(value: ITexture2D) {
174
+ this._texture = value as WebGlTexture2D;
175
+ }
176
+
177
+ /** @inheritdoc */
178
+ public get diffuseTextureSampler(): ISampler | undefined {
179
+ return this._sampler;
180
+ }
181
+
182
+ public set diffuseTextureSampler(value: ISampler | undefined) {
183
+ this._sampler = value as WebGlSampler | undefined;
184
+ }
185
+
186
+ /** @inheritdoc */
187
+ public override initialize(): void {
188
+
189
+ this._loadProgram();
190
+ this.vertexBufferLayouts = [VertexBufferLayout.createFloat3Float4Float2Float3Layout()];
191
+ super.initialize();
192
+ this._initialized = true;
193
+ }
194
+
195
+ /** Loads the shader variant for the current light counts (cached per counts by the shader loader). */
196
+ private _loadProgram(): void {
197
+ const module = this._framework.content.loadShaderModule("forward_blinn_phong_material", {
198
+ "DIRECTIONAL_LIGHTS_COUNT": this._maxDirectionalLights,
199
+ "POINT_LIGHTS_COUNT": this._maxPointLights,
200
+ }) as WebGlShaderModule;
201
+ this._program = module.program!;
202
+ this._createResources();
203
+ }
204
+
205
+ private _createResources(): void {
206
+ {
207
+ this._texture = WebGlTexture2D.getOrCreateDefault(this._framework);
208
+
209
+ this._cameraBlockIndex = this._gl.getUniformBlockIndex(this._program, "CameraBuffer");
210
+ this._gl.uniformBlockBinding(this._program, this._cameraBlockIndex, WebGlForwardBlinnPhongRenderPipeline.CAMERA_BINDING_POINT);
211
+
212
+ this._modelBlockIndex = this._gl.getUniformBlockIndex(this._program, "ModelBuffer");
213
+ this._gl.uniformBlockBinding(this._program, this._modelBlockIndex, WebGlForwardBlinnPhongRenderPipeline.MODEL_BINDING_POINT);
214
+
215
+ this._materialBlockIndex = this._gl.getUniformBlockIndex(this._program, "MaterialBuffer");
216
+ this._gl.uniformBlockBinding(this._program, this._materialBlockIndex, WebGlForwardBlinnPhongRenderPipeline.MATERIAL_BINDING_POINT);
217
+
218
+ this._lightsBlockIndex = this._gl.getUniformBlockIndex(this._program, "LightsBuffer");
219
+ this._gl.uniformBlockBinding(this._program, this._lightsBlockIndex, WebGlForwardBlinnPhongRenderPipeline.LIGHTS_BINDING_POINT);
220
+
221
+ this._cameraPositionBlockIndex = this._gl.getUniformBlockIndex(this._program, "CameraPositionBuffer");
222
+ this._gl.uniformBlockBinding(this._program, this._cameraPositionBlockIndex, WebGlForwardBlinnPhongRenderPipeline.CAMERA_POSITION_BINDING_POINT);
223
+ }
224
+ }
225
+
226
+
227
+ /** @inheritdoc */
228
+ protected _provideBuffers(): WebGLBuffer[] | undefined | null {
229
+ if (this._lastVertexBuffer === null) {
230
+ return null;
231
+ }
232
+
233
+ this._buffersArray[0] = this._lastVertexBuffer.buffer!;
234
+ return this._buffersArray;
235
+ }
236
+
237
+ /** @inheritdoc */
238
+ public render(vertexBuffer: IVertexBuffer, indexBuffer: IIndexBuffer, indicesCount: number = -1, indicesOffset: number = 0): void {
239
+
240
+ if (indicesCount == 0) {
241
+ return;
242
+ }
243
+
244
+ const webGlVertexBuffer = vertexBuffer as WebGlVertexBuffer;
245
+ const webGlIndexBuffer = indexBuffer as WebGLIndexBuffer;
246
+ const webGlSampler = this._sampler ?? this._defaultTextureSampler;
247
+
248
+ this.primitiveState.apply(this._gl);
249
+ this._blendState.apply(this._gl);
250
+
251
+ // if it was changed, we need to create a new vao.
252
+ if (this._lastVertexBuffer != webGlVertexBuffer) {
253
+ // Create a new VAO. Internally deletes the old one.
254
+ this._lastVertexBuffer = webGlVertexBuffer;
255
+ this._createVertexArrayObject();
256
+ }
257
+
258
+ this._gl.useProgram(this._program);
259
+ // Bind the vao. It contains all the information about the vertex buffer layout ( vertices + instances)
260
+ this._gl.bindVertexArray(this._vertexArrayObject);
261
+ this._gl.bindBuffer(this._gl.ELEMENT_ARRAY_BUFFER, webGlIndexBuffer.buffer);
262
+ this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER,
263
+ WebGlForwardBlinnPhongRenderPipeline.CAMERA_BINDING_POINT,
264
+ this._projectionViewBuffer.glBuffer!);
265
+ this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER,
266
+ WebGlForwardBlinnPhongRenderPipeline.MODEL_BINDING_POINT,
267
+ this._modelBuffer.glBuffer!);
268
+
269
+ if (this.materialBuffer) {
270
+ this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER,
271
+ WebGlForwardBlinnPhongRenderPipeline.MATERIAL_BINDING_POINT,
272
+ this._materialBuffer.glBuffer!);
273
+ }
274
+ if (this._lightsBuffer) {
275
+ this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER,
276
+ WebGlForwardBlinnPhongRenderPipeline.LIGHTS_BINDING_POINT,
277
+ this._lightsBuffer.glBuffer!);
278
+ }
279
+ this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER,
280
+ WebGlForwardBlinnPhongRenderPipeline.CAMERA_POSITION_BINDING_POINT,
281
+ this._cameraPositionBuffer.glBuffer!);
282
+ this._gl.activeTexture(this._gl.TEXTURE0);
283
+ this._gl.bindTexture(this._gl.TEXTURE_2D, this._texture!.glTexture);
284
+ this._gl.bindSampler(0, webGlSampler.glSampler);
285
+
286
+ // We can only really use two types uint16 and uint32. Boolean check to see which one to use.
287
+ const type = indexBuffer.type == IndexBufferType.UINT_16
288
+ ? this._gl.UNSIGNED_SHORT
289
+ : this._gl.UNSIGNED_INT;
290
+
291
+ // api.PolygonMode(GLEnum.FrontAndBack, GLEnum.Line);
292
+
293
+ // Either draw all indices or a specific amount. If indicesCount is -1, draw all as defined by the index buffer.
294
+ const toIndices = indicesCount > 0 ? indicesCount : indexBuffer.indicesCount;
295
+ const fromIndices = indicesOffset * indexBuffer.elementByteSize;
296
+
297
+ this._gl.drawElements(this.primitiveState.glPrimitiveType, toIndices, type, fromIndices);
298
+ }
299
+
300
+ }
@@ -1,9 +1,10 @@
1
- import type {
2
- IFramework, IPrimitiveState,
3
- ISampler,
4
- ITexture2D,
5
- IUniformBuffer, IUnlitRenderPipeline,
6
- IVertexBuffer
1
+ import {
2
+ GeometryFormat,
3
+ type IFramework, type IPrimitiveState,
4
+ type ISampler,
5
+ type ITexture2D,
6
+ type IUniformBuffer, type IUnlitRenderPipeline,
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";
@@ -50,12 +51,18 @@ export class WebGlUnlitRenderPipeline extends AWebGlRenderPipeline implements IU
50
51
  materialBuffer: IUniformBuffer,
51
52
  primitiveState?: IPrimitiveState,
52
53
  ) {
54
+ // Validated before super(), which touches WebGL.
55
+ if (!modelBuffer) {
56
+ throw new Error("WebGlUnlitRenderPipeline: modelBuffer is required (the mesh's model buffer, std140 mat4).");
57
+ }
53
58
  super(framework, primitiveState);
54
59
  this._projectionViewBuffer = projectionViewBuffer as WebGlUniformBuffer;
55
60
  this._modelBuffer = modelBuffer as WebGlUniformBuffer;
56
61
  this._materialBuffer = materialBuffer as WebGlUniformBuffer;
57
62
  }
58
63
 
64
+ /** @inheritDoc */
65
+ public readonly geometryFormat = GeometryFormat.POS3_COLOR4_TEXTURECOORDS2;
59
66
 
60
67
  /** @inheritdoc */
61
68
  public get projectionViewBuffer(): IUniformBuffer {
@@ -74,6 +81,9 @@ export class WebGlUnlitRenderPipeline extends AWebGlRenderPipeline implements IU
74
81
 
75
82
  /** @inheritdoc */
76
83
  public set modelBuffer(value: IUniformBuffer) {
84
+ if (!value) {
85
+ throw new Error("WebGlUnlitRenderPipeline: modelBuffer is required (the mesh's model buffer, std140 mat4).");
86
+ }
77
87
  this._modelBuffer = asWebGLUniformBuffer(value);
78
88
  }
79
89
 
@@ -1,10 +1,11 @@
1
- import type {
2
- IFramework,
3
- ISampler,
4
- ISpriteRenderPipeline,
5
- ITexture2D,
6
- IUniformBuffer,
7
- IVertexBuffer
1
+ import {
2
+ GeometryFormat,
3
+ type IFramework,
4
+ type ISampler,
5
+ type ISpriteRenderPipeline,
6
+ type ITexture2D,
7
+ type IUniformBuffer,
8
+ type IVertexBuffer
8
9
  } from "../../../api/index.ts";
9
10
  import {VertexBufferLayout} from "../../../core/rendering/vertex-buffer-layout";
10
11
  import type {WebGlUniformBuffer} from "../../buffers/WebGlUniformBuffer.ts";
@@ -41,6 +42,9 @@ export class WebGlSpriteRenderPipeline extends AWebGlRenderPipeline implements I
41
42
  this._projectionViewBuffer = asWebGLUniformBuffer(projectionViewBuffer);
42
43
  }
43
44
 
45
+ /** @inheritDoc */
46
+ public readonly geometryFormat = GeometryFormat.POS3_COLOR4_TEXTURECOORDS2;
47
+
44
48
  /** @inheritdoc */
45
49
  public get projectionViewBuffer(): IUniformBuffer {
46
50
  return this._projectionViewBuffer;
@@ -22,12 +22,12 @@ export class WebGlShaderModule implements IShaderModule {
22
22
  * The constructor of the WebGL shader module.
23
23
  * @param framework The framework.
24
24
  * @param shaderFilePath
25
+ * @param @param keyValueDictionary - If present, tries to find key in shader such that it replaced ##DIRECTIONAL_LIGHT_COUNT## by given value for key DIRECTIONAL_LIGHST_COUNT.
25
26
  */
26
- public constructor(framework: IFramework, shaderFilePath: string) {
27
+ public constructor(framework: IFramework, shaderFilePath: string, keyValueDictionary?: {[id:string]: number} ) {
27
28
  this._graphicsDevice = framework.renderer.graphicsDevice as WebGlGraphicsDevice;
28
29
  this._gl = this._graphicsDevice.gl;
29
- this._program = this._loadShaders(shaderFilePath);
30
-
30
+ this._program = this._loadShaders(shaderFilePath, keyValueDictionary);
31
31
  }
32
32
 
33
33
  /** @inheritDoc */
@@ -63,7 +63,7 @@ export class WebGlShaderModule implements IShaderModule {
63
63
  return this._program;
64
64
  }
65
65
 
66
- private _loadShaders(shaderFilePath: string): WebGLProgram {
66
+ private _loadShaders(shaderFilePath: string, keyValueDictionary?: {[id:string]: number} ): WebGLProgram {
67
67
 
68
68
  const internalShader = this._tryResolveFrameworkShader(shaderFilePath);
69
69
 
@@ -72,6 +72,7 @@ export class WebGlShaderModule implements IShaderModule {
72
72
  if (internalShader) {
73
73
  vertexShaderSource = internalShader.vertex;
74
74
  fragmentShaderSource = internalShader.fragment;
75
+
75
76
  } else {
76
77
 
77
78
  throw new Error("Not implemented");
@@ -84,6 +85,12 @@ export class WebGlShaderModule implements IShaderModule {
84
85
  // fragmentShaderSource = await this._shaderLoader.load(shaderFilePath, RenderingBackend.WEB_GL, [ShaderStage.FRAGMENT]);
85
86
  }
86
87
 
88
+ if(keyValueDictionary) {
89
+ for(const key in keyValueDictionary) {
90
+ vertexShaderSource = vertexShaderSource.replace(`##${key}##`, String(keyValueDictionary[key]));
91
+ fragmentShaderSource = fragmentShaderSource.replace(`##${key}##`, String(keyValueDictionary[key]));
92
+ }
93
+ }
87
94
 
88
95
  const vertexShader = WebGlUtilities.shader.createVertexShader(this._gl, vertexShaderSource);
89
96
  const fragmentShader = WebGlUtilities.shader.createFragmentShader(this._gl, fragmentShaderSource);
@@ -2,6 +2,21 @@ import WebGlShaderModule from "./WebGlShaderModule.ts";
2
2
  import type {IFramework, IShaderModule} from "../../api/index.ts";
3
3
 
4
4
 
5
+ /**
6
+ * Builds the cache key of a shader module: the id plus the sorted replacement values,
7
+ * so the same shader with different `##KEY##` values (e.g. light counts) is compiled separately.
8
+ * @param id The shader module id.
9
+ * @param keyValueDictionary The optional replacement values.
10
+ * @internal
11
+ */
12
+ export function shaderModuleCacheKey(id: string, keyValueDictionary?: {[id: string]: number}): string {
13
+ if (!keyValueDictionary) {
14
+ return id;
15
+ }
16
+ const entries = Object.keys(keyValueDictionary).sort().map(key => `${key}=${keyValueDictionary[key]}`);
17
+ return entries.length === 0 ? id : `${id}?${entries.join("&")}`;
18
+ }
19
+
5
20
  /**
6
21
  * The content WebGL implementation of ShaderContentModule.
7
22
  */
@@ -17,24 +32,28 @@ export class WebGlShaderModuleLoader {
17
32
  this._framework = framework;
18
33
  }
19
34
 
20
- /**
21
- * The content types provided by this content module.
22
- * @param assetFilePathOrIdentifier The asset file path or identifier of the content to load.
23
- */
24
- public load(assetFilePathOrIdentifier: string): IShaderModule {
35
+ /** @inheritDoc */
36
+ public load(assetFilePathOrIdentifier: string, keyValueDictionary?: {[id:string]: number} ): IShaderModule {
25
37
 
26
38
  // Here something like 'sprite' is provided, we must resolve it.
27
39
 
28
40
  // Is it already cached?
29
- let shaderModule = this._shaderModules.get(assetFilePathOrIdentifier);
41
+ const cacheKey = shaderModuleCacheKey(assetFilePathOrIdentifier, keyValueDictionary);
42
+ let shaderModule = this._shaderModules.get(cacheKey);
30
43
  if (!shaderModule) {
31
44
 
32
45
  // If it does not exist create one and set it.
33
- shaderModule = new WebGlShaderModule(this._framework, assetFilePathOrIdentifier);
34
- this._shaderModules.set(assetFilePathOrIdentifier, shaderModule);
46
+ shaderModule = new WebGlShaderModule(this._framework, assetFilePathOrIdentifier, keyValueDictionary);
47
+ this._shaderModules.set(cacheKey, shaderModule);
35
48
  }
36
49
  return shaderModule;
37
50
  }
38
51
 
39
-
40
- }
52
+ /** Deletes every cached shader program and clears the cache. */
53
+ public dispose(): void {
54
+ for (const shaderModule of this._shaderModules.values()) {
55
+ shaderModule.dispose();
56
+ }
57
+ this._shaderModules.clear();
58
+ }
59
+ }
@@ -107,16 +107,19 @@ export class WebGlTexture2D extends ATexture2D {
107
107
  }
108
108
  }
109
109
 
110
- private static _defaultFilled: WebGlTexture2D | null = null;
110
+ /** One default texture per framework, so a new framework (and GL context) never gets a texture of an old one. */
111
+ private static readonly _defaultFilled = new WeakMap<IFramework, WebGlTexture2D>();
111
112
 
112
113
  /**
113
114
  * Creates a default 1x1 white texture if it doesn't already exist and returns it.
114
115
  * This can be used as a placeholder texture when a texture is expected but not available.
115
116
  * @param framework The framework instance.
117
+ * The texture belongs to that framework's GL context; each framework gets its own.
116
118
  * @returns The default 1x1 white texture.
117
119
  */
118
120
  public static getOrCreateDefault(framework: IFramework): WebGlTexture2D {
119
- if (this._defaultFilled === null || this._defaultFilled.state === State.DISPOSED) {
121
+ let texture = WebGlTexture2D._defaultFilled.get(framework);
122
+ if (!texture || texture.state === State.DISPOSED) {
120
123
 
121
124
  const desc = new TextureDescriptor();
122
125
  desc.width = 1;
@@ -125,11 +128,22 @@ export class WebGlTexture2D extends ATexture2D {
125
128
  desc.textureFormat = framework.renderer.preferredTextureFormat;
126
129
  desc.label = "RisDefaultFilledTexture";
127
130
 
128
- this._defaultFilled = new WebGlTexture2D(framework, desc);
129
- this._defaultFilled.initialize();
131
+ texture = new WebGlTexture2D(framework, desc);
132
+ texture.initialize();
133
+ WebGlTexture2D._defaultFilled.set(framework, texture);
130
134
  }
131
135
 
132
- return this._defaultFilled;
136
+ return texture;
137
+ }
138
+
139
+ /**
140
+ * Disposes and forgets the default texture of a framework. Called from `Framework.dispose()`.
141
+ * @param framework The framework instance.
142
+ */
143
+ public static disposeDefault(framework: IFramework): void {
144
+ const texture = WebGlTexture2D._defaultFilled.get(framework);
145
+ WebGlTexture2D._defaultFilled.delete(framework);
146
+ texture?.dispose();
133
147
  }
134
148
 
135
149
  }
@@ -7,18 +7,17 @@ export class WebGLFilterAnisotropicUtilities {
7
7
  */
8
8
  private MAX_ANISOTROPY_EXT: string = "EXT_texture_filter_anisotropic";
9
9
 
10
- private _extension: any;
11
-
12
10
  /**
13
11
  * Gets the max anisotropy.
14
12
  * @param gl The WebGL2 rendering context.
15
13
  * @returns The maximum supported level of anisotropic filtering. `0` if not supported.
16
14
  */
17
15
  public getMaxAnisotropy(gl: WebGL2RenderingContext): number {
18
- this._extension = gl.getExtension(this.MAX_ANISOTROPY_EXT);
16
+ // Looked up per context: this utility is a shared static, and an extension object belongs to one context.
17
+ const extension = gl.getExtension(this.MAX_ANISOTROPY_EXT);
19
18
 
20
- if (this._extension) {
21
- return gl.getParameter(this._extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
19
+ if (extension) {
20
+ return gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
22
21
  }
23
22
 
24
23
  return 0;
@@ -31,7 +30,11 @@ export class WebGLFilterAnisotropicUtilities {
31
30
  * @param anisotropy The level of anisotropic filtering
32
31
  */
33
32
  public setAnisotropy(gl: WebGL2RenderingContext, texture: WebGLTexture, anisotropy: number) {
33
+ const extension = gl.getExtension(this.MAX_ANISOTROPY_EXT);
34
+ if (!extension) {
35
+ return;
36
+ }
34
37
  gl.bindTexture(gl.TEXTURE_2D, texture);
35
- gl.texParameterf(gl.TEXTURE_2D, this._extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
38
+ gl.texParameterf(gl.TEXTURE_2D, extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
36
39
  }
37
40
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"shader-loader.d.ts","sourceRoot":"","sources":["../../../src/api/shader/shader-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAE,KAAK,WAAW,EAAC,MAAM,aAAa,CAAC;AAE/D,qBAAa,YAAY;IAErB;;;;;;OAMG;IACU,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAexH"}