<commit_before>## Gfx Module

The Oryol Gfx module provides a thin portability wrapper around a 
platform's native 3D APIs, with WebGL/OpenGLES2 on the low-end, and
D3D12 and (hopefully soon) Vulkan on the 'high-end'.


### Platform/API matrix

What 3D APIs are supported on which platforms:

Platform   |GL3.3|GLES2|Metal|D3D11|D3D12|Vulkan
-----------|-----|-----|-----|-----|-----|------
OSX 10.11+ |YES  |---  |YES  |---  |---  |---
iOS 9.x+   |---  |YES  |YES  |---  |---  |---
Window7+   |YES  |---  |---  |YES  |---  |MAYBE
Window10+  |YES  |---  |---  |YES  |YES  |MAYBE
Linux      |YES  |---  |---  |---  |---  |MAYBE
Android    |---  |YES  |---  |---  |---  |MAYBE
HTML5      |---  |YES  |---  |---  |---  |---
PNaCl      |---  |YES  |---  |---  |---  |---
RaspberryPi|---  |YES  |---  |---  |---  |---

### Use the Source, Luke!

The most important and detailed documentation of the Gfx module
is the Samples source code. I'm trying very hard to make
the sample code easy to read and understand.

Looking at those four samples should give you most of the
information necessary to work with the Gfx module:

* [Clear Sample](https://github.com/floooh/oryol/blob/master/code/Samples/Clear/Clear.cc)
* [Triangle Sample](https://github.com/floooh/oryol/blob/master/code/Samples/Triangle/Triangle.cc)
* [Shapes Sample](https://github.com/floooh/oryol/blob/master/code/Samples/Shapes/Shapes.cc)
* [Texture Loading](https://github.com/floooh/oryol/blob/master/code/Samples/DDSCubeMap/DDSCubeMap.cc)

The 'manual' documentation in here will focus more on 'filling the gaps',
background information and explaining design choices.

### Selecting a Rendering Backend

Rendering backends are selected at compile time through cmake options and
cannot be switched at runtime. Each target platform has a default rendering
backend that will be selected automatically, usually this is OpenGL.

The easiest way to select a non-default rendering backend is to
select a different **fips build config**:

To see the list of supported build configs for D3D11, D3D12 
and Metal:

```
> ./fips list configs | grep d3d11
...
> ./fips list configs | grep d3d12
...
> ./fips list configs | grep metal
...
```

For instance, to select an iOS build config using the Metal rendering backend:

```
> ./fips set config metal-ios-xcode-debug
'config' set to 'metal-ios-xcode-debug' in project 'oryol'
> ./fips gen
...
> ./fips open
...
```

Alternatively, the rendering backend can be selected by activating
cmake options directly in the cmake config tool:

```bash
> fips config
...
# the cmake options are:

ORYOL_USE_D3D11
ORYOL_USE_D3D12
ORYOL_USE_METAL
```

### Frame Rendering

Rendering through the Gfx module usually involves the following steps:

1. [Initialize the Gfx Module](#initialize-the-gfx-module)
2. [Create Resources](#resources)
3. [Apply Render Target and optionally Clear](#render-targets)
4. [Optional: Update Dynamic Resources](#dynamic-resources)
5. [Apply a DrawState and Textures](#drawstates)
6. [Apply Uniform Blocks](#uniformblocks)
7. [Draw](#draw-functions)
8. [Commit](#committing-the-frame)
9. [Shutdown the Gfx Module](#shutting-down)

### Initialize the Gfx Module

To initialize the Gfx module, include the header **"Gfx/Gfx.h"** and
call the **Gfx::Setup()** method. This will create the application window
and a 3D-API context:

```cpp
#include "Gfx/Gfx.h"
...
    Gfx::Setup(GfxSetup::Window(800, 600, "My Oryol App"));
```
This would create a 800x600 window titled "My Oryol App".

The GfxSetup object allows to configure and tweak the rendering system
for the specific needs of the Oryol application. Have a look at the
[Gfx/Gfx.h](https://github.com/floooh/oryol/blob/master/code/Modules/Gfx/Setup/GfxSetup.h)
header to see what's possible.

>NOTE: On some platforms (mostly mobile), the actual rendering 
resolution can be different from what the application requested. To
get the actual rendering resolution, call the **Gfx::DisplayAttrs()** after
the Gfx module has been initialized.

See also:
- [GfxSetup.h](https://github.com/floooh/oryol/blob/master/code/Modules/Gfx/Setup/GfxSetup.h)
- [Gfx.h](https://github.com/floooh/oryol/blob/master/code/Modules/Gfx/Gfx.h)

### Resources

Gfx resources are thin wrapper objects which manage the lifetime of an
underlying 3D-API specific rendering resource.

See also:
- [Resource Module](https://github.com/floooh/oryol/blob/master/code/Modules/Resource/README.md)

#### Resource Types

The Oryol Gfx module provides the following resource types:

1. [Meshes](#meshes): vertices, indices and primitive groups
2. [Textures](#textures): textures and offscreen-rendertargets
3. [Shaders](#shaders): vertex-shaders, fragment-shaders and shader parameters
4. [DrawStates](#drawstates): the complete state needed to issue draw-calls

The most important resource type is the DrawState, this bundles all static
state required for issuing draw calls. A DrawState takes one or several Meshes
and exactly one Shader as input, Textures are set together with a DrawState in
the Gfx::ApplyDrawState() call. Here's a diagram how the different resource
types are used together for rendering:

```
+--------------+
|              |
| 1..N Meshes  +-----+
|              |     |    +--------------+
+--------------+     |    |              |
                     +---->  DrawState   +----+
+--------------+     |    |              |    |
|              |     |    +--------------+    |
|    Shader    +-----+                        |
|              |                              |    +-------------------------+
+--------------+                              +---->  Gfx::ApplyDrawState()  |
                                              |    +------------+------------+
+---------------+                             |                 |
|               |                             |                 |
| 1..N Textures +-----------------------------+                 |
|               |                                  +------------v------------+
+---------------+                Shader Params+----> Gfx::ApplyUniformBlock()|
                                                   +------------+------------+
                                                                |
                                                                |
                                                   +------------v------------+
                                                   |       Gfx::Draw()       |
                                                   +-------------------------+
```

Most simple rendering scenarios will only use a single input Mesh. Using
multiple meshes is required for hardware-instanced rendering, and may 
be useful in other advanced scenarios, for instance one part of the
vertex data is dynamic and another part is static.

The main reason why Meshes and Shaders are separate resource
objects, and not directly defined as part of a DrawState is reusability.
A single Mesh or Shader can be used by many DrawStates.

The reason why Textures are not baked into DrawStates at all is to prevent
combinatorial explosions for the number of required DrawState object in some 
usage scenarios like using a cascade of offscreen render targets which are
then used as textures later in the rendering cascade.

Finally, modern rendering APIs have a lot of restrictions for dynamic state
that could change unpredictably during rendering. The relationship
between different resources and their memory layout is very
rigid and must be defined upfront. 

So basically, the way resources and their relationships are defined in the
Oryol Gfx module is a compromise between keeping the whole system simple, the
requirements of modern 3D APIs, and the restrictions of the low-end APIs (WebGL
and OpenGLES2).

See also:<commit_msg>More Gfx documentation tweaks<commit_after>## Gfx Module

The Oryol Gfx module provides a thin portability wrapper around a 
platform's native 3D APIs, with WebGL/OpenGLES2 on the low-end, and
D3D12 and (hopefully soon) Vulkan on the 'high-end'.


### Platform/API matrix

What 3D APIs are supported on which platforms:

Platform   |GL3.3|GLES2|Metal|D3D11|D3D12|Vulkan
-----------|-----|-----|-----|-----|-----|------
OSX 10.11+ |YES  |---  |YES  |---  |---  |---
iOS 9.x+   |---  |YES  |YES  |---  |---  |---
Window7+   |YES  |---  |---  |YES  |---  |MAYBE
Window10+  |YES  |---  |---  |YES  |YES  |MAYBE
Linux      |YES  |---  |---  |---  |---  |MAYBE
Android    |---  |YES  |---  |---  |---  |MAYBE
HTML5      |---  |YES  |---  |---  |---  |---
PNaCl      |---  |YES  |---  |---  |---  |---
RaspberryPi|---  |YES  |---  |---  |---  |---

### Use the Source, Luke!

The most important and detailed documentation of the Gfx module
is the Samples source code. I'm trying very hard to make
the sample code easy to read and understand.

Looking at those four samples should give you most of the
information necessary to work with the Gfx module:

* [Clear Sample](https://github.com/floooh/oryol/blob/master/code/Samples/Clear/Clear.cc)
* [Triangle Sample](https://github.com/floooh/oryol/blob/master/code/Samples/Triangle/Triangle.cc)
* [Shapes Sample](https://github.com/floooh/oryol/blob/master/code/Samples/Shapes/Shapes.cc)
* [Texture Loading](https://github.com/floooh/oryol/blob/master/code/Samples/DDSCubeMap/DDSCubeMap.cc)

The 'manual' documentation in here will focus more on 'filling the gaps',
background information and explaining design choices.

### Selecting a Rendering Backend

Rendering backends are selected at compile time through cmake options and
cannot be switched at runtime. Each target platform has a default rendering
backend that will be selected automatically, usually this is OpenGL.

The easiest way to select a non-default rendering backend is to
select a different **fips build config**:

To see the list of supported build configs for D3D11, D3D12 
and Metal:

```
> ./fips list configs | grep d3d11
...
> ./fips list configs | grep d3d12
...
> ./fips list configs | grep metal
...
```

For instance, to select an iOS build config using the Metal rendering backend:

```
> ./fips set config metal-ios-xcode-debug
'config' set to 'metal-ios-xcode-debug' in project 'oryol'
> ./fips gen
...
> ./fips open
...
```

Alternatively, the rendering backend can be selected by activating
cmake options directly in the cmake config tool:

```bash
> fips config
...
# the cmake options are:

ORYOL_USE_D3D11
ORYOL_USE_D3D12
ORYOL_USE_METAL
```

### Frame Rendering

Rendering through the Gfx module usually involves the following steps:

1. [Initialize the Gfx Module](#initialize-the-gfx-module)
2. [Create Resources](#resources)
3. [Apply Render Target and optionally Clear](#render-targets)
4. [Optional: Update Dynamic Resources](#dynamic-resources)
5. [Apply a DrawState and Textures](#drawstates)
6. [Apply Uniform Blocks](#uniformblocks)
7. [Draw](#draw-functions)
8. [Commit](#committing-the-frame)
9. [Shutdown the Gfx Module](#shutting-down)

### Initialize the Gfx Module

To initialize the Gfx module, include the header **"Gfx/Gfx.h"** and
call the **Gfx::Setup()** method. This will create the application window
and a 3D-API context:

```cpp
#include "Gfx/Gfx.h"
...
    Gfx::Setup(GfxSetup::Window(800, 600, "My Oryol App"));
```
This would create a 800x600 window titled "My Oryol App".

The GfxSetup object allows to configure and tweak the rendering system
for the specific needs of the Oryol application. Have a look at the
[Gfx/Gfx.h](https://github.com/floooh/oryol/blob/master/code/Modules/Gfx/Setup/GfxSetup.h)
header to see what's possible.

>NOTE: On some platforms (mostly mobile), the actual rendering 
resolution can be different from what the application requested. To
get the actual rendering resolution, call the **Gfx::DisplayAttrs()** method after
the Gfx module has been initialized.

See also:
- [GfxSetup.h](https://github.com/floooh/oryol/blob/master/code/Modules/Gfx/Setup/GfxSetup.h)
- [Gfx.h](https://github.com/floooh/oryol/blob/master/code/Modules/Gfx/Gfx.h)

### Resources

Gfx resources are thin wrapper objects which manage the lifetime of an
underlying 3D-API specific rendering resource.

See also:
- [Resource Module](https://github.com/floooh/oryol/blob/master/code/Modules/Resource/README.md)

#### Resource Types

The Oryol Gfx module provides the following resource types:

1. [Meshes](#meshes): vertices, indices and primitive groups
2. [Textures](#textures): textures and offscreen-rendertargets
3. [Shaders](#shaders): vertex-shaders, fragment-shaders and shader parameters
4. [DrawStates](#drawstates): the complete state needed to issue draw-calls

The most important resource type is the DrawState, this bundles all static
state required for issuing draw calls. A DrawState takes one or several Meshes
and exactly one Shader as input, Textures are set together with a DrawState in
the Gfx::ApplyDrawState() call. Here's a diagram how the different resource
types are used together for rendering:

```
+--------------+
|              |
| 1..N Meshes  +-----+
|              |     |    +--------------+
+--------------+     |    |              |
                     +---->  DrawState   +----+
+--------------+     |    |              |    |
|              |     |    +--------------+    |
|    Shader    +-----+                        |
|              |                              |    +-------------------------+
+--------------+                              +---->  Gfx::ApplyDrawState()  |
                                              |    +------------+------------+
+---------------+                             |                 |
|               |                             |                 |
| 1..N Textures +-----------------------------+                 |
|               |                                  +------------v------------+
+---------------+                Shader Params+----> Gfx::ApplyUniformBlock()|
                                                   +------------+------------+
                                                                |
                                                                |
                                                   +------------v------------+
                                                   |       Gfx::Draw()       |
                                                   +-------------------------+
```

Most simple rendering scenarios will only use a single input Mesh. Using
multiple meshes is required for hardware-instanced rendering, and may 
be useful in other advanced scenarios, for instance if one part of the
vertex data is dynamic and another part is static.

The main reason why Meshes and Shaders are separate resource
objects, and not directly defined as part of a DrawState is reusability.
A single Mesh or Shader can be used by many different DrawStates.

The reason why Textures are not baked into DrawStates at all is to prevent
combinatorial explosions for the number of required DrawState object in some 
usage scenarios like using a cascade of offscreen render targets which are
then used as textures later in the rendering cascade.

Finally, modern rendering APIs have a lot of restrictions for dynamic state
that could change unpredictably during rendering. The relationship
between different resources and their memory layout is very
rigid and must be defined upfront. 

So basically, the way resources and their relationships have been designed in the
Oryol Gfx module is a compromise between keeping the whole system simple, the
requirements of modern 3D APIs, and the restrictions of the low-end APIs (WebGL
and OpenGLES2).

See also:
{'fraction_non_alphanumeric': 0.14537529645535543, 'fraction_numerical': 0.009358374463175438, 'mean_word_length': 2.098093725178713, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 16, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 44, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4901598', 'n_tokens_mistral': 4490, 'n_tokens_neox': 4213, 'n_words': 1568}