ris-framework 0.2.0-dev.12 → 0.2.0-dev.13

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 (3) hide show
  1. package/CHANGELOG.md +1 -2
  2. package/README.md +96 -159
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -19,7 +19,6 @@ Compared with `main` (0.1.0).
19
19
 
20
20
  ### Added
21
21
 
22
- - WebGPU backend (preview): set `renderingBackend` and call `framework.initializeAsync()`. Only unlit materials are supported so far; WebGL stays the default and is used as a fallback.
23
22
  - `Scene` with `add`/`remove` for meshes, lights and the camera, plus `SceneMesh` for owning a mesh and its materials.
24
23
  - Lights: `AmbientLight`, `DirectionalLight` and `PointLight`.
25
24
  - `ForwardBlinnPhongMaterial`, `SpriteMaterial`, and the `ICameraMaterial`/`ILightsMaterial` interfaces.
@@ -27,7 +26,7 @@ Compared with `main` (0.1.0).
27
26
  - OBJ/MTL loading through `framework.objLoader`, `ObjParser`, and `content.loadMeshAsync`, `loadUnlitMeshAsync` and `loadBlinnPhongMeshAsync`.
28
27
  - `geometryBuilder.create(descriptor)` and the exported `BaseGeometry`.
29
28
  - sRGB compressed texture formats (BC1, BC3, BC7, ETC2), with KTX2 loading choosing sRGB automatically.
30
- - Examples: `unlit_mesh`, `unlit_mesh_webgpu`, `blinn_phong_mesh` and `sprite_batch`.
29
+ - Examples: `unlit_mesh`, `blinn_phong_mesh` and `sprite_batch`.
31
30
 
32
31
  ### Changed
33
32
 
package/README.md CHANGED
@@ -1,212 +1,149 @@
1
1
  # ris-framework
2
2
 
3
- `ris-framework` is a browser WebGL2 framework, published as an ES module. Version 0.1.0. An application imports the compiled package. This repository also contains a sample page that runs the framework.
4
-
5
- Open `index.html`. The module script is `src/main.ts`. That file builds the page, constructs a `Framework`, and starts the frame loop. Shared interfaces and value types (`IFramework`, `Color`, `Rect`, `TextureDescriptor`, and the rest) ship from this package. They used to live in `ris-framework-api`. This repository implements them.
6
-
7
- ## Layout
8
-
9
- | Path | What lives there |
10
- | --- | --- |
11
- | `index.html` | The page. It has `#app` and `<canvas id="game-canvas" width="800" height="600">`. |
12
- | `src/main.ts` | Application entry. |
13
- | `src/index.ts` | Package entry. Exports `Framework`, `FrameworkConfiguration`, `TextureSamplerFilteringPreset`, and everything under `src/api`. |
14
- | `src/Framework.ts` | `Framework`, which wires the renderer, factories, managers, and the frame loop together. |
15
- | `src/api` | Interfaces and value types formerly published as `ris-framework-api` (input, textures, cameras, `TextureUtilities`, and the rest). It also holds `FrameworkConfiguration` and the backend-independent implementations: `WindowManager`, `InputManager`, `ContentManager`, `SpriteBatch`, `GeometryBuilder`, and `BaseGeometry`. `src/api/content/ShaderModuleContent.ts` maps the built-in shader module ids to GLSL from `shaders/glsl`. |
16
- | `src/core` | Renderer and graphics-device base classes (`ARenderer`, `AGraphicsDevice`), the texture base class, blend and sampler descriptors, `VertexBufferLayout`, and `TextureSamplerFilteringPreset`. |
17
- | `src/webgl` | The WebGL2 graphics device, renderer, textures, buffers, samplers, and render pipelines. |
18
- | `shaders/glsl` | Vertex and fragment shaders used by the built-in shader modules. |
19
- | `tests` | Vitest tests for the types under `src/api`. |
20
-
21
- Runtime dependencies are `ris-ktx2` and `gl-matrix`. The KTX2 types (`IKtx2Texture`, `VkFormat`, `KtxTranscodeFormat`, and the rest) are imported from `ris-ktx2`. The library build includes the browser portion of `ris-ktx2`, with its Node loader replaced by a stub, so the published entry does not import Node built-ins. TypeScript, Vite, and Vitest are dev dependencies. Notices for the bundled KTX loader are in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). The package license is Apache License 2.0. Copyright 2026 Luka Erkapic. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
22
-
23
- ## Prerequisites
24
-
25
- - Node.js 22. Continuous integration uses Node.js 22. Vite 7 in this repo requires `^20.19.0` or `>=22.12.0`.
26
- - npm.
27
- - A browser that can create a WebGL2 context. If `canvas.getContext("webgl2")` fails, startup throws `WebGL not supported.`
28
-
29
- ## Install
30
-
31
- Install the package in an application:
3
+ A browser WebGL2 framework for TypeScript, published as an ES module (version 0.2.0). Runtime dependencies are `gl-matrix` and `ris-ktx2`.
32
4
 
33
5
  ```sh
34
6
  npm install ris-framework
35
7
  ```
36
8
 
37
- The published entry is compiled JavaScript and TypeScript declarations (`dist/index.js` and `dist/index.d.ts`). Import the public surface by package name:
9
+ Everything public is exported from the package entry: `Framework`, `TextureSamplerFilteringPreset`, and the API types (scenes, meshes, materials, lights, cameras, textures, loaders, input).
38
10
 
39
- ```ts
40
- import { Framework, FrameworkConfiguration, TextureSamplerFilteringPreset } from "ris-framework";
41
- ```
11
+ ## Create and start a framework
42
12
 
43
- The same entry re-exports the former `ris-framework-api` surface, so a consumer can import those names from `ris-framework`:
13
+ Pass an `IFrameworkConfiguration` object. Every field is optional.
44
14
 
45
15
  ```ts
46
- import { Color, Rect, TextureFormat, TextureUtilities, type IInputManager } from "ris-framework";
47
- ```
16
+ import { Color, Framework, type IFrameworkConfiguration, TextureSamplerFilteringPreset } from "ris-framework";
48
17
 
49
- `Framework`, `FrameworkConfiguration`, `TextureSamplerFilteringPreset`, and that API surface are the public entry. Built-in GLSL is compiled into `dist/index.js`, so a consumer does not load this repository's `shaders/` directory at runtime. The same file includes the browser KTX2 loader. A consuming Vite app can import the package and build without adding a Node stub of its own.
18
+ const config: IFrameworkConfiguration = {
19
+ canvas: document.querySelector<HTMLCanvasElement>("#game-canvas")!,
20
+ textureFiltering: TextureSamplerFilteringPreset.BILINEAR,
21
+ useKtx2: true,
22
+ };
50
23
 
51
- To work in this repository:
52
-
53
- ```sh
54
- npm ci
55
- ```
56
-
57
- `Framework` creates its services itself and passes dependencies through their constructors; no dependency-injection container or `reflect-metadata` import is needed.
58
-
59
- ## Create a framework instance
60
-
61
- Construct `FrameworkConfiguration`, then pass it to `Framework`. The constructor is `constructor(options?: IFrameworkConfiguration)`. Omitting the argument uses `new FrameworkConfiguration()`. The constructor writes the resolved `backBufferSize` back onto the object you pass.
24
+ const framework = new Framework(config);
62
25
 
63
- Another project imports that public entry by package name: `import { Framework, FrameworkConfiguration, TextureSamplerFilteringPreset } from "ris-framework"`.
26
+ framework.addOnLoadContentListener(async () => { /* load content */ });
27
+ framework.addOnUpdateListener(time => { /* update, time.deltaTimeSec */ });
28
+ framework.addOnRenderListener(() => { /* draw */ });
64
29
 
65
- No config field is required. Each field has a default.
30
+ framework.initialize();
31
+ framework.renderer.clearColor = Color.cornerFlowerBlue();
32
+ ```
66
33
 
67
- | Field | Default | What the code does with it |
34
+ | Field | Default | Meaning |
68
35
  | --- | --- | --- |
69
- | `canvas` | `undefined` | The canvas the WebGL2 context is created from. When unset, `Framework` logs a warning and `WindowManager` creates a canvas and appends it to `document.body`. `src/main.ts` sets this to `#game-canvas`. |
70
- | `backBufferSize` | `undefined` (the constructor uses `vec2.fromValues(800, 600)`) | Copied onto an internal `IRendererConfiguration`. `WebGlRenderer` leaves that copy unused. The main render target starts at the canvas element's `width` and `height`. The canvas in `index.html` is 800 by 600. |
71
- | `textureFiltering` | `TextureSamplerFilteringPreset.BILINEAR` | Preset for the graphics device's default texture sampler. `POINT` is nearest filtering with no mipmaps. `BILINEAR` is linear filtering with no mipmaps. `TRILINEAR` is linear filtering with linear mipmaps. `undefined` is treated as `BILINEAR`. |
72
- | `useKtx2` | `false` | When `true`, the constructor sets `framework.ktx2Factory` to a `Ktx2Factory`. `initialize()` then calls `initializeAsync()` on it and does not wait. When `false`, `ktx2Factory` stays unset. |
73
- | `alpha` | `false` | Passed as the WebGL2 context's `alpha` attribute, so it decides whether the canvas back buffer has an alpha channel. |
74
- | `powerPreference` | `PowerPreferenceType.DEFAULT` | Passed as the WebGL2 context's `powerPreference` (`"default"`, `"low-power"`, or `"high-performance"`). It only matters on machines with more than one GPU. |
75
-
76
- Every field is optional on `IFrameworkConfiguration`. A new `FrameworkConfiguration` sets `useKtx2`, `textureFiltering`, `alpha`, and `powerPreference`. `canvas` and `backBufferSize` start unset.
36
+ | `canvas` | created and appended | The canvas to render into. |
37
+ | `backBufferSize` | `800 × 600` | Back buffer size. |
38
+ | `textureFiltering` | `BILINEAR` | Default sampler preset. |
39
+ | `textureColorSpace` | `SRGB` | Default texture colour space. |
40
+ | `useKtx2` | `false` | Creates `framework.ktx2Factory`. |
41
+ | `alpha` | `false` | Whether the back buffer has an alpha channel. |
42
+ | `powerPreference` | `DEFAULT` | GPU preference on multi-GPU systems. |
77
43
 
78
- ```ts
79
- import { Framework, FrameworkConfiguration, TextureSamplerFilteringPreset } from "ris-framework";
80
-
81
- const config = new FrameworkConfiguration();
82
- config.canvas = document.getElementById("game-canvas") as HTMLCanvasElement;
83
- config.textureFiltering = TextureSamplerFilteringPreset.BILINEAR;
44
+ Register listeners before `initialize()`. Load-content and initialized listeners run inside that call.
84
45
 
85
- const framework = new Framework(config);
86
- ```
46
+ ## Scenes, cameras and lights
87
47
 
88
- `src/main.ts` constructs the sample the same way, but it imports those three symbols from the source files under `src/` instead of from the package name.
48
+ ```ts
49
+ import { Color, DirectionalLight, PointLight, Scene } from "ris-framework";
89
50
 
90
- `framework.renderingBackend` is `RenderingBackend.WEB_GL`. After `initialize()`, `framework.graphicsDevice` is the renderer's WebGL2 device.
51
+ const scene = new Scene(framework);
91
52
 
53
+ // Passing the scene makes this the scene's camera.
54
+ const camera = framework.cameraFactory.createPerspectiveCamera({
55
+ aspectRatio: canvas.width / canvas.height,
56
+ eye: [0, 0, 3],
57
+ }, scene);
92
58
 
93
- ## From startup to the first frame
59
+ scene.activeAmbientLight.color = new Color(0.4, 0.4, 0.4);
60
+ // Lights take an optional scene; passing it adds them.
61
+ new DirectionalLight({ color: new Color(1, 1, 1), intensity: 0.8, direction: [-0.4, -0.6, 1] }, scene);
62
+ new PointLight({ color: new Color(1, 0.5, 0.2), intensity: 1.2, linear: 0.35, quadratic: 0.44 }, scene);
94
63
 
95
- `src/main.ts` is the current startup path. It still fills `#app` with the Vite starter page (logos and a heading) and then starts the framework on `#game-canvas`.
64
+ framework.addOnUpdateListener(time => {
65
+ camera.update(time);
66
+ scene.update(time);
67
+ });
68
+ framework.addOnRenderListener(() => scene.render());
69
+ ```
96
70
 
97
- Register listeners before `initialize()`. Load-content and initialized listeners run only inside that call. Update and render listeners stay on the loop, so a listener added later still runs on a following frame. `initialize()` does this:
71
+ `scene.add(item)` and `scene.remove(item)` accept a renderable mesh, a `SceneMesh`, a light or a camera. Blinn-Phong materials support up to 3 directional and 5 point lights.
98
72
 
99
- 1. Starts KTX2 initialization when `useKtx2` is set, without awaiting it.
100
- 2. Creates the WebGL2 context, swap chain, and default sampler, blend state, and primitive state.
101
- 3. Initializes the sprite batch (a default orthographic camera and a 1×1 white texture).
102
- 4. Initializes input. Mouse move, mouse buttons, and wheel events on the canvas update `framework.input.getMouseState()`. Touch start, move, end, and cancel events on the canvas update `framework.input.getTouchCollection()`, using the same viewport `clientX` / `clientY` coordinates as the mouse. A cancel is `TouchLocationState.CANCELLED`, which is not a finger lift. The canvas `touch-action` is set to `none`, and touch start and move call `preventDefault`, so the browser does not scroll or pinch-zoom that canvas.
103
- 5. Prepares the time manager.
104
- 6. Calls every `addOnLoadContentListener` callback. Async callbacks are not awaited.
105
- 7. Calls every `addOnInitializedListener` callback.
106
- 8. Creates the main render target at the canvas size and a swap-chain pass. The clear color at this moment is `Color.lightPink()`, the renderer default.
107
- 9. Subscribes an update callback and a render callback, then runs both once before returning. Later frames are scheduled with `requestAnimationFrame`.
73
+ ## Meshes and materials
108
74
 
109
- Each update calls `timeManager.frameStart()`, updates input, then calls `addOnUpdateListener` callbacks with that frame's `GameTime`. `src/main.ts` registers no update listener. Each render begins the main pass, calls `addOnRenderListener` callbacks, calls `spriteBatch.frameEnd()`, and presents.
75
+ - `IMesh` / `Mesh` hold geometry and the vertex and index buffers.
76
+ - `IRenderableMesh` / `RenderableMesh` add a material, an index range and sub meshes (`mesh.addSubMesh(material, start, count)` or `meshFactory.createWithSubMeshes`). The root mesh owns the transform and one model buffer, which all its sub meshes share.
77
+ - Transforms: `mesh.position`, `mesh.rotation` (Euler radians, applied Y, then X, then Z) and `mesh.scale`. `mesh.modelMatrix` is recomputed only when one of them changes.
78
+ - `SceneMesh`: `scene.add(mesh)` wraps a renderable mesh in a `SceneMesh`, which owns its materials. `sceneMesh.dispose()` and `scene.dispose()` dispose the mesh and each material once.
79
+ - Materials come from `framework.materialFactory`. They include unlit, `ForwardBlinnPhongMaterial` and `SpriteMaterial`.
110
80
 
111
- Before that call, `src/main.ts` registers the listeners below. The sample loads images, creates a nearest sampler, and draws with the sprite batch:
81
+ ## Loading OBJ/MTL
112
82
 
113
83
  ```ts
114
- import {
115
- Color,
116
- Rect,
117
- SamplerDescriptor,
118
- SamplerFilter,
119
- TextureDescriptor,
120
- TextureFormat,
121
- type ISampler,
122
- type ITexture2D,
123
- } from "ris-framework";
124
-
125
- const rect = new Rect(200, 200, 200, 200);
126
- const texRect = new Rect(500, 200, 200, 200);
127
- const color = Color.blue();
128
- const white = Color.white();
129
- let tex: ITexture2D;
130
- let sampler: ISampler;
131
-
132
- framework.addOnLoadContentListener(async () => {
133
- const texDesc = new TextureDescriptor();
134
- texDesc.generateMipmaps = true;
135
- texDesc.textureFormat = TextureFormat.RGBA_8_UNORM;
136
-
137
- tex = await framework.content.loadTexture2DAsync("/assets/test.png", texDesc);
138
- });
84
+ // Unlit or Blinn-Phong materials (one per usemtl), coloured from the .mtl.
85
+ const cube = await framework.content.loadBlinnPhongMeshAsync("/assets/cube.obj", camera);
86
+ const flat = await framework.content.loadUnlitMeshAsync("/assets/cube.obj", camera);
87
+ scene.add(cube);
139
88
 
140
- framework.addOnInitializedListener(() => {
141
- const desc = new SamplerDescriptor();
142
- desc.minFilter = SamplerFilter.NEAREST;
143
- desc.magFilter = SamplerFilter.NEAREST;
144
- sampler = framework.graphicsDevice.createSampler(desc);
145
- });
146
-
147
- framework.addOnRenderListener(() => {
148
- const spriteBatch = framework.spriteBatch;
149
- spriteBatch.begin(undefined, sampler);
150
- spriteBatch.drawRect(rect, color);
151
- if (tex != null) {
152
- spriteBatch.draw(tex, texRect, white);
153
- }
154
- spriteBatch.end();
89
+ // Lower level: pass a Blinn-Phong descriptor or a material factory per sub mesh.
90
+ const mesh = await framework.objLoader.loadAsync("/assets/cube.obj", {
91
+ projectionViewBuffer: camera.projectionViewBuffer,
92
+ cameraPositionBuffer: camera.positionBuffer,
155
93
  });
156
94
 
157
- framework.initialize();
158
- framework.renderer.clearColor = Color.lightPink();
95
+ // Geometry only, with no materials (GeometryFormat is exported from "ris-framework").
96
+ const geometry = await framework.content.loadMeshAsync("/assets/cube.obj", GeometryFormat.POS3_COLOR4_TEXTURECOORDS2);
159
97
  ```
160
98
 
161
- `loadTexture2DAsync(path, textureDescriptor?, contentConfig?)` is the image path used above. For a path that does not end in `.ktx2`, the descriptor's `textureFormat` is used when it is not `TextureFormat.UNDEFINED`; otherwise the renderer's preferred format is used. `generateMipmaps` is passed through. Width, height, pixel data, usage, label, and block size on that descriptor are not applied to this load. An optional `ContentConfig` only forwards `keepDataCached` to the image loader.
99
+ `ObjLoader.parseAsync(path)` and `ObjParser` return plain data without creating GPU resources.
162
100
 
163
- The first `begin` / `drawRect` / `end` runs inside `initialize()`, before the texture promise resolves, so the blue rectangle is the first draw. Later frames draw the texture once `tex` is set. `spriteBatch.begin` with no matrix keeps the default orthographic camera. The sampler argument overrides the device's default sampler for that batch. `drawRect` draws the 1×1 white texture tinted by `color`.
101
+ ## Textures and KTX2
164
102
 
165
- `src/main.ts` also loads `/assets/cat.jpg` the same way and draws it at `new Rect(200, 500, 200, 200)`. Those two files are absent from this repository. Put them under `public/assets/` before those loads can succeed. The blue rectangle still draws when the image loads fail.
103
+ ```ts
104
+ const png = await framework.content.loadTexture2DAsync("/assets/test.png");
105
+ const ktx = await framework.content.loadTexture2DAsync("/assets/kodim23.ktx2");
106
+ ```
166
107
 
167
- Setting `framework.renderer.clearColor` after `initialize()` updates later frames. The first frame has already cleared with the default light pink.
108
+ Paths ending in `.ktx2` are loaded through `ris-ktx2`.
168
109
 
169
- ## Scene
110
+ - **Basis Universal files** are transcoded to the best format the GPU supports, in this order: BC7, ASTC 4×4, BC3, ETC2, PVRTC, and RGBA8 as a last resort.
111
+ - **Other KTX2 files** are uploaded in their stored format.
112
+ - **sRGB:** sRGB files load as sRGB formats (`BC7_RGBA_SRGB`, `BC3_RGBA_SRGB`, `BC1_RGB_SRGB`, `ETC2_RGBA8_SRGB`, `ETC2_RGB8_SRGB`, `ASTC_*_RGBA_SRGB`, `RGBA_8_UNORM_SRGB`), so the GPU decodes them to linear.
113
+ - **sRGB fallback:** if `WEBGL_compressed_texture_s3tc_srgb` is missing, sRGB BC1 and BC3 textures fall back to linear with a warning.
170
114
 
171
- `new Scene(framework)` holds meshes, lights and the camera. `scene.add(item)` and `scene.remove(item)` accept a renderable mesh (wrapped in a `SceneMesh`, which owns and disposes its materials), an `AmbientLight`, `DirectionalLight`, `PointLight` or a camera; adding twice does nothing. Lights and the perspective camera given a scene in their constructor add themselves. Adding a camera makes it `scene.camera`; removing the active camera clears it. `scene.update(time)` hands the camera, the active ambient light and the scene's light lists (by reference) to the materials. `addLight`/`removeLight` remain as deprecated aliases.
115
+ `framework.graphicsDevice.features` reports compression support: `supportsTextureCompressionBC` (BPTC/BC7), `supportsTextureCompressionS3TC`, `supportsTextureCompressionS3TCSrgb`, `supportsTextureCompressionETC2`, `supportsTextureCompressionASTC` and `supportsTextureCompressionPVRTC`.
172
116
 
173
- Meshes follow the C# framework: `IMesh`/`Mesh` hold geometry and buffers only; `IRenderableMesh`/`RenderableMesh` add an optional material, an index range (`indexStart`, `indexCount`, -1 for all), sub meshes that share the root's buffers, and the transform with one model buffer per root. OBJ files load through `framework.objLoader`:
117
+ ## Sprites
174
118
 
175
119
  ```ts
176
- const mesh = await framework.objLoader.loadAsync(url, {
177
- projectionViewBuffer: camera.projectionViewBuffer,
178
- cameraPositionBuffer: camera.positionBuffer,
179
- }); // one ForwardBlinnPhongMaterial per usemtl material
180
- // or: framework.objLoader.loadAsync(url, subMesh => myMaterial(subMesh.material))
181
- // or: await ObjLoader.parseAsync(url) for plain data without GPU resources
182
- scene.add(mesh);
120
+ framework.addOnRenderListener(() => {
121
+ framework.spriteBatch.begin();
122
+ framework.spriteBatch.draw(texture, new Rect(200, 200, 200, 200), Color.white());
123
+ framework.spriteBatch.drawRect(new Rect(500, 200, 100, 100), Color.blue());
124
+ framework.spriteBatch.end();
125
+ });
183
126
  ```
184
127
 
185
- ## Examples
128
+ ## Examples and scripts
186
129
 
187
- Browser examples live in [`examples/`](examples/), one folder per example. See [`examples/README.md`](examples/README.md).
130
+ Examples live in [`examples/`](examples/): `unlit_mesh`, `blinn_phong_mesh` and `sprite_batch` (see [`examples/README.md`](examples/README.md)).
188
131
 
189
132
  ```sh
190
- npm run dev:examples # serve the examples index, e.g. /sprite_batch/
191
- npm run build:examples # build every example into examples/dist/
133
+ npm ci
134
+ npm run dev:examples # serve the examples
135
+ npm run build:examples # build them into examples/dist/
136
+ npm run dev # src/main.ts playground
137
+ npm test # type-check and Vitest
138
+ npm run build # library (dist/) and app build
192
139
  ```
193
140
 
194
- ## What is still unfinished
195
-
196
- These throw, or they accept a call and do not do the work the name suggests:
141
+ Requires Node.js 22 (or `^20.19.0`) and a WebGL2-capable browser.
197
142
 
198
- - `WindowManager.addOnResizeListener`, `removeOnResizeListener`, `initializeForWebGPU`, `initializeForWebGl`, and `dispose` throw `Method not implemented.` `title` and `windowBounds` are stored and never applied. There is no WebGPU backend.
199
- - `Framework.dispose()` is empty. It does not release the window, device, or GPU resources.
200
- - `renderer.beginComputePass()` and `renderer.endComputePass()` throw `Method not implemented.` `ARenderer.limits` throws the same error.
201
- - `graphicsDevice.setupDebugCallback()`, `frameEnd()`, `pushDebugGroup()`, and `popDebugGroup()` throw `Method not implemented.`
202
- - `ITexture2D.createView()` throws `Method not implemented.`
203
- - `content.loadShaderModule` only resolves the built-in ids `sprite`, `unlit_material`, `inspect_texture_mips`, and `main_render_target_flip_y`. Any other id throws `Not implemented`.
204
- - `SpriteBatch.draw` and `drawRect` accept rotation arguments and do not use them. `layerDepth` is written as the sprite's z position.
205
- - Keyboard and gamepad queries return empty state. `getKeyboardState()` is an empty `KeyboardState`. `getGamePadState()` is a disconnected `GamePadState`. `thumbstickDeadZone` is stored and not applied.
206
- - A render pass that enables stencil without depth throws `Not implemented`.
207
- - Paths ending in `.ktx2` go through `content.loadKtx2Async`, which uses its own `Ktx2Factory` and does not call `initializeAsync`. The libktx module is shared by every `Ktx2Factory`, so `loadAsync` works only after some factory has finished `initializeAsync()`. `useKtx2` starts that call in `initialize()` but does not wait for it. To load a `.ktx2` file, set `useKtx2`, await `framework.ktx2Factory.initializeAsync()` before `initialize()`, and then call `loadTexture2DAsync` from a load-content listener. `src/main.ts` does not load a `.ktx2` file.
208
- - The geometry and unlit-pipeline steps at the bottom of `src/main.ts` are comments. `geometryBuilder.quadGeometry()` can build quad data; the entry file does not upload it or draw it.
143
+ ## Known limitations
209
144
 
210
- ## Version
145
+ - Window resize listeners and compute passes throw `Method not implemented.`
146
+ - Keyboard and gamepad state are stubs.
147
+ - `SpriteBatch` ignores rotation.
211
148
 
212
- `package.json` `version` stays a release version with no prerelease suffix. It is `0.1.0`. Branch and publish rules are in [CONTRIBUTING.md](CONTRIBUTING.md).
149
+ Branch and publish rules are in [CONTRIBUTING.md](CONTRIBUTING.md). Changes are listed in [CHANGELOG.md](CHANGELOG.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ris-framework",
3
- "version": "0.2.0-dev.12",
3
+ "version": "0.2.0-dev.13",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",