diff --git a/.github/workflows/pip-build.yml b/.github/workflows/pip-build.yml index 9f5912021a5..38a8f089df7 100644 --- a/.github/workflows/pip-build.yml +++ b/.github/workflows/pip-build.yml @@ -41,8 +41,8 @@ jobs: shell: bash - name: Install Dependencies run: | - curl -LO https://sdk.lunarg.com/sdk/download/1.3.224.1/windows/VulkanSDK-1.3.224.1-Installer.exe - .\VulkanSDK-1.3.224.1-Installer.exe --accept-licenses --default-answer --confirm-command install + curl -LO https://sdk.lunarg.com/sdk/download/1.3.275.0/windows/VulkanSDK-1.3.275.0-Installer.exe + .\VulkanSDK-1.3.275.0-Installer.exe --accept-licenses --default-answer --confirm-command install - name: Build run: | python -m pip install --upgrade pip==24.0 @@ -50,7 +50,7 @@ jobs: pip wheel . --verbose python -m twine upload --repository pypi *.whl env: - VULKAN_SDK: C:\VulkanSDK\1.3.224.1 + VULKAN_SDK: C:\VulkanSDK\1.3.275.0 SKBUILD_BUILD_OPTIONS: -j4 macos: runs-on: macos-12 diff --git a/BuildingOgre.md b/BuildingOgre.md index 8681246b6a2..b61fd662841 100644 --- a/BuildingOgre.md +++ b/BuildingOgre.md @@ -77,20 +77,27 @@ The optional dependencies will enable input handling and allow building the docu * SDL: https://www.libsdl.org/ * zlib: http://www.zlib.net * freetype: http://www.freetype.org +* googletest: https://github.com/google/googletest ### Optional dependencies * DirectX SDK: http://msdn.microsoft.com/en-us/directx/ * Vulkan SDK: https://vulkan.lunarg.com/ -* FreeImage: http://freeimage.sourceforge.net * Doxygen: http://doxygen.org -* Cg: http://developer.nvidia.com/object/cg_toolkit.html * Remotery: https://github.com/Celtoys/Remotery * SWIG: http://www.swig.org/ * %Assimp: https://www.assimp.org/ * Wayland: https://wayland.freedesktop.org/ +* Rust: https://www.rust-lang.org/ +* Bullet: https://pybullet.org/wordpress/ + +### Deprecated dependencies + +* FreeImage: http://freeimage.sourceforge.net +* Cg: http://developer.nvidia.com/object/cg_toolkit.html +* OpenEXR: http://www.openexr.com -Running CMake +Running CMake {#running-cmake} ------------- Now start the program cmake-gui by either typing the name in a console @@ -147,7 +154,7 @@ This will freshly generate the API documentation for Ogre's classes from the hea make OgreDoc -Installing +Installing {#installing-sdk} ---------- Once the build is complete, the libraries and headers must be copied to a clean location. @@ -177,8 +184,8 @@ The ogre port in vcpkg is kept up to date by Microsoft team members and communit # Cross-Compiling -Building on Ubuntu for Android --------------------------------------------- +Android +------- To build Ogre for Android, you need to specify the android cross toolchain to cmake as @@ -190,8 +197,8 @@ You can now import these projects in Android Studio or manually trigger the APK gradle assembleRelease -Building for WebAssembly (using Emscripten) ------------------------------------------ +WebAssembly / Emscripten +------------------------ Install the Emscripten SDK (see full documentation on [www.emscripten.org](https://emscripten.org/docs/getting_started/downloads.html)), and make sure that the environment variables are correctly set (eg. run `source /emsdk_env.sh` before attempting to build) @@ -207,8 +214,8 @@ This will not build the full SampleBrowser, but just a minimal Sample. The resul To prevent any cross-origin issues, start a local webserver as `python3 -m http.server 8000` and visit http://localhost:8000. -Building on Mac OS X for iOS OS -------------------------------- +iOS OS +------ To build Ogre for iOS, you need to specify the ios cross toolchain to cmake as @@ -233,8 +240,8 @@ the Info.plist file to match the App ID of the chosen code signing identity. This can be done from the Target Properties panel. It must match the bundle identifier of a valid developer certificate if you are building for devices. -Building as Windows Store or Windows Phone application -------------------------------------------------------------------- +WinRT / UWP +------------------------------ You need Windows 8.0 or later, Windows 10 is recommended. diff --git a/CMakeLists.txt b/CMakeLists.txt index ade278ef338..c5d23d7ee8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,7 @@ if (APPLE AND NOT ANDROID AND NOT EMSCRIPTEN AND NOT ANDROID_PLATFORM) add_definitions(-D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0) endif () -project(OGRE VERSION 14.3.0) +project(OGRE VERSION 14.3.1) # extra version info set(OGRE_VERSION_SUFFIX "") diff --git a/Docs/src/high-level-programs.md b/Docs/src/high-level-programs.md index ae4b635e9b2..3e64735d88b 100644 --- a/Docs/src/high-level-programs.md +++ b/Docs/src/high-level-programs.md @@ -227,7 +227,7 @@ The available varyings are: The following features are only available when using the legacy OpenGL profile. Notably they are not available with GL3+ or GLES2. ### OpenGL state -GLSL can access most of the GL states directly so you do not need to pass these states through [param\_named\_auto](#param_005fnamed_005fauto) in the material script. This includes lights, material state, and all the matrices used in the openGL state i.e. model view matrix, worldview projection matrix etc. +GLSL can access most of the GL states directly so you do not need to pass these states through [param_named_auto](#param_005fnamed_005fauto) in the material script. This includes lights, material state, and all the matrices used in the openGL state i.e. model view matrix, worldview projection matrix etc. ### Built-in attributes GLSL natively supports automatic binding of the most common incoming per-vertex attributes (e.g. `gl_Vertex`, `gl_Normal`, `gl_MultiTexCoord0` etc) @@ -557,11 +557,11 @@ At runtime, when myVertexProgram or myFragmentProgram are used, OGRE automatical Parameters can be specified using one of 4 commands as shown below. The same syntax is used whether you are defining a parameter just for this particular use of the program, or when specifying the @ref Default-Program-Parameters. Parameters set in the specific use of the program override the defaults. -- [param\_indexed](#param_005findexed) -- [param\_indexed\_auto](#param_005findexed_005fauto) -- [param\_named](#param_005fnamed) -- [param\_named\_auto](#param_005fnamed_005fauto) -- [shared\_params\_ref](#shared_005fparams_005fref) +- [param_indexed](#param_005findexed) +- [param_indexed_auto](#param_005findexed_005fauto) +- [param_named](#param_005fnamed) +- [param_named_auto](#param_005fnamed_005fauto) +- [shared_params_ref](#shared_005fparams_005fref) @@ -595,7 +595,7 @@ Format: param\_indexed\_auto <index> <autoConstType> <extraInfo&g Example: param\_indexed\_auto 0 worldviewproj\_matrix @param index -has the same meaning as [param\_indexed](#param_005findexed); note this time you do not have to specify the size of the parameter because the engine knows this already. In the example, the world/view/projection matrix is being used so this is implicitly a matrix4x4. +has the same meaning as [param_indexed](#param_005findexed); note this time you do not have to specify the size of the parameter because the engine knows this already. In the example, the world/view/projection matrix is being used so this is implicitly a matrix4x4. @param autoConstType, extraInfo is one of Ogre::GpuProgramParameters::AutoConstantType without the `ACT_` prefix. E.g. `ACT_WORLD_MATRIX` becomes `world_matrix`. @@ -623,7 +623,7 @@ Format: param\_named\_auto <name> <autoConstType> <extraInfo> @par Example: param\_named\_auto worldViewProj worldviewproj\_matrix -The allowed @c autoConstType and the meaning of @c extraInfo are detailed in [param\_indexed\_auto](#param_005findexed_005fauto). +The allowed @c autoConstType and the meaning of @c extraInfo are detailed in [param_indexed_auto](#param_005findexed_005fauto). @@ -649,7 +649,7 @@ shared_params YourSharedParamsName } ``` -As you can see, you need to use the keyword ’shared\_params’ and follow it with the name that you will use to identify these shared parameters. Inside the curly braces, you can define one parameter per line, in a way which is very similar to the [param\_named](#param_005fnamed) syntax. The definition of these lines is: +As you can see, you need to use the keyword ’shared\_params’ and follow it with the name that you will use to identify these shared parameters. Inside the curly braces, you can define one parameter per line, in a way which is very similar to the [param_named](#param_005fnamed) syntax. The definition of these lines is: @par Format: shared\_param\_named <param\_name> <param\_type> \[<\[array\_size\]>\] \[<initial\_values>\] @@ -658,7 +658,7 @@ Format: shared\_param\_named <param\_name> <param\_type> \[<\[arr @param array_size allows you to define arrays of param\_type should you wish, and if present must be a number enclosed in square brackets (and note, must be separated from the param\_type with whitespace). @param initial_values If you wish, you can also initialise the parameters by providing a list of values. -Once you have defined the shared parameters, you can reference them inside default\_params and params blocks using [shared\_params\_ref](#shared_005fparams_005fref). You can also obtain a reference to them in your code via Ogre::GpuProgramManager::getSharedParameters, and update the values for all instances using them. +Once you have defined the shared parameters, you can reference them inside default\_params and params blocks using [shared_params_ref](#shared_005fparams_005fref). You can also obtain a reference to them in your code via Ogre::GpuProgramManager::getSharedParameters, and update the values for all instances using them. ## Hardware Support diff --git a/Docs/src/manual.md b/Docs/src/manual.md index da7b04fc5d6..52054856ec0 100644 --- a/Docs/src/manual.md +++ b/Docs/src/manual.md @@ -391,7 +391,7 @@ mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); 2. Create one or more lights. Note that not all light types are necessarily supported by all shadow techniques, you should check the sections about each technique to check. Note that if certain lights should not cast shadows, you can turn that off by calling setCastShadows(false) on the light, the default is true. 3. Disable shadow casting on objects which should not cast shadows. Call setCastShadows(false) on objects you don’t want to cast shadows, the default for all objects is to cast shadows. 4. Configure shadow far distance. You can limit the distance at which shadows are considered for performance reasons, by calling Ogre::SceneManager::setShadowFarDistance. -5. Turn off the receipt of shadows on materials that should not receive them. You can turn off the receipt of shadows (note, not the casting of shadows - that is done per-object) by calling Material::setReceiveShadows or using the receive\_shadows material attribute. This is useful for materials which should be considered self-illuminated for example. Note that transparent materials are typically excluded from receiving and casting shadows, although see the [transparency\_casts\_shadows](#transparency_005fcasts_005fshadows) option for exceptions. +5. Turn off the receipt of shadows on materials that should not receive them. You can turn off the receipt of shadows (note, not the casting of shadows - that is done per-object) by calling Material::setReceiveShadows or using the receive\_shadows material attribute. This is useful for materials which should be considered self-illuminated for example. Note that transparent materials are typically excluded from receiving and casting shadows, although see the [transparency_casts_shadows](#transparency_005fcasts_005fshadows) option for exceptions. # Opting out of shadows {#Opting-out-of-shadows} diff --git a/Docs/src/material-scripts.md b/Docs/src/material-scripts.md index b778aaa805f..a57dd5017e6 100644 --- a/Docs/src/material-scripts.md +++ b/Docs/src/material-scripts.md @@ -90,7 +90,7 @@ Default: lod\_strategy distance_sphere ## lod\_values -This attribute defines the values used to control the LOD transition for this material. By setting this attribute, you indicate that you want this material to alter the Technique that it uses based on some metric, such as the distance from the camera, or the approximate screen space coverage. The exact meaning of these values is determined by the option you select for [lod\_strategy](#lod_005fstrategy) - it is a list of distances for the @c distance_sphere strategy, and a list of pixel counts for the @c pixel_count strategy, for example. You must give it a list of values, in order from highest LOD value to lowest LOD value, each one indicating the point at which the material will switch to the next LOD. All materials automatically activate LOD index 0 for values less than the first entry, so you don't have to explicitly specify this. Additionally, if there is no technique that matches the active LOD index, a technique with a lower LOD index will be used instead. Therefore, it is important to always have at least one technique with LOD index 0. +This attribute defines the values used to control the LOD transition for this material. By setting this attribute, you indicate that you want this material to alter the Technique that it uses based on some metric, such as the distance from the camera, or the approximate screen space coverage. The exact meaning of these values is determined by the option you select for [lod_strategy](#lod_005fstrategy) - it is a list of distances for the @c distance_sphere strategy, and a list of pixel counts for the @c pixel_count strategy, for example. You must give it a list of values, in order from highest LOD value to lowest LOD value, each one indicating the point at which the material will switch to the next LOD. All materials automatically activate LOD index 0 for values less than the first entry, so you don't have to explicitly specify this. Additionally, if there is no technique that matches the active LOD index, a technique with a lower LOD index will be used instead. Therefore, it is important to always have at least one technique with LOD index 0. @par Format: lod\_values <value0> <value1> <value2> ... @@ -106,7 +106,7 @@ The above example would cause the material to use the best Technique at lod\_ind ## lod\_distances -@deprecated This option is deprecated in favour of [lod\_values](#lod_005fvalues) now. +@deprecated This option is deprecated in favour of [lod_values](#lod_005fvalues) now. @@ -148,7 +148,7 @@ A "technique" section in your material script encapsulates a single method of re When a material is used for the first time, it is ’compiled’. That involves scanning the techniques which have been defined, and marking which of them are supportable using the current rendering API and graphics card. If no techniques are supportable, your material will render as blank white. The compilation examines a number of things, such as: -- The number of texture\_unit entries in each pass
Note that if the number of texture\_unit entries exceeds the number of texture units in the current graphics card, the technique may still be supportable so long as a fragment program is not being used. In this case, Ogre will split the pass which has too many entries into multiple passes for the less capable card, and the multitexture blend will be turned into a multipass blend (See [colour\_op\_multipass\_fallback](#colour_005fop_005fmultipass_005ffallback)). +- The number of texture\_unit entries in each pass
Note that if the number of texture\_unit entries exceeds the number of texture units in the current graphics card, the technique may still be supportable so long as a fragment program is not being used. In this case, Ogre will split the pass which has too many entries into multiple passes for the less capable card, and the multitexture blend will be turned into a multipass blend (See [colour_op_multipass_fallback](#colour_005fop_005fmultipass_005ffallback)). - Whether vertex, geometry or fragment programs are used, and if so which syntax they use (e.g. vs\_1\_1, ps\_2\_x, arbfp1 etc.) - Other effects like cube mapping and dot3 blending - Whether the vendor or device name of the current graphics card matches some user-specified rules @@ -165,11 +165,11 @@ Format: technique name Techniques have only a small number of attributes of their own: - [scheme](#scheme) -- [lod\_index](#lod_005findex) (and also see [lod\_distances](#lod_005fdistances) in the parent material) -- [shadow\_caster\_material](#shadow_005fcaster_005fmaterial) -- [shadow\_receiver\_material](#shadow_005freceiver_005fmaterial) -- [gpu\_vendor\_rule](#gpu_005fvendor_005frule) -- [gpu\_device\_rule](#gpu_005fdevice_005frule) +- [lod_index](#lod_005findex) (and also see [lod_distances](#lod_005fdistances) in the parent material) +- [shadow_caster_material](#shadow_005fcaster_005fmaterial) +- [shadow_receiver_material](#shadow_005freceiver_005fmaterial) +- [gpu_vendor_rule](#gpu_005fvendor_005frule) +- [gpu_device_rule](#gpu_005fdevice_005frule) @@ -260,37 +260,37 @@ Here are the attributes you can use in a ’pass’ section of a .material scrip - [diffuse](#diffuse) - [specular](#specular) - [emissive](#emissive) -- [scene\_blend](#scene_005fblend) -- [separate\_scene\_blend](#separate_005fscene_005fblend) -- [scene\_blend\_op](#scene_005fblend_005fop) -- [separate\_scene\_blend\_op](#separate_005fscene_005fblend_005fop) -- [depth\_check](#depth_005fcheck) -- [depth\_write](#depth_005fwrite) -- [depth\_func](#depth_005ffunc) -- [depth\_bias](#depth_005fbias) -- [iteration\_depth\_bias](#iteration_005fdepth_005fbias) -- [alpha\_rejection](#alpha_005frejection) -- [alpha\_to\_coverage](#alpha_005fto_005fcoverage) -- [light\_scissor](#light_005fscissor) -- [light\_clip\_planes](#light_005fclip_005fplanes) -- [illumination\_stage](#illumination_005fstage) -- [transparent\_sorting](#transparent_005fsorting) -- [cull\_hardware](#cull_005fhardware) -- [cull\_software](#cull_005fsoftware) +- [scene_blend](#scene_005fblend) +- [separate_scene_blend](#separate_005fscene_005fblend) +- [scene_blend_op](#scene_005fblend_005fop) +- [separate_scene_blend_op](#separate_005fscene_005fblend_005fop) +- [depth_check](#depth_005fcheck) +- [depth_write](#depth_005fwrite) +- [depth_func](#depth_005ffunc) +- [depth_bias](#depth_005fbias) +- [iteration_depth_bias](#iteration_005fdepth_005fbias) +- [alpha_rejection](#alpha_005frejection) +- [alpha_to_coverage](#alpha_005fto_005fcoverage) +- [light_scissor](#light_005fscissor) +- [light_clip_planes](#light_005fclip_005fplanes) +- [illumination_stage](#illumination_005fstage) +- [transparent_sorting](#transparent_005fsorting) +- [cull_hardware](#cull_005fhardware) +- [cull_software](#cull_005fsoftware) - [lighting](#lighting) - [shading](#shading) -- [polygon\_mode](#polygon_005fmode) -- [polygon\_mode\_overrideable](#polygon_005fmode_005foverrideable) -- [fog\_override](#fog_005foverride) -- [colour\_write](#colour_005fwrite) -- [max\_lights](#max_005flights) -- [start\_light](#start_005flight) +- [polygon_mode](#polygon_005fmode) +- [polygon_mode_overrideable](#polygon_005fmode_005foverrideable) +- [fog_override](#fog_005foverride) +- [colour_write](#colour_005fwrite) +- [max_lights](#max_005flights) +- [start_light](#start_005flight) - [iteration](#iteration) -- [point\_size](#point_005fsize) -- [point\_sprites](#point_005fsprites) -- [point\_size\_attenuation](#point_005fsize_005fattenuation) -- [point\_size\_min](#point_005fsize_005fmin) -- [point\_size\_max](#point_005fsize_005fmax) +- [point_size](#point_005fsize) +- [point_sprites](#point_005fsprites) +- [point_size_attenuation](#point_005fsize_005fattenuation) +- [point_size_min](#point_005fsize_005fmin) +- [point_size_max](#point_005fsize_005fmax) - [line_width](#line_width) @@ -419,25 +419,25 @@ Example: scene\_blend one one\_minus\_dest\_alpha @par Default: scene\_blend one zero (opaque) -Also see [separate\_scene\_blend](#separate_005fscene_005fblend). +Also see [separate_scene_blend](#separate_005fscene_005fblend). ## separate\_scene\_blend -This option operates in exactly the same way as [scene\_blend](#scene_005fblend), except that it allows you to specify the operations to perform between the rendered pixel and the frame buffer separately for colour and alpha components. By nature this option is only useful when rendering to targets which have an alpha channel which you’ll use for later processing, such as a render texture. +This option operates in exactly the same way as [scene_blend](#scene_005fblend), except that it allows you to specify the operations to perform between the rendered pixel and the frame buffer separately for colour and alpha components. By nature this option is only useful when rendering to targets which have an alpha channel which you’ll use for later processing, such as a render texture. @par Format1: separate\_scene\_blend <simple\_colour\_blend> <simple\_alpha\_blend> @par Example: separate\_scene\_blend add modulate -This example would add colour components but multiply alpha components. The blend modes available are as in [scene\_blend](#scene_005fblend). The more advanced form is also available: +This example would add colour components but multiply alpha components. The blend modes available are as in [scene_blend](#scene_005fblend). The more advanced form is also available: @par Format2: separate\_scene\_blend <colour\_src\_factor> <colour\_dest\_factor> <alpha\_src\_factor> <alpha\_dest\_factor> @par Example: separate\_scene\_blend one one\_minus\_dest\_alpha one one -Again the options available in the second format are the same as those in the second format of [scene\_blend](#scene_005fblend). +Again the options available in the second format are the same as those in the second format of [scene_blend](#scene_005fblend). @@ -457,7 +457,9 @@ You may change this to ’add’, ’subtract’, ’reverse_subtract’, ’min This directive is as scene\_blend\_op, except that you can set the operation for colour and alpha separately. @par -Format: separate\_scene\_blend\_op <colourOp> <alphaOp> Default: separate\_scene\_blend\_op add add +Format: separate\_scene\_blend\_op <colourOp> <alphaOp> +@par +Default: separate\_scene\_blend\_op add add @@ -510,13 +512,13 @@ Format: depth\_bias <constantBias> \[<slopeScaleBias>\] @copydetails Ogre::Pass::setDepthBias -Also see [iteration\_depth\_bias](#iteration_005fdepth_005fbias) +Also see [iteration_depth_bias](#iteration_005fdepth_005fbias) ## iteration\_depth\_bias -Sets an additional bias derived from the number of times a given pass has been iterated. Operates just like [depth\_bias](#depth_005fbias) except that it applies an additional bias factor to the base depth\_bias value, multiplying the provided value by the number of times this pass has been iterated before, through one of the [iteration](#iteration) variants. So the first time the pass will get the depth\_bias value, the second time it will get depth\_bias + iteration\_depth\_bias, the third time it will get depth\_bias + iteration\_depth\_bias \* 2, and so on. The default is zero. +Sets an additional bias derived from the number of times a given pass has been iterated. Operates just like [depth_bias](#depth_005fbias) except that it applies an additional bias factor to the base depth\_bias value, multiplying the provided value by the number of times this pass has been iterated before, through one of the [iteration](#iteration) variants. So the first time the pass will get the depth\_bias value, the second time it will get depth\_bias + iteration\_depth\_bias, the third time it will get depth\_bias + iteration\_depth\_bias \* 2, and so on. The default is zero. @par Format: iteration\_depth\_bias <bias\_per\_iteration> @@ -670,7 +672,7 @@ Default: polygon\_mode solid ## polygon\_mode\_overrideable -Sets whether or not the [polygon\_mode](#polygon_005fmode) set on this pass can be downgraded by the camera +Sets whether or not the [polygon_mode](#polygon_005fmode) set on this pass can be downgraded by the camera @par Format: polygon\_mode\_overrideable <override> @@ -921,7 +923,7 @@ Default: point\_size\_attenuation off ## point\_size\_min -Sets the minimum point size after attenuation ([point\_size\_attenuation](#point_005fsize_005fattenuation)). For details on the size metrics, See [point\_size](#point_005fsize). +Sets the minimum point size after attenuation ([point_size_attenuation](#point_005fsize_005fattenuation)). For details on the size metrics, See [point_size](#point_005fsize). @par Format: point\_size\_min <size> @par @@ -931,7 +933,7 @@ Default: point\_size\_min 0 ## point\_size\_max -Sets the maximum point size after attenuation ([point\_size\_attenuation](#point_005fsize_005fattenuation)). For details on the size metrics, See [point\_size](#point_005fsize). A value of 0 means the maximum is set to the same as the max size reported by the current card. +Sets the maximum point size after attenuation ([point_size_attenuation](#point_005fsize_005fattenuation)). For details on the size metrics, See [point_size](#point_005fsize). A value of 0 means the maximum is set to the same as the max size reported by the current card. @par Format: point\_size\_max <size> @par @@ -954,24 +956,24 @@ Here are the attributes you can use in a @c texture_unit section of a .material ## Available Texture Unit Attributes -- [texture\_alias](#texture_005falias) +- [texture_alias](#texture_005falias) - [texture](#texture) -- [anim\_texture](#anim_005ftexture) -- [cubic\_texture](#cubic_005ftexture) -- [tex\_coord\_set](#tex_005fcoord_005fset) -- [colour\_op](#colour_005fop) -- [colour\_op\_ex](#colour_005fop_005fex) -- [colour\_op\_multipass\_fallback](#colour_005fop_005fmultipass_005ffallback) -- [alpha\_op\_ex](#alpha_005fop_005fex) -- [env\_map](#env_005fmap) +- [anim_texture](#anim_005ftexture) +- [cubic_texture](#cubic_005ftexture) +- [tex_coord_set](#tex_005fcoord_005fset) +- [colour_op](#colour_005fop) +- [colour_op_ex](#colour_005fop_005fex) +- [colour_op_multipass_fallback](#colour_005fop_005fmultipass_005ffallback) +- [alpha_op_ex](#alpha_005fop_005fex) +- [env_map](#env_005fmap) - [scroll](#scroll) -- [scroll\_anim](#scroll_005fanim) +- [scroll_anim](#scroll_005fanim) - [rotate](#rotate) -- [rotate\_anim](#rotate_005fanim) +- [rotate_anim](#rotate_005fanim) - [scale](#scale) -- [wave\_xform](#wave_005fxform) +- [wave_xform](#wave_005fxform) - [transform](#transform) -- [content\_type](#content_005ftype) +- [content_type](#content_005ftype) - [sampler_ref](#sampler_ref) - [unordered_access_mip](#unordered_access_mip) @@ -1096,7 +1098,7 @@ This is no longer supported and behaves like combinedUVW. ## content_type -Tells this texture unit where it should get its content from. The default is to get texture content from a named texture, as defined with the [texture](#texture), [cubic\_texture](#cubic_005ftexture), [anim\_texture](#anim_005ftexture) attributes. However you can also pull texture information from other automated sources. +Tells this texture unit where it should get its content from. The default is to get texture content from a named texture, as defined with the [texture](#texture), [cubic_texture](#cubic_005ftexture), [anim_texture](#anim_005ftexture) attributes. However you can also pull texture information from other automated sources. @par Format: content\_type <type> \[<compositorName>\] \[<textureName>\] \[<mrtIndex>\] @@ -1113,7 +1115,7 @@ This option allows you to pull in a shadow texture, and is only valid when you u
compositor
-@copybrief Ogre::TextureUnitState::CONTENT_COMPOSITOR This can be either in a render\_scene directive inside a compositor script, or in a general pass in a viewport that has a compositor attached. Note that this is a reference only, meaning that it does not change the render order. You must make sure that the order is reasonable for what you are trying to achieve (for example, texture pooling might cause the referenced texture to be overwritten by something else by the time it is referenced). +@copybrief Ogre::TextureUnitState::CONTENT_COMPOSITOR This can be either in a @c render_scene directive inside a compositor script, or in a general pass in a viewport that has a compositor attached. Note that this is a reference only, meaning that it does not change the render order. You must make sure that the order is reasonable for what you are trying to achieve (for example, texture pooling might cause the referenced texture to be overwritten by something else by the time it is referenced).
@@ -1399,10 +1401,10 @@ sampler mySampler ## Available parameters - [filtering](#filtering) -- [max\_anisotropy](#max_005fanisotropy) -- [tex\_address\_mode](#tex_005faddress_005fmode) -- [tex\_border\_colour](#tex_005fborder_005fcolour) -- [mipmap\_bias](#mipmap_005fbias) +- [max_anisotropy](#max_005fanisotropy) +- [tex_address_mode](#tex_005faddress_005fmode) +- [tex_border_colour](#tex_005fborder_005fcolour) +- [mipmap_bias](#mipmap_005fbias) - [compare_test](#compare_test) - [comp_func](#comp_func) @@ -1423,7 +1425,7 @@ Default: tex\_address\_mode wrap ## tex\_border\_colour -Sets the border colour of border texture address mode (see [tex\_address\_mode](#tex_005faddress_005fmode)). +Sets the border colour of border texture address mode (see [tex_address_mode](#tex_005faddress_005fmode)). @par Format: tex\_border\_colour <red> <green> <blue> \[<alpha>\]
NB valid colour values are between 0.0 and 1.0. @par diff --git a/Docs/src/particle-scripts.md b/Docs/src/particle-scripts.md index 34c984c3fc7..98bc8645172 100644 --- a/Docs/src/particle-scripts.md +++ b/Docs/src/particle-scripts.md @@ -18,24 +18,24 @@ This section describes to attributes which you can set on every particle system - [quota](#quota) - [material](#particle_005fmaterial) -- [particle\_width](#particle_005fwidth) -- [particle\_height](#particle_005fheight) -- [cull\_each](#cull_005feach) +- [particle_width](#particle_005fwidth) +- [particle_height](#particle_005fheight) +- [cull_each](#cull_005feach) - [renderer](#particle_005frenderer) - [sorted](#particle_005fsorted) -- [local\_space](#particle_005flocalspace) -- [iteration\_interval](#iteration_005finterval) -- [nonvisible\_update\_timeout](#nonvisible_005fupdate_005ftimeout) +- [local_space](#particle_005flocalspace) +- [iteration_interval](#iteration_005finterval) +- [nonvisible_update_timeout](#nonvisible_005fupdate_005ftimeout) @par Billboard Renderer Attributes -- [billboard\_type](#billboard_005ftype) -- [billboard\_origin](#billboard_005forigin) -- [billboard\_rotation\_type](#billboard_005frotation_005ftype) -- [common\_direction](#common_005fdirection) -- [common\_up\_vector](#common_005fup_005fvector) -- [point\_rendering](#particle_005fpoint_005frendering) -- [accurate\_facing](#particle_005faccurate_005ffacing) +- [billboard_type](#billboard_005ftype) +- [billboard_origin](#billboard_005forigin) +- [billboard_rotation_type](#billboard_005frotation_005ftype) +- [common_direction](#common_005fdirection) +- [common_up_vector](#common_005fup_005fvector) +- [point_rendering](#particle_005fpoint_005frendering) +- [accurate_facing](#particle_005faccurate_005ffacing) @see @ref Particle-Emitters @see @ref Particle-Affectors @@ -144,7 +144,7 @@ The default arrangement, this approximates spherical particles and the billboard
oriented\_common
-Particles are oriented around a common, typically fixed direction vector (see [common\_direction](#common_005fdirection)), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented\_self (see below). +Particles are oriented around a common, typically fixed direction vector (see [common_direction](#common_005fdirection)), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented\_self (see below).
oriented\_self
@@ -152,11 +152,11 @@ Particles are oriented around their own direction vector, which acts as their lo
perpendicular\_common
-Particles are perpendicular to a common, typically fixed direction vector (see [common\_direction](#common_005fdirection)), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see [common\_up\_vector](#common_005fup_005fvector)). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular\_self (see below). +Particles are perpendicular to a common, typically fixed direction vector (see [common_direction](#common_005fdirection)), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see [common_up_vector](#common_005fup_005fvector)). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular\_self (see below).
perpendicular\_self
-Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see [common\_up\_vector](#common_005fup_005fvector)). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for rings stack etc where the particles will perpendicular to their traveling direction. +Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see [common_up_vector](#common_005fup_005fvector)). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for rings stack etc where the particles will perpendicular to their traveling direction.
@@ -191,7 +191,7 @@ Billboard particles will rotate the texture coordinates to according with partic ### common\_direction -Only required if [billboard\_type](#billboard_005ftype) is set to oriented\_common or perpendicular\_common, this vector is the common direction vector used to orient all particles in the system. +Only required if [billboard_type](#billboard_005ftype) is set to oriented\_common or perpendicular\_common, this vector is the common direction vector used to orient all particles in the system. format: common\_direction <x> <y> <z>
example: common\_direction 0 -1 0
default: 0 0 1
@@ -199,7 +199,7 @@ format: common\_direction <x> <y> <z>
example: common\_dir ### common\_up\_vector -Only required if [billboard\_type](#billboard_005ftype) is set to perpendicular\_self or perpendicular\_common, this vector is the common up vector used to orient all particles in the system. +Only required if [billboard_type](#billboard_005ftype) is set to perpendicular\_self or perpendicular\_common, this vector is the common up vector used to orient all particles in the system. format: common\_up\_vector <x> <y> <z>
example: common\_up\_vector 0 1 0
default: 0 1 0
@@ -260,24 +260,24 @@ This section describes the common attributes of all particle emitters. Specific - [angle](#angle) - [colour](#colour) -- [colour\_range\_start](#colour_005frange_005fstart) -- [colour\_range\_end](#colour_005frange_005fend) +- [colour_range_start](#colour_005frange_005fstart) +- [colour_range_end](#colour_005frange_005fend) - [direction](#direction) -- [direction\_position\_reference](#direction_005fposition_005freference) -- [emission\_rate](#emission_005frate) +- [direction_position_reference](#direction_005fposition_005freference) +- [emission_rate](#emission_005frate) - [position](#position) - [velocity](#velocity) -- [velocity\_min](#velocity_005fmin) -- [velocity\_max](#velocity_005fmax) -- [time\_to\_live](#time_005fto_005flive) -- [time\_to\_live\_min](#time_005fto_005flive_005fmin) -- [time\_to\_live\_max](#time_005fto_005flive_005fmax) +- [velocity_min](#velocity_005fmin) +- [velocity_max](#velocity_005fmax) +- [time_to_live](#time_005fto_005flive) +- [time_to_live_min](#time_005fto_005flive_005fmin) +- [time_to_live_max](#time_005fto_005flive_005fmax) - [duration](#duration) -- [duration\_min](#duration_005fmin) -- [duration\_max](#duration_005fmax) -- [repeat\_delay](#repeat_005fdelay) -- [repeat\_delay\_min](#repeat_005fdelay_005fmin) -- [repeat\_delay\_max](#repeat_005fdelay_005fmax) +- [duration_min](#duration_005fmin) +- [duration_max](#duration_005fmax) +- [repeat_delay](#repeat_005fdelay) +- [repeat_delay_min](#repeat_005fdelay_005fmin) +- [repeat_delay_max](#repeat_005fdelay_005fmax) @@ -371,7 +371,7 @@ format: as time\_to\_live
example:
    time\_to\_live\_min 2
  ## duration -Sets the number of seconds the emitter is active. The emitter can be started again, see [repeat\_delay](#repeat_005fdelay). +Sets the number of seconds the emitter is active. The emitter can be started again, see [repeat_delay](#repeat_005fdelay). See also the duration\_min and duration\_max attributes which let you set a duration range instead of a fixed one. format: duration <seconds>
example:
    duration 2.5
default: 0

diff --git a/Docs/src/scripts.md b/Docs/src/scripts.md index 8c39bca6875..e02795f459b 100644 --- a/Docs/src/scripts.md +++ b/Docs/src/scripts.md @@ -279,7 +279,7 @@ As Target, but this is the single final result of all operations. The size and p
Target Section
-A Target may be rendered to many times in the course of a composition effect. In particular if you ’ping pong’ a convolution between a couple of textures, you will have more than one Target Sections per Target. Target Sections are declared in the script using a [target or target\_output line](#Compositor-Target-Passes), the latter being the final output of which there can be only one. +A Target may be rendered to many times in the course of a composition effect. In particular if you ’ping pong’ a convolution between a couple of textures, you will have more than one Target Sections per Target. Target Sections are declared in the script using a [target or target_output line](#Compositor-Target-Passes), the latter being the final output of which there can be only one. @note Internally this is referred to as Ogre::CompositionTargetPass
Pass
@@ -315,11 +315,11 @@ Format: technique { } Techniques can have the following nested elements: - [texture](#compositor-texture) -- [texture\_ref](#compositor_005ftexture_005fref) +- [texture_ref](#compositor_005ftexture_005fref) - [scheme](#compositor_005fscheme) -- [compositor\_logic](#compositor_005flogic) +- [compositor_logic](#compositor_005flogic) - [target](#Compositor-Target-Passes) -- [target\_output](#Compositor-Target-Passes) +- [target_output](#Compositor-Target-Passes) @@ -368,7 +368,7 @@ When present, this directive has to be followed by an integer. This directive is - Ignored with depth pixel formats. @param scope -If present, this directive sets the scope for the texture for being accessed by other compositors using the [texture\_ref](#compositor_005ftexture_005fref) directive. There are three options : +If present, this directive sets the scope for the texture for being accessed by other compositors using the [texture_ref](#compositor_005ftexture_005fref) directive. There are three options: 1. @c local_scope (which is also the default) means that only the compositor defining the texture can access it. 2. @c chain_scope means that the compositors after this compositor in the chain can reference its textures, and 3. @c global_scope means that the entire application can access the texture. This directive also affects the creation of the textures (global textures are created once and thus can’t be used with the pooled directive, and can’t rely on viewport size). @@ -451,9 +451,9 @@ Note, the target entry can refer to @ref Cube-map-textures. Therefore, it takes Here are the attributes you can use in a ’target’ or ’target\_output’ section of a .compositor script: - [input](#compositor_005ftarget_005finput) -- [only\_initial](#only_005finitial) -- [visibility\_mask](#visibility_005fmask) -- [lod\_bias](#compositor_005flod_005fbias) +- [only_initial](#only_005finitial) +- [visibility_mask](#visibility_005fmask) +- [lod_bias](#compositor_005flod_005fbias) - [material_scheme](#material_005fscheme) - [shadows](#compositor_005fshadows) @@ -546,7 +546,7 @@ This kind of pass configures stencil operations for the subsequent passes. It ca
render\_scene
-This kind of pass performs a regular rendering of the scene. It will use the [visibility\_mask](#visibility_005fmask), [lod\_bias](#compositor_005flod_005fbias), and [material\_scheme](#material_005fscheme) from the parent target pass. +This kind of pass performs a regular rendering of the scene. It will use the [visibility_mask](#visibility_005fmask), [lod_bias](#compositor_005flod_005fbias), and [material_scheme](#material_005fscheme) from the parent target pass.
render\_quad
@@ -641,9 +641,9 @@ Format: thread_groups <groups_x> <groups_y> <groups_z> Here are the attributes you can use in a @c render_scene section of a .compositor script: -- [first\_render\_queue](#first_005frender_005fqueue) -- [last\_render\_queue](#last_005frender_005fqueue) -- [material\_scheme](#compositor_005fpass_005fmaterial_005fscheme) +- [first_render_queue](#first_005frender_005fqueue) +- [last_render_queue](#last_005frender_005fqueue) +- [material_scheme](#compositor_005fpass_005fmaterial_005fscheme) - [camera](#camera) @@ -699,9 +699,9 @@ Format: pass clear { } Here are the attributes you can use in a ’clear’ section of a .compositor script: - [buffers](#compositor_005fclear_005fbuffers) -- [colour\_value](#compositor_005fclear_005fcolour_005fvalue) -- [depth\_value](#compositor_005fclear_005fdepth_005fvalue) -- [stencil\_value](#compositor_005fclear_005fstencil_005fvalue) +- [colour_value](#compositor_005fclear_005fcolour_005fvalue) +- [depth_value](#compositor_005fclear_005fdepth_005fvalue) +- [stencil_value](#compositor_005fclear_005fstencil_005fvalue) ### buffers @@ -756,13 +756,13 @@ Format: pass stencil { } Here are the attributes you can use in a ’stencil’ section of a .compositor script: - [check](#compositor_005fstencil_005fcheck) -- [comp\_func](#compositor_005fstencil_005fcomp_005ffunc) -- [ref\_value](#compositor_005fstencil_005fref_005fvalue) +- [comp_func](#compositor_005fstencil_005fcomp_005ffunc) +- [ref_value](#compositor_005fstencil_005fref_005fvalue) - [mask](#compositor_005fstencil_005fmask) -- [fail\_op](#compositor_005fstencil_005ffail_005fop) -- [depth\_fail\_op](#compositor_005fstencil_005fdepth_005ffail_005fop) -- [pass\_op](#compositor_005fstencil_005fpass_005fop) -- [two\_sided](#compositor_005fstencil_005ftwo_005fsided) +- [fail_op](#compositor_005fstencil_005ffail_005fop) +- [depth_fail_op](#compositor_005fstencil_005fdepth_005ffail_005fop) +- [pass_op](#compositor_005fstencil_005fpass_005fop) +- [two_sided](#compositor_005fstencil_005ftwo_005fsided) ### check @@ -967,9 +967,9 @@ Must be a name unique among all other elements / containers by which to identify The properties which can be included within the braces depend on the custom type. However the following are always valid: -- [metrics\_mode](#metrics_005fmode) -- [horz\_align](#horz_005falign) -- [vert\_align](#vert_005falign) +- [metrics_mode](#metrics_005fmode) +- [horz_align](#horz_005falign) +- [vert_align](#vert_005falign) - [left](#left) - [top](#overlaytopelement) - [width](#width) @@ -1228,7 +1228,7 @@ This is a slightly more advanced version of Panel, where instead of just a singl ## TextArea (element) {#TextArea} -This is a generic element that you can use to render text. It uses fonts which can be defined in code using the FontManager and Font classes, or which have been predefined in .fontdef files. See the font definitions section for more information. +This is a generic element that you can use to render text. It uses fonts which can be defined in code using the Ogre::FontManager and0Ogre:: Font classes, or which have been predefined in @c .fontdef files. See the font definitions section for more information. @param font\_name <name> The name of the font to use. This font must be defined in a .fontdef file to ensure it is available at scripting time. @@ -1270,16 +1270,16 @@ font # Using an existing font texture -If you have one or more artists working with you, no doubt they can produce you a very nice font texture. OGRE supports full colour font textures, or alternatively you can keep them monochrome / greyscale and use TextArea’s colouring feature. Font textures should always have an alpha channel, preferably an 8-bit alpha channel such as that supported by TGA and PNG files, because it can result in much nicer edges. To use an existing texture, here are the settings you need: +If you have one or more artists working with you, no doubt they can produce you a very nice font texture. OGRE supports full colour font textures, or alternatively you can keep them monochrome / greyscale and use the colouring feature of Ogre::TextAreaOverlayElement. Font textures should always have an alpha channel, preferably an 8-bit alpha channel such as that supported by TGA and PNG files, because it can result in much nicer edges. To use an existing texture, here are the settings you need: @param type image This just tells OGRE you want a pre-drawn font. @param source <filename> This is the name of the image file you want to load. This will be loaded from the standard resource locations and can be of any type OGRE supports, although JPEG is not recommended because of the lack of alpha and the lossy compression. I recommend PNG format which has both good lossless compression and an 8-bit alpha channel. @param glyph <character> <u1> <v1> <u2> <v2> This provides the texture coordinates for the specified character. You must repeat this for every character you have in the texture. The first 2 numbers are the x and y of the top-left corner, the second two are the x and y of the bottom-right corner. Note that you really should use a common height for all characters, but widths can vary because of proportional fonts. -’character’ is either an ASCII character for non-extended 7-bit ASCII, or for extended glyphs, a unicode decimal value, which is identified by preceding the number with a ’u’ - e.g. ’u0546’ denotes unicode value 546. +’character’ is either an ASCII character for non-extended 7-bit ASCII, or for extended glyphs, a unicode decimal value, which is identified by preceding the number with a ’u’ - e.g. @c u0546 denotes unicode value 546. -A note for Windows users: I recommend using [BitmapFontBuilder](), a free tool which will generate a texture and export character widths for you, you can find a tool for converting the binary output from this into ’glyph’ lines in the Tools folder.
+You can use [font2bitmap](https://stmn.github.io/font2bitmap/), a web tool which will generate a texture for you. You will still have to manually create the @c glyph entries, but it will give you a good starting point. @@ -1299,4 +1299,4 @@ Here are the attributes you need to supply: @param code\_points nn-nn \[nn-nn\] .. This directive allows you to specify which unicode code points should be generated as glyphs into the font texture. If you don’t specify this, code points 32-126 will be generated by default which covers the ASCII glyphs. If you use this flag, you should specify a space-separated list of inclusive code point ranges of the form ’start-end’. Numbers must be decimal. -You can also create new fonts at runtime by using the FontManager if you wish. +You can also create new fonts at runtime by using the Ogre::FontManager if you wish. diff --git a/OgreMain/src/OgreAnimation.cpp b/OgreMain/src/OgreAnimation.cpp index 2238afd49ce..ccd31a14d80 100644 --- a/OgreMain/src/OgreAnimation.cpp +++ b/OgreMain/src/OgreAnimation.cpp @@ -607,6 +607,10 @@ namespace Ogre { if( timePos > totalAnimationLength && totalAnimationLength > 0.0f ) timePos = std::fmod( timePos, totalAnimationLength ); + // Not best practice, but prevent from crash + if (mKeyFrameTimes.empty()) + return timePos; + // Search for global index auto it = std::lower_bound(mKeyFrameTimes.begin(), mKeyFrameTimes.end() - 1, timePos); return TimeIndex(timePos, static_cast(std::distance(mKeyFrameTimes.begin(), it))); diff --git a/OgreMain/src/OgreScriptCompiler.cpp b/OgreMain/src/OgreScriptCompiler.cpp index d135b234262..f98589b1cff 100644 --- a/OgreMain/src/OgreScriptCompiler.cpp +++ b/OgreMain/src/OgreScriptCompiler.cpp @@ -1379,7 +1379,7 @@ namespace Ogre // Get the name // Unless the type is in the exclusion list - if(iter != temp.end() && ((*iter)->type == CNT_WORD || (*iter)->type == CNT_QUOTE) && + if(iter != temp.end() && ((*iter)->type == CNT_WORD || (*iter)->type == CNT_QUOTE || (*iter)->type == CNT_VARIABLE) && !mCompiler->isNameExcluded(*impl, mCurrent)) { impl->name = (*iter)->token; diff --git a/PlugIns/RsImageCodec/src/OgreRsImageCodec.cpp b/PlugIns/RsImageCodec/src/OgreRsImageCodec.cpp index 6510597d90e..1d6b79fb50c 100644 --- a/PlugIns/RsImageCodec/src/OgreRsImageCodec.cpp +++ b/PlugIns/RsImageCodec/src/OgreRsImageCodec.cpp @@ -49,7 +49,7 @@ RsImageCodec::RegisteredCodecList RsImageCodec::msCodecList; void RsImageCodec::startup(void) { // Register codecs - String exts = "jpeg,jpg,png,bmp,gif,tiff,tga,exr"; + String exts = "jpeg,jpg,png,bmp,gif,tiff,tga,exr,hdr"; StringVector extsVector = StringUtil::split(exts, ","); for (auto& v : extsVector) { diff --git a/PlugIns/STBICodec/src/OgreSTBICodec.cpp b/PlugIns/STBICodec/src/OgreSTBICodec.cpp index f89e9a16c29..c5a4d4bfa23 100644 --- a/PlugIns/STBICodec/src/OgreSTBICodec.cpp +++ b/PlugIns/STBICodec/src/OgreSTBICodec.cpp @@ -74,7 +74,7 @@ namespace Ogre { stbi_convert_iphone_png_to_rgb(1); stbi_set_unpremultiply_on_load(1); - LogManager::getSingleton().logMessage("stb_image - v2.28 - public domain image loader"); + LogManager::getSingleton().logMessage("stb_image - v2.30 - public domain image loader"); // Register codecs String exts = "jpeg,jpg,png,bmp,psd,tga,gif,pic,ppm,pgm,hdr"; diff --git a/PlugIns/STBICodec/src/stbi/stb_image.h b/PlugIns/STBICodec/src/stbi/stb_image.h index 5e807a0a6e7..9eedabedc45 100644 --- a/PlugIns/STBICodec/src/stbi/stb_image.h +++ b/PlugIns/STBICodec/src/stbi/stb_image.h @@ -1,4 +1,4 @@ -/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb +/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb no warranty implied; use at your own risk Do this: @@ -48,6 +48,8 @@ LICENSE RECENT REVISION HISTORY: + 2.30 (2024-05-31) avoid erroneous gcc warning + 2.29 (2023-05-xx) optimizations 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes 2.26 (2020-07-13) many minor fixes @@ -1072,8 +1074,8 @@ static int stbi__addints_valid(int a, int b) return a <= INT_MAX - b; } -// returns 1 if the product of two signed shorts is valid, 0 on overflow. -static int stbi__mul2shorts_valid(short a, short b) +// returns 1 if the product of two ints fits in a signed short, 0 on overflow. +static int stbi__mul2shorts_valid(int a, int b) { if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid @@ -3384,13 +3386,13 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) return 1; } -static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) +static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) { // some JPEGs have junk at end, skip over it but if we find what looks // like a valid marker, resume there while (!stbi__at_eof(j->s)) { - int x = stbi__get8(j->s); - while (x == 255) { // might be a marker + stbi_uc x = stbi__get8(j->s); + while (x == 0xff) { // might be a marker if (stbi__at_eof(j->s)) return STBI__MARKER_none; x = stbi__get8(j->s); if (x != 0x00 && x != 0xff) { @@ -4176,6 +4178,7 @@ typedef struct { stbi_uc *zbuffer, *zbuffer_end; int num_bits; + int hit_zeof_once; stbi__uint32 code_buffer; char *zout; @@ -4242,9 +4245,20 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) int b,s; if (a->num_bits < 16) { if (stbi__zeof(a)) { - return -1; /* report error for unexpected end of data. */ + if (!a->hit_zeof_once) { + // This is the first time we hit eof, insert 16 extra padding btis + // to allow us to keep going; if we actually consume any of them + // though, that is invalid data. This is caught later. + a->hit_zeof_once = 1; + a->num_bits += 16; // add 16 implicit zero bits + } else { + // We already inserted our extra 16 padding bits and are again + // out, this stream is actually prematurely terminated. + return -1; + } + } else { + stbi__fill_bits(a); } - stbi__fill_bits(a); } b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; if (b) { @@ -4309,6 +4323,13 @@ static int stbi__parse_huffman_block(stbi__zbuf *a) int len,dist; if (z == 256) { a->zout = zout; + if (a->hit_zeof_once && a->num_bits < 16) { + // The first time we hit zeof, we inserted 16 extra zero bits into our bit + // buffer so the decoder can just do its speculative decoding. But if we + // actually consumed any of those bits (which is the case when num_bits < 16), + // the stream actually read past the end so it is malformed. + return stbi__err("unexpected end","Corrupt PNG"); + } return 1; } if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data @@ -4320,7 +4341,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a) dist = stbi__zdist_base[z]; if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); - if (zout + len > a->zout_end) { + if (len > a->zout_end - zout) { if (!stbi__zexpand(a, zout, len)) return 0; zout = a->zout; } @@ -4464,6 +4485,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) if (!stbi__parse_zlib_header(a)) return 0; a->num_bits = 0; a->code_buffer = 0; + a->hit_zeof_once = 0; do { final = stbi__zreceive(a,1); type = stbi__zreceive(a,2); @@ -4619,9 +4641,8 @@ enum { STBI__F_up=2, STBI__F_avg=3, STBI__F_paeth=4, - // synthetic filters used for first scanline to avoid needing a dummy row of 0s - STBI__F_avg_first, - STBI__F_paeth_first + // synthetic filter used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first }; static stbi_uc first_row_filter[5] = @@ -4630,29 +4651,56 @@ static stbi_uc first_row_filter[5] = STBI__F_sub, STBI__F_none, STBI__F_avg_first, - STBI__F_paeth_first + STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub }; static int stbi__paeth(int a, int b, int c) { - int p = a + b - c; - int pa = abs(p-a); - int pb = abs(p-b); - int pc = abs(p-c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; + // This formulation looks very different from the reference in the PNG spec, but is + // actually equivalent and has favorable data dependencies and admits straightforward + // generation of branch-free code, which helps performance significantly. + int thresh = c*3 - (a + b); + int lo = a < b ? a : b; + int hi = a < b ? b : a; + int t0 = (hi <= thresh) ? lo : c; + int t1 = (thresh <= lo) ? hi : t0; + return t1; } static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; +// adds an extra all-255 alpha channel +// dest == src is legal +// img_n must be 1 or 3 +static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n) +{ + int i; + // must process data backwards since we allow dest==src + if (img_n == 1) { + for (i=x-1; i >= 0; --i) { + dest[i*2+1] = 255; + dest[i*2+0] = src[i]; + } + } else { + STBI_ASSERT(img_n == 3); + for (i=x-1; i >= 0; --i) { + dest[i*4+3] = 255; + dest[i*4+2] = src[i*3+2]; + dest[i*4+1] = src[i*3+1]; + dest[i*4+0] = src[i*3+0]; + } + } +} + // create the png data from post-deflated data static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) { - int bytes = (depth == 16? 2 : 1); + int bytes = (depth == 16 ? 2 : 1); stbi__context *s = a->s; stbi__uint32 i,j,stride = x*out_n*bytes; stbi__uint32 img_len, img_width_bytes; + stbi_uc *filter_buf; + int all_ok = 1; int k; int img_n = s->img_n; // copy it into a local for later @@ -4664,8 +4712,11 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into if (!a->out) return stbi__err("outofmem", "Out of memory"); + // note: error exits here don't need to clean up a->out individually, + // stbi__do_png always does on error. if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); + if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); img_len = (img_width_bytes + 1) * y; // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, @@ -4673,189 +4724,137 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r // so just check for raw_len < img_len always. if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + // Allocate two scan lines worth of filter workspace buffer. + filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); + if (!filter_buf) return stbi__err("outofmem", "Out of memory"); + + // Filtering for low-bit-depth images + if (depth < 8) { + filter_bytes = 1; + width = img_width_bytes; + } + for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *prior; + // cur/prior filter buffers alternate + stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; + stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; + stbi_uc *dest = a->out + stride*j; + int nk = width * filter_bytes; int filter = *raw++; - if (filter > 4) - return stbi__err("invalid filter","Corrupt PNG"); - - if (depth < 8) { - if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG"); - cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place - filter_bytes = 1; - width = img_width_bytes; + // check filter type + if (filter > 4) { + all_ok = stbi__err("invalid filter","Corrupt PNG"); + break; } - prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above // if first row, use special filter that doesn't sample previous row if (j == 0) filter = first_row_filter[filter]; - // handle first byte explicitly - for (k=0; k < filter_bytes; ++k) { - switch (filter) { - case STBI__F_none : cur[k] = raw[k]; break; - case STBI__F_sub : cur[k] = raw[k]; break; - case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; - case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; - case STBI__F_avg_first : cur[k] = raw[k]; break; - case STBI__F_paeth_first: cur[k] = raw[k]; break; - } - } - - if (depth == 8) { - if (img_n != out_n) - cur[img_n] = 255; // first pixel - raw += img_n; - cur += out_n; - prior += out_n; - } else if (depth == 16) { - if (img_n != out_n) { - cur[filter_bytes] = 255; // first pixel top byte - cur[filter_bytes+1] = 255; // first pixel bottom byte - } - raw += filter_bytes; - cur += output_bytes; - prior += output_bytes; - } else { - raw += 1; - cur += 1; - prior += 1; + // perform actual filtering + switch (filter) { + case STBI__F_none: + memcpy(cur, raw, nk); + break; + case STBI__F_sub: + memcpy(cur, raw, filter_bytes); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); + break; + case STBI__F_up: + for (k = 0; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); + break; + case STBI__F_avg: + for (k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); + break; + case STBI__F_paeth: + for (k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes])); + break; + case STBI__F_avg_first: + memcpy(cur, raw, filter_bytes); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); + break; } - // this is a little gross, so that we don't switch per-pixel or per-component - if (depth < 8 || img_n == out_n) { - int nk = (width - 1)*filter_bytes; - #define STBI__CASE(f) \ - case f: \ - for (k=0; k < nk; ++k) - switch (filter) { - // "none" filter turns into a memcpy here; make that explicit. - case STBI__F_none: memcpy(cur, raw, nk); break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; - } - #undef STBI__CASE - raw += nk; - } else { - STBI_ASSERT(img_n+1 == out_n); - #define STBI__CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ - for (k=0; k < filter_bytes; ++k) - switch (filter) { - STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; - } - #undef STBI__CASE - - // the loop above sets the high byte of the pixels' alpha, but for - // 16 bit png files we also need the low byte set. we'll do that here. - if (depth == 16) { - cur = a->out + stride*j; // start at the beginning of the row again - for (i=0; i < x; ++i,cur+=output_bytes) { - cur[filter_bytes+1] = 255; - } - } - } - } + raw += nk; - // we make a separate pass to expand bits to pixels; for performance, - // this could run two scanlines behind the above code, so it won't - // intefere with filtering but will still be in the cache. - if (depth < 8) { - for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; - // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit - // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + // expand decoded bits in cur to dest, also adding an extra alpha channel if desired + if (depth < 8) { stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + stbi_uc *in = cur; + stbi_uc *out = dest; + stbi_uc inb = 0; + stbi__uint32 nsmp = x*img_n; - // note that the final byte might overshoot and write more data than desired. - // we can allocate enough data that this never writes out of memory, but it - // could also overwrite the next scanline. can it overwrite non-empty data - // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. - // so we need to explicitly clamp the final ones - + // expand bits to bytes first if (depth == 4) { - for (k=x*img_n; k >= 2; k-=2, ++in) { - *cur++ = scale * ((*in >> 4) ); - *cur++ = scale * ((*in ) & 0x0f); + for (i=0; i < nsmp; ++i) { + if ((i & 1) == 0) inb = *in++; + *out++ = scale * (inb >> 4); + inb <<= 4; } - if (k > 0) *cur++ = scale * ((*in >> 4) ); } else if (depth == 2) { - for (k=x*img_n; k >= 4; k-=4, ++in) { - *cur++ = scale * ((*in >> 6) ); - *cur++ = scale * ((*in >> 4) & 0x03); - *cur++ = scale * ((*in >> 2) & 0x03); - *cur++ = scale * ((*in ) & 0x03); + for (i=0; i < nsmp; ++i) { + if ((i & 3) == 0) inb = *in++; + *out++ = scale * (inb >> 6); + inb <<= 2; } - if (k > 0) *cur++ = scale * ((*in >> 6) ); - if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); - if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); - } else if (depth == 1) { - for (k=x*img_n; k >= 8; k-=8, ++in) { - *cur++ = scale * ((*in >> 7) ); - *cur++ = scale * ((*in >> 6) & 0x01); - *cur++ = scale * ((*in >> 5) & 0x01); - *cur++ = scale * ((*in >> 4) & 0x01); - *cur++ = scale * ((*in >> 3) & 0x01); - *cur++ = scale * ((*in >> 2) & 0x01); - *cur++ = scale * ((*in >> 1) & 0x01); - *cur++ = scale * ((*in ) & 0x01); + } else { + STBI_ASSERT(depth == 1); + for (i=0; i < nsmp; ++i) { + if ((i & 7) == 0) inb = *in++; + *out++ = scale * (inb >> 7); + inb <<= 1; } - if (k > 0) *cur++ = scale * ((*in >> 7) ); - if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); - if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); - if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); - if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); - if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); - if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); } - if (img_n != out_n) { - int q; - // insert alpha = 255 - cur = a->out + stride*j; + + // insert alpha=255 values if desired + if (img_n != out_n) + stbi__create_png_alpha_expand8(dest, dest, x, img_n); + } else if (depth == 8) { + if (img_n == out_n) + memcpy(dest, cur, x*img_n); + else + stbi__create_png_alpha_expand8(dest, cur, x, img_n); + } else if (depth == 16) { + // convert the image data from big-endian to platform-native + stbi__uint16 *dest16 = (stbi__uint16*)dest; + stbi__uint32 nsmp = x*img_n; + + if (img_n == out_n) { + for (i = 0; i < nsmp; ++i, ++dest16, cur += 2) + *dest16 = (cur[0] << 8) | cur[1]; + } else { + STBI_ASSERT(img_n+1 == out_n); if (img_n == 1) { - for (q=x-1; q >= 0; --q) { - cur[q*2+1] = 255; - cur[q*2+0] = cur[q]; + for (i = 0; i < x; ++i, dest16 += 2, cur += 2) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = 0xffff; } } else { STBI_ASSERT(img_n == 3); - for (q=x-1; q >= 0; --q) { - cur[q*4+3] = 255; - cur[q*4+2] = cur[q*3+2]; - cur[q*4+1] = cur[q*3+1]; - cur[q*4+0] = cur[q*3+0]; + for (i = 0; i < x; ++i, dest16 += 4, cur += 6) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = (cur[2] << 8) | cur[3]; + dest16[2] = (cur[4] << 8) | cur[5]; + dest16[3] = 0xffff; } } } } - } else if (depth == 16) { - // force the image data from big-endian to platform-native. - // this is done in a separate pass due to the decoding relying - // on the data being untouched, but could probably be done - // per-line during decode if care is taken. - stbi_uc *cur = a->out; - stbi__uint16 *cur16 = (stbi__uint16*)cur; - - for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { - *cur16 = (cur[0] << 8) | cur[1]; - } } + STBI_FREE(filter_buf); + if (!all_ok) return 0; + return 1; } @@ -5161,9 +5160,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } if (z->depth == 16) { - for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning + tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is } else { - for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + for (k = 0; k < s->img_n && k < 3; ++k) + tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger } } break; diff --git a/SDK/Dockerfile b/SDK/Dockerfile index e80ca733d58..88e5642f986 100644 --- a/SDK/Dockerfile +++ b/SDK/Dockerfile @@ -1,7 +1,7 @@ FROM quay.io/pypa/manylinux_2_28_x86_64:latest RUN yum install -y libXrandr-devel mesa-libEGL-devel vulkan-devel WORKDIR / -RUN curl -LO https://sdk.lunarg.com/sdk/download/1.3.224.1/linux/vulkansdk-linux-x86_64-1.3.224.1.tar.gz && tar xvf vulkansdk-linux-x86_64-1.3.224.1.tar.gz -ENV VULKAN_SDK=/1.3.224.1/x86_64/ +RUN curl -LO https://sdk.lunarg.com/sdk/download/1.3.275.0/linux/vulkansdk-linux-x86_64-1.3.275.0.tar.gz && tar xvf vulkansdk-linux-x86_64-1.3.275.0.tar.gz +ENV VULKAN_SDK=/1.3.275.0/x86_64/ WORKDIR /workspace CMD PATH="/opt/python/$PYVER/bin/:$PATH" pip wheel . --verbose \ No newline at end of file diff --git a/Samples/Browser/include/SampleBrowser.h b/Samples/Browser/include/SampleBrowser.h index e7251e88be5..dc76889d060 100644 --- a/Samples/Browser/include/SampleBrowser.h +++ b/Samples/Browser/include/SampleBrowser.h @@ -885,6 +885,7 @@ namespace OgreBites if (!sp) // this is not a SamplePlugin, so unload it { + Ogre::LogManager::getSingleton().logError(*i + " is not a SamplePlugin"); unloadedSamplePlugins.push_back(sampleDir + *i); mRoot->unloadPlugin(sampleDir + *i); continue; diff --git a/appveyor.yml b/appveyor.yml index f6d9f1fcb2a..29b0348c7e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,13 +10,13 @@ install: - cmd: pip install swig - cmd: curl -sSf -o rustup-init.exe https://win.rustup.rs/ - cmd: rustup-init.exe -y - - cmd: curl -LO https://sdk.lunarg.com/sdk/download/1.3.224.1/windows/VulkanSDK-1.3.224.1-Installer.exe - - cmd: VulkanSDK-1.3.224.1-Installer.exe --accept-licenses --default-answer --confirm-command install + - cmd: curl -LO https://sdk.lunarg.com/sdk/download/1.3.275.0/windows/VulkanSDK-1.3.275.0-Installer.exe + - cmd: VulkanSDK-1.3.275.0-Installer.exe --accept-licenses --default-answer --confirm-command install - cmd: cd %APPVEYOR_BUILD_FOLDER% - cmd: git submodule update --init --recursive build_script: - set PATH=C:\Qt\6.2\msvc2019_64\bin;C:\Users\appveyor\.cargo\bin;%PATH% - - set VULKAN_SDK=C:\VulkanSDK\1.3.224.1 + - set VULKAN_SDK=C:\VulkanSDK\1.3.275.0 - cmake -P ci-build.cmake - cmake --build build --config RelWithDebInfo --target INSTALL test_script: