<commit_before># Proposal for a new glTF-Sample-Viewer API and Design

The main goal of refactoring the glTF-Sample-Viewer API is to make it compatible with NodeJS by removing the strong dependency on the HTML user interface. Furthermore, it should be possible to load resources asynchroneously and independently from each other, thus avoiding a full reload of the sample viewer when one of the resources is changed.

Our proposal aims to separate the current interface into smaller components that can be called and used individually while keeping the underlying functionality intact.

## Components

The current `GltfViewer` object combines resource loading, render loop execution, UI binding and state management in one class. In the proposed API these responsibilities are separated into their own respective modules. 

### GltfView

The GltfView component is associated with one WebGL2 context. In practice this means it will be associated with one HTML5 Canvas. This component manages the interaction between the canvas and the GL context. For example it therefore specifies the viewport, the swapchain and can be used to schedule frame renders. 

```js
const view = new GltfView(canvas);
```

The view is also used to render frames, either on every window repaint event or on demand, e.g. when taking a frame capture.

```js
const finished = view.startRendering(state);
```

```js
const buffer = await view.renderToBuffer(state);
```

### GltfState

The GltfState is the view model for a GltfView. It is a complete description of the content that should be visible in the GltfView's associated canvas. You could create multiple states for one view and swap between them, e.g. when a resource is done loading. *As currently some WebGL resources are stored directly in the Gltf objects, the state cannot be shared between views.*

```js
const state = view.createState();
state.activeScene = 0;
state.activeAnimations = [0, 1, 2];
state.renderingOptions = { useIbl: false };
```

### ResourceLoader
<commit_msg>add headless GL example<commit_after># Proposal for a new glTF-Sample-Viewer API and Design

The main goal of refactoring the glTF-Sample-Viewer API is to make it compatible with NodeJS by removing the strong dependency on the HTML user interface. Furthermore, it should be possible to load resources asynchroneously and independently from each other, thus avoiding a full reload of the sample viewer when one of the resources is changed.

Our proposal aims to separate the current interface into smaller components that can be called and used individually while keeping the underlying functionality intact.

## Components

The current `GltfViewer` object combines resource loading, render loop execution, UI binding and state management in one class. In the proposed API these responsibilities are separated into their own respective modules. 

### GltfView

The GltfView component is associated with one WebGL2 context. In practice this means it will be associated with one HTML5 Canvas. This component manages the interaction between the canvas and the GL context. For example it therefore specifies the viewport, the swapchain and can be used to schedule frame renders. 

```js
const view = new GltfView(canvas);
```

One could also create a headless view with code like the following. *Note that the signature might change in the final API*

```js
const view = new GltfView(hedlessGlContext);
```

The view is also used to render frames, either on every window repaint event or on demand, e.g. when taking a frame capture.

```js
const finished = view.startRendering(state);
```

```js
const buffer = await view.renderToBuffer(state);
```

### GltfState

The GltfState is the view model for a GltfView. It is a complete description of the content that should be visible in the GltfView's associated canvas. You could create multiple states for one view and swap between them, e.g. when a resource is done loading. *As currently some WebGL resources are stored directly in the Gltf objects, the state cannot be shared between views.*

```js
const state = view.createState();
state.activeScene = 0;
state.activeAnimations = [0, 1, 2];
state.renderingOptions = { useIbl: false };
```

### ResourceLoader

{'fraction_non_alphanumeric': 0.05520018952854774, 'fraction_numerical': 0.0028429282160625444, 'mean_word_length': 4.76775956284153, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '664610', 'n_tokens_mistral': 1068, 'n_tokens_neox': 1008, 'n_words': 606}