# New and Noteworthy in OGRE 14
This is only a high level overview. For detailed changes, see the git changelog.

## Core changes
Following the removal of `UTFString` in Ogre 13, the generic data structures `AnyNumeric` and `HashedVector` were removed in order to reduce code complexity.
If you were using them, consider copying the code from Ogre 13 into your project.

The option to store tangents with `TEXCOORD` semantic was removed. The `TANGENT` semantic is now used unconditionally.

On GL, D3D11 and Vulkan VertexWinding is set in terms of FrontFace, so `gl_FrontFacing` and `SV_IsFrontFace` now behave as expected.

Object space bones are now enabled by default. Use `MeshManager::setBonesUseObjectSpace(false)` to go back to old behaviour.

All builtin Factory classes were made private. Replace `DefaultSceneManagerFactory::FACTORY_TYPE_NAME` by `SMT_DEFAULT` and e.g. `ManualObjectFactory::FACTORY_TYPE_NAME` by `MOT_MANUAL_OBJECT`.

Since 14.1, `ACT_MATERIAL_LOD_INDEX` is available to implement multiple material LOD levels in a single shader.

Since 14.3, textures defined in compositor scripts can explicitly set the FSAA level, e.g. `texture myTex fsaa 4`.

Since 14.3, `float16` vertex elements are supported via the `VET_HALFx` types. Note, that `VET_HALF3` is not supported on D3D11 and D3D9 and is padded to `VET_HALF4` on loading there.

Since 14.5, multi-sample textures are supported via the `TEX_TYPE_2D_MULTISAMPLE` texture type.

Since 14.5, `GpuProgramParameters::setUseLinearColours` can be used to specify that automatic sRGB to linear conversion should be applied to colour parameters when setting them.

Since 14.6, `GpuSharedParameters` may contain auto constants, which allows sharing automatically updated values across programs.

### OgreUnifiedShader.h

Sampler definitions now implicitly include the `uniform` keyword to support Vulkan; i.e. this will generate an error:

```cpp
uniform SAMPLER2D(sampler, 0);
// with Ogre 14 use:
SAMPLER2D(sampler, 0);
```

You opt-in to this syntax with Ogre 13, by defining `USE_OGRE_FROM_FUTURE` before including `OgreUnifiedShader.h`.

Since Ogre 14.5, relaxed precision (i.e. `mediump`) is used on Vulkan in fragment shaders to improve performance.
This means that shader code now behaves equivalently to OpenGL ES.
On D3D11, one can opt-in to this behaviour by defining `USE_OGRE_FROM_FUTURE` before including `OgreUnifiedShader.h`.

### Task-based WorkQueue

The WorkQueue API was changed from request/ response style to a task-based style.
I.e. instead of sending messages between threads, the actual work is send as a callback.

Or speaking with code, whereas before you would do:
```cpp
Root::getSingleton().getWorkQueue()->addRequest(mWorkQueueChannel, WORKQUEUE_DERIVED_DATA_REQUEST, data);
```

With the new API you do:
```cpp
Root::getSingleton().getWorkQueue()->addTask(
    [this, req]()
    {
        auto req = new WorkQueue::Request(0, 0, data, 0, 0);
        auto res = handleRequest(r, NULL);
        Root::getSingleton().getWorkQueue()->addMainThreadTask([this, res]() {
            handleResponse(res, NULL);
            delete res;
        });
    });
```

the new version might seem more lengthy, but actually it requires less code, while being more explicit.
There is neither a request handler nor a response handler interface that you must implement.
Also the WorkQueue-channel concept is gone.
Ultimately, the Request and Response classes are not necessary either and are here for illustrative purposes.

At this, the custom ticketing mechanism of `ResourceBackgroundQueue` was replaced by the more modern use of `std::future`.
So where you would previously do:
```cpp
Ogre::WorkQueue::RequestID ticket = rbq.prepare(tex->getCreator()->getType(), tex->getName(), tex->getGroup());
...
rbq.isProcessComplete(ticket);
```
you now do:
```cpp
auto future = rbq.prepare(tex);
...
future.wait_for(std::chrono::milliseconds(0));
```

### Transparent objects are now on their own render queue

Transparent objects are now put on the `RENDER_QUEUE_TRANSPARENTS` queue, which is rendered after `RENDER_QUEUE_SKIES_LATE`.
This fixes compatibility with late sky rendering, but more importantly makes transparent objects easily accessible from compositor scripts.

This simplifies many advanced algorithms, such as deferred shading, where you want to render transparent objects after the opaque ones.

### Breaking non-API changes

The second argument of `RenderQueueListener::renderQueueStarted` now contains the current camera name and hence is always non-empty.

### Rectangular Area Lights (since 14.1)

A new spot light type `LT_RECTLIGHT` has been introduced along with the `setSourceSize` method, enabling the rendering of rectangular area lights. In order to process this light type in your shader, verify that the `spotlight_params.w` autoparam is equal to 2. Then, `spotlight_params.xyz` contains the light width in the view space, and `light_attenuation.xyz` contains the light height.

### Mesh & Task Shaders (since 14.3)

The shader types `GPT_MESH_PROGRAM` and `GPT_TASK_PROGRAM` are now available, with support indicated by the `RSC_MESH_PROGRAM` capability. This functionality is provided in GL3Plus through the `GL_NV_mesh_shader` extension and in Vulkan via the `VK_NV_mesh_shader` extension.

### Enhanced Layered RenderTarget Support (since 14.4)

Version 14.4 introduces significant improvements for layered rendering:

**Compositor Textures:** You can now declare `2d_array` compositor textures, and individual layers can be targeted using the syntax `target myTex 1 {...`.

**Layered Shadow Samplers:** Support for `GCT_SAMPLER2DARRAYSHADOW` and `GCT_SAMPLERCUBESHADOW` was added, allowing the shadow mapping system to render directly to texture arrays and cubemaps. The assignment of lights to specific texture layers is controlled by `setShadowTextureCountPerLightType`. The count you provide dictates how layers are addressed; for instance, setting 6 textures for a point light will render its shadows across the faces of a cubemap.

**Rendering to All Layers (VPRT Targets):** `TU_RENDERTARGET` can now be combined with `TU_TARGET_ALL_LAYERS` to render to all layers of a texture array or cubemap. This is useful for rendering to multiple layers in a single pass, such as when rendering a environment map, doing PSSM shadow mapping, or doing side-by-side stereo rendering.

Additionally, you can check `RSC_VP_RT_INDEX_ANY_SHADER` to see if the rendering system supports efficient dispatch from vertex shaders, eliminating the need for a geometry shader.

### HDR Display (since 14.6)

The `hdrDisplay` option was added to the RenderSystem options (and as a window parameter). When enabled, the backbuffer is switched to FP16 and the scRGB colour space is requested.
This requires an HDR capable monitor with HDR enabled in the OS settings and is available on Windows with the GL, GLES2, D3D11 and Vulkan render systems.

### Hardened asset loading (since 14.6)

The mesh, skeleton, script, DDS/KTX and zip loading paths received extensive validation and bounds checking, driven by fuzz testing.
Recursive variable expansion, self-delegating unified shaders and self-inheriting materials are now detected and reported as script errors.

Loading of mesh formats older than v1.8 is disabled by default. Use `MeshSerializer::enablePre1_8Formats(true)` to re-enable it or run them through
`OgreMeshUpgrader`.

## Python

The double `ImGui` namespacing in `Ogre.ImGui` enums was removed; e.g. `ImGui.ImGuiWindowFlags_NoTitleBar` is now `ImGui.WindowFlags_NoTitleBar`.
Since 14.1, `Checkbox` and multidimensional input (e.g. `ColorEdit3` `InputFloat2`) are correctly wrapped.

Since 14.1, primitive types like `Ogre.Vector3`, `Ogre.ColourValue` etc. behave like Python sequences and can be used with `len()` and expanded `myfun(*Ogre.Quaternion())`.
Additionally, `Ogre.Degree` can be transparently used where `Ogre.Radian` is required.

Since 14.6, `PixelBox` requires a `memoryview` instead of a raw buffer. This enables 3D image formats through the bindings.

## Bites

Since 14.2 `ApplicationContextBase::runRenderingSettingsDialog()` is available, that displays an ImGui based dialog to change the rendering settings.
This replaces the platform specific `getNativeConfigDialog()` based dialogs which will be removed in a future release.

Additionally, there is `DrawRenderingSettings` in the overlay component, that allows you to integrate the dialog logic into your application. See the SampleBrowser for an example.

Since 14.6, Gizmo widgets are available to build custom editor tooling.

## RTShader System

The PSSM3, TriplanarTexturing and GBuffer sub-renderstates are now only configurable through the generic `setParameter()` method.

Light types are now dynamically handled inside the shader. Shader recompilation is no longer required when changing the light type.
Consequently, the `light_count` property now only takes a single count instead of a count per light type.

The default (FFP) sub-renderstates are now added to the scheme render state first instead of last. This means that you can inspect and modify them in the scheme render state.

The normal maps should now be specified at the `texture_unit` level instead of the `pass` level

```nginx
// with Ogre 13
pass
{
    rtshader_system
    {
        lighting_stage normal_map Panels_Normal_Tangent.png tangent_space 0 RTSS/NormalMapSampler
    }
}

// with Ogre 14
pass
{
    texture_unit
    {
        texture Panels_Normal_Tangent.png
        sampler_ref RTSS/NormalMapSampler
        rtshader_system
        {
            normal_map tangent_space
        }
    }
}
```

Additionally `parallax_occlusion` mapping is now supported by using the respective keyword. It is also available with the Terrain Component.

Since 14.5, the lighting can be done in linear space by setting `ShaderGenerator::setTargetLinearColours`. This is enabled automatically by the `ApplicationContext` when the sRGB gamma correction is enabled and by the CookTorrance sub-renderstate.

Since 14.6, `shared_params` can be referenced by sub-renderstates.

Since 14.6, the `metal_roughness` sub-renderstate supports an additional `occlusion` parameter to sample ambient occlusion from the R channel of the texture.

Since 14.6, clustered light culling (also known as Forward+) is available through the `SRS_CLUSTERED_LIGHT_CULLING` sub-renderstate.

Since 14.6, the distance attenuation is smoothed towards the light range to avoid a visible cut-off.

## Terrain

The TerrainMaterialGenerator API was simplified by making the use of a Profile optional.
Furthermore, the required TerrainLayer metadata was reduced to a minimum.
If you have a custom `TerrainMaterialGenerator`, you will need to update it.

## Bullet

A separate `CollisionWorld` wrapper was split off from `DynamicsWorld`, enabling the use of Bullet for collision detection only.

## MeshLodGenerator

The MeshLodGenerator now also support line primitives and correctly handles the boundaries between SubMeshes. The latter needs to be explicitly enabled, as it increases LOD generation time and is not required, if only a single submesh is used.

## MeshUpgrader

The interactive mode has been removed. Edge lists are no longer generated by default. Pass `-el` to generate them.

Since 14.2 the flag `-optvtxcache` is available to optimize the vertex cache utilization of a mesh.

Since 14.6, tangents are generated with parity by default.

## GL3Plus

Transform feedback outputs are now consistently named `xfb_position`, `xfb_uv0` instead of `oPos`, `oUv0`.
Shader updates are required.

On OSX, `texture2D` etc. functions are no longer implicitly upgraded to version 150 equivalents, explicitly `#include <GLSL_GL3Support.glsl>` to get them.

## Wayland support (since 14.3)

Ogre can now run on Wayland in Linux if compiled with `OGRE_USE_WAYLAND=TRUE`. This is supported across all GL and Vulkan render systems, as well as the OgreBites SDL2 integration.

## Vulkan on macOS (since 14.6)

The Vulkan render system can now be used on macOS via [MoltenVK](https://github.com/KhronosGroup/MoltenVK).
Window surfaces are created through the `VK_EXT_metal_surface` extension, so a Vulkan SDK (or a standalone
MoltenVK build) providing this extension is required at runtime.