From bb40519a10c3ebdf6ec721bb65544816b3b518ab Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 15 May 2023 14:13:41 -0700 Subject: [PATCH 01/58] remove Item::clone, which has been documented but unimplemented for years --- OgreMain/include/OgreItem.h | 11 ----------- OgreMain/src/OgreItem.cpp | 23 ----------------------- 2 files changed, 34 deletions(-) diff --git a/OgreMain/include/OgreItem.h b/OgreMain/include/OgreItem.h index c713c17fc33..7fa301a9790 100644 --- a/OgreMain/include/OgreItem.h +++ b/OgreMain/include/OgreItem.h @@ -143,17 +143,6 @@ namespace Ogre /// Sets the given HLMS datablock to all SubEntities void setDatablock( IdString datablockName ); - /** Clones this Item and returns a pointer to the clone. - @remarks - Useful method for duplicating an Item. The new Item must be - given a unique name, and is not attached to the scene in any way - so must be attached to a SceneNode to be visible (exactly as - entities returned from SceneManager::createItem). - @param newName - Name for the new Item. - */ - Item *clone( const String &newName ) const; - /** Sets the material to use for the whole of this Item. @remarks This is a shortcut method to set all the materials for all diff --git a/OgreMain/src/OgreItem.cpp b/OgreMain/src/OgreItem.cpp index b6c80485886..c0d4946d617 100644 --- a/OgreMain/src/OgreItem.cpp +++ b/OgreMain/src/OgreItem.cpp @@ -196,29 +196,6 @@ namespace Ogre setDatablock( datablock ); } -#if 0 - //----------------------------------------------------------------------- - Item* Item::clone( const String& newName ) const - { - if (!mManager) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot clone an Item that wasn't created through a " - "SceneManager", "Item::clone"); - } - Item* newEnt = mManager->createItem( newName, getMesh()->getName() ); - - if( mInitialised ) - { - // Copy material settings - unsigned int n = 0; - for( SubItem &subitem : mSubItems ) - newEnt->getSubItem(n++)->setDatablock( subitem.getDatablock() ); - } - - return newEnt; - } -#endif //----------------------------------------------------------------------- void Item::setDatablockOrMaterialName( const String &name, From 550a76de7bee903f950ff30c22b719697a496085 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 16 May 2023 18:13:35 -0300 Subject: [PATCH 02/58] [VK, HLSL] Fix spelling error of weight Fix #386 --- RenderSystems/Vulkan/src/OgreVulkanMappings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp b/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp index af7d45b5ac5..91d0a042481 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp @@ -1033,7 +1033,7 @@ namespace Ogre { if( strcmp( sem, "input.blendIndices" ) == 0 ) return VES_BLEND_INDICES; - if( strcmp( sem, "input.blendWeigth" ) == 0 ) + if( strcmp( sem, "input.blendWeight" ) == 0 ) return VES_BLEND_WEIGHTS; if( strcmp( sem, "input.colour" ) == 0 ) return VES_DIFFUSE; From 5b6d444ece12a32ed8115c22650c2c79cb54c8e1 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 20 May 2023 13:39:12 -0300 Subject: [PATCH 03/58] [GL3+] Fix shader compiler error on GL 3.3 drivers Old GPUs and systems with incomplete GL implementations like WSLg would trigger shader compiler errors because C++ saw that GL_ARB_shader_storage_buffer_object was supported but we didn't request it in the shader. Affects gazebosim/gz-sim#920 --- .../Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl b/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl index c51a61360e2..ccbc336bda5 100644 --- a/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl +++ b/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl @@ -6,6 +6,10 @@ #version 430 core @else #version 330 core + + @property( !hlms_readonly_is_tex ) + #extension GL_ARB_shader_storage_buffer_object: require + @end @end @end From 29670801fe7b53d2bc0874a5c23cc8a29341e9e2 Mon Sep 17 00:00:00 2001 From: Silvio Traversaro Date: Sun, 21 May 2023 17:08:06 +0200 Subject: [PATCH 04/58] GL3Plus: If GL_ARB_copy_image is not available, use GL_NV_copy_image --- .../GL3Plus/src/OgreGL3PlusTextureGpu.cpp | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp index c9a1147b188..85a94ae7a71 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp @@ -649,15 +649,23 @@ namespace Ogre dstBox.getZOrSlice() + dstGl->getInternalSliceStart(), srcBox.width, srcBox.height, srcBox.getDepthOrSlices() ) ); } - /*TODO else if( support.checkExtension( "GL_NV_copy_image" ) ) - { - OCGE( glCopyImageSubDataNV( this->mFinalTextureName, this->mGlTextureTarget, - srcMipLevel, srcBox.x, srcBox.y, srcBox.z, - dstGl->mFinalTextureName, dstGl->mGlTextureTarget, - dstMipLevel, dstBox.x, dstBox.y, dstBox.z, - srcBox.width, srcBox.height, srcBox.getDepthOrSlices() ) ); - }*/ + { + // Initialize the pointer only the first time + PFNGLCOPYIMAGESUBDATANVPROC local_glCopyImageSubDataNV = nullptr; + if (!local_glCopyImageSubDataNV) + { + local_glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)gl3wGetProcAddress("glCopyImageSubDataNV"); + } + + OCGE( local_glCopyImageSubDataNV( this->mFinalTextureName, this->mGlTextureTarget, + srcMipLevel, srcBox.x, srcBox.y, + srcBox.getZOrSlice() + this->getInternalSliceStart(), + dstGl->mFinalTextureName, dstGl->mGlTextureTarget, + dstMipLevel, dstBox.x, dstBox.y, + dstBox.getZOrSlice() + dstGl->getInternalSliceStart(), + srcBox.width, srcBox.height, srcBox.getDepthOrSlices() ) ); + } /*TODO: These are for OpenGL ES 3.0+ else if( support.checkExtension( "GL_OES_copy_image" ) ) { From 3d9d380683cdd3fb252d754c4e40d01dfa81a3aa Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 21 May 2023 15:52:41 -0300 Subject: [PATCH 05/58] [WSLg] Fix shader compiler errors under WSLg OpenGL via d3d12 (Mesa) under WSL; since it currently supports up to OpenGL 4.2. Affects gazebosim/gz-rendering#852 --- .../materials/Common/GLSL/GaussianBlurBase_cs.glsl | 8 +++++++- .../Tutorial_Terrain/GLSL/TerraShadowGenerator.glsl | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Samples/Media/2.0/scripts/materials/Common/GLSL/GaussianBlurBase_cs.glsl b/Samples/Media/2.0/scripts/materials/Common/GLSL/GaussianBlurBase_cs.glsl index 9e013df6ab0..126bf8195a9 100644 --- a/Samples/Media/2.0/scripts/materials/Common/GLSL/GaussianBlurBase_cs.glsl +++ b/Samples/Media/2.0/scripts/materials/Common/GLSL/GaussianBlurBase_cs.glsl @@ -1,5 +1,11 @@ @property( syntax != glslvk ) - #version 430 + @property( GL3+ >= 430 ) + #version 430 + @else + #version 420 + #extension GL_ARB_arrays_of_arrays: enable + #extension GL_ARB_compute_shader: enable + @end @else #version 450 @end diff --git a/Samples/Media/2.0/scripts/materials/Tutorial_Terrain/GLSL/TerraShadowGenerator.glsl b/Samples/Media/2.0/scripts/materials/Tutorial_Terrain/GLSL/TerraShadowGenerator.glsl index e519d273606..94083379ab3 100644 --- a/Samples/Media/2.0/scripts/materials/Tutorial_Terrain/GLSL/TerraShadowGenerator.glsl +++ b/Samples/Media/2.0/scripts/materials/Tutorial_Terrain/GLSL/TerraShadowGenerator.glsl @@ -1,5 +1,10 @@ @property( syntax != glslvk ) - #version 430 + @property( GL3+ >= 430 ) + #version 430 + @else + #version 420 + #extension GL_ARB_compute_shader: enable + @end #define ogre_B0 binding = 0 #define ogre_B1 binding = 1 @else From 41494bdfd476235b38437cf7468d496ef41e34ee Mon Sep 17 00:00:00 2001 From: cryham Date: Mon, 22 May 2023 19:35:46 +0200 Subject: [PATCH 06/58] fix space between _h and ( --- Samples/Media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/Media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any index 3fdbdf88642..76a7a12c710 100644 --- a/Samples/Media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any @@ -331,7 +331,7 @@ midf3 BRDF_IR( midf3 lightDir, midf3 lightDiffuse, PixelData pixelData ) midf3 clearCoatEnvBRDF = midf3_c( 1.0f, 0.0f, 1.0f ); @end - Rs += pixelData.clearCoatEnvColourS * pixelData.specular.xyz * ( _h ( 0.04 ) * clearCoatEnvBRDF.x + clearCoatEnvBRDF.y ) * pixelData.clearCoat; + Rs += pixelData.clearCoatEnvColourS * pixelData.specular.xyz * ( _h( 0.04 ) * clearCoatEnvBRDF.x + clearCoatEnvBRDF.y ) * pixelData.clearCoat; @end finalColour += Rd + Rs; From f1add1e548c2e4d501dfe2f836fa3f9ad0f164b8 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 22 May 2023 20:57:29 -0300 Subject: [PATCH 07/58] [Docs] Fix broken links in Hlms page --- Docs/src/manual/hlms.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Docs/src/manual/hlms.md b/Docs/src/manual/hlms.md index 7e7b4f17298..0b5b9a96910 100644 --- a/Docs/src/manual/hlms.md +++ b/Docs/src/manual/hlms.md @@ -519,7 +519,7 @@ Saves all the text inside the blocks and saves it as a named piece. If a piece with the given name already exists, a compiler error will be thrown. The text that was inside the block won't be printed. Useful when in combination with `@insertpiece`. Pieces can also be defined from C++ or -[collected](#9.3.Hlms templates|outline) from piece template files. +[collected](#HlmsTemplates) from piece template files. Trying to define a piece twice will result in error and may produce incorrect output. @@ -629,7 +629,7 @@ output showed the overriden `Hello` version. ### @pset padd psub pmul pdiv pmod pmin pmax {#HlmsPreprocessorSyntaxPsetEtc} Analogous to [the family of math functions without the 'p' -prefix](#9.4.1.5.\@set add sub mul div mod|outline). The difference is +prefix](#HlmsPreprocessorSyntaxSetEtc). The difference is that the math is evaluated before anything else. There is no much use to these functions, probably except for quickly testing whether a given flag/variable is being properly set from C++ without having to @@ -681,7 +681,7 @@ The following graph summarizes the process: Later on during rendering, at the start each render pass, a similar process is done, which ends up generating a [pass -hash](#9.6.1.preparePassHash|outline) instead of a renderable hash. +hash](#HlmsRuntimeRenderingPreparePassHash) instead of a renderable hash. Pass data stores settings like number of shadow casting lights, number of lights per type (directional, point, spot). @@ -797,7 +797,7 @@ There are different levels in which an Hlms implementation can be customized: 1. Using a library, see [Hlms - Initialization](#8.8.1.Initialization|outline). pass a set of piece + Initialization](#UsingHlmsImplementationInitialization). pass a set of piece files in a folder by pushing the folder to `ArchiveVec`. The files in that folder will be parsed first, in order (`archiveVec[0]` then `archiveVec[1]`, ... `archiveVec[N-1]`); which will let you define @@ -1074,7 +1074,7 @@ configurations, and only apply for textures being loaded for the first time. **The texture type is ignored when such texture has already been loaded, and beware that it may have been packed with different settings**. If you need to load it with different parameters, see -[aliasing](#8.9.1.4.Loading a texture twice (i.e. with a different format) via aliasing|outline). +[Loading a texture twice via aliasing](#HlmsTextureManagerAutomaticBatchingLoadingTwice). The following types are defined: @@ -1483,4 +1483,4 @@ Only Vulkan and Metal can currently take advantage of these settings and is like Support is very new: we've encountered various bugs (in drivers, in [spirv-reflect](https://github.com/KhronosGroup/SPIRV-Reflect/issues/134), in [fxc](https://twitter.com/matiasgoldberg/status/1485758709473189888), in [RenderDoc](https://github.com/baldurk/renderdoc/issues/2466)) **so users are advised to test this option thoroughly before deploying it to end users.** -Metal is likely the API with best half 16-bit support at the moment. \ No newline at end of file +Metal is likely the API with best half 16-bit support at the moment. From 501500a8e7b426348dcf29c1333c727bbf28349c Mon Sep 17 00:00:00 2001 From: Crystal Hammer <720641+cryham@users.noreply.github.com> Date: Tue, 23 May 2023 17:23:15 +0200 Subject: [PATCH 08/58] Docs fixes (#390) * fix typo behavor * docs: some spelling fixes, more formal words etc * docs: more fixes * docs: hlms last fixes * docs: add note hlms @ precedence over // * docs: hlms add more missing custom_* found in .any, need description * docs: restore set "key" to the given value * docs: replace .. with TBD --- .../manual/BehaviorOfStagingTexturesD3D11.md | 2 +- Docs/src/manual/hlms.md | 88 ++++++++++--------- Docs/src/manual/manual.md | 2 +- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/Docs/src/manual/BehaviorOfStagingTexturesD3D11.md b/Docs/src/manual/BehaviorOfStagingTexturesD3D11.md index 7b5285a3991..9c2ca5fa3fd 100644 --- a/Docs/src/manual/BehaviorOfStagingTexturesD3D11.md +++ b/Docs/src/manual/BehaviorOfStagingTexturesD3D11.md @@ -1,4 +1,4 @@ -# Behavor of StagingTexture in D3D11 {#BehavorStagingTextureD3D11} +# Behavior of StagingTexture in D3D11 {#BehaviorStagingTextureD3D11} __Note:__ this article is intended for developers who want to understand or modify Ogre. diff --git a/Docs/src/manual/hlms.md b/Docs/src/manual/hlms.md index 0b5b9a96910..85c6a4821cc 100644 --- a/Docs/src/manual/hlms.md +++ b/Docs/src/manual/hlms.md @@ -145,7 +145,7 @@ was cut as well. The HLMS default systems handle these. these files (or write some of their own) to fit their custom needs. 3. **C++ classes implementation.** The C++ takes care of picking the shader templates and manipulating them before compiling; and most - importantly it feeds the shaders with uniform/constans data and sets + importantly it feeds the shaders with uniform/constants data and sets the textures that are being in use. It is extremely flexible, powerful, efficient and scalable, but it's harder to use than good ol' Materials because those used to be data-driven: there are no @@ -153,12 +153,11 @@ was cut as well. The HLMS default systems handle these. the camera when the scene pass is about to start, and then pass it yourself to the shader. This is very powerful, because in D3D11/GL3+ you can just set the uniform buffer with the view matrix just once - for the entire frame, and thus have multiple uniforms buffers sorted - by update frequency. Very advanced user will be using messing with - this part. + for the entire frame, and thus have multiple uniform buffers sorted + by update frequency. Very advanced user will be using this part. -Based on your skillset and needs, you can pick up to which parts you -want to mess with. Most users will just use the scripts to define +Based on your skillset and needs, you can pick which parts you +want to tinker with. Most users will just use the scripts to define materials, advanced users will change the template, and very advanced users who need something entirely different will change all three. @@ -167,7 +166,7 @@ implementation and its own set of shader templates. The Toon Shading has its own C++ implementation and set of shaders. There is also an "Unlit" implementation, specifically meant to deal with GUI and simple particle FXs (ignores normals & lighting, manages multiple UVs, can mix multiple -texture with photoshop-like blend modes, can animate the UVs, etc) +texture with photoshop-like blend modes, can animate the UVs, etc). It is theoretically possible to implement both Toon & PBS in the same C++ module, but that would be crazy, hard to maintain and not very @@ -236,7 +235,7 @@ We also sort by blendblocks to reduce state changes. ## Samplerblocks {#HlmsBlocksSampleblocks} Samplerblocks hold information about texture units, like filtering -options, addressing modes (wrap, clamp, etc), Lod bias, anisotropy, +options, addressing modes (wrap, clamp, etc), LOD bias, anisotropy, border colour, etc. They're analogous to `D3D11_SAMPLER_DESC`. GL3+ and D3D11 both support samplerblocks natively[^12]. On GLES2, the @@ -264,7 +263,7 @@ according to the following rules: 1. The files with the names "VertexShader\_vs", "PixelShader\_ps", "GeometryShader\_gs", "HullShader\_hs", "DomainShader\_ds" will be fully parsed and compiled into the shader. If an implementation only - provides "VertexShader\_vs.glsl", "PixelShader\_ps.glsl"; only the + provides "VertexShader\_vs.glsl", "PixelShader\_ps.glsl" only the vertex and pixel shaders for OpenGL will be created. There will be no geometry or tesellation shaders. 2. The files that contain the string "piece\_vs" in their filenames @@ -277,7 +276,7 @@ according to the following rules: shortcut to collect from a piece file in all stages. The Hlms takes a template file (i.e. a file written in GLSL or HLSL) and -spits out valid shader code. Templates can take advantage of the Hlms' +produces valid shader code. Templates can take advantage of the Hlms' preprocessor, which is a simple yet powerful macro-like preprocessor that helps writing the required code. @@ -332,6 +331,9 @@ case sensitive. The following keywords are recognized: - \@insertpiece - \@pset padd psub pmul pdiv pmod pmin pmax +Note: @ takes precedence over comment //. If you comment out with // +a line that has @, it will _not_ be commented out. + ### \@property( expression ) {#HlmsPreprocessorSyntaxProperty} Checks whether the variables in the expression are true, if so, the text @@ -402,13 +404,13 @@ Which will print: Loop that prints the text inside the block, The text is repeated `count - start` times. Must be finalized with `@end`. -- count The number of times to repeat the loop (if start = 0). Count +- `count` The number of times to repeat the loop (if start = 0). Count can read variables. - `scopedVar` is a variable that can be used to print the current iteration of the loop while inside the block. i.e. `@scopedVar` will be converted into a number in the range \[start; - count) -- start Optional. Allows to start from a value different than 0. Start + count). +- `start` Optional. Allows to start from a value different than 0. Start can read variables. Newlines are very important, as they will be printed with the loop. @@ -451,7 +453,7 @@ Examples: > @end > > @end ->``` +> ``` > > Because psub will be evaluated before expanding the foreach. @@ -515,7 +517,7 @@ Useful in combination with `@counter` and `@value` ### @piece( nameOfPiece ) {#HlmsPreprocessorSyntaxPiece} -Saves all the text inside the blocks and saves it as a named piece. If a +Saves all the text inside the blocks as a named piece. If a piece with the given name already exists, a compiler error will be thrown. The text that was inside the block won't be printed. Useful when in combination with `@insertpiece`. Pieces can also be defined from C++ or @@ -659,7 +661,7 @@ shader itself and would need to be recompiled: multiplying it against the diffuse colour, etc. 2. The Mesh. Is it skeletally animated? Then include skeletal animation code. How many blend weights? Modify the skeletal animation code - appropiately. It doesn't have tangents? Then skip the normal map + appropriately. It doesn't have tangents? Then skip the normal map defined in the material. And so on. When calling `Renderable::setDatablock()`, what happens is that @@ -679,7 +681,7 @@ The following graph summarizes the process: ![](hlms_hash.svg) -Later on during rendering, at the start each render pass, a similar +Later on during rendering, at the start of each render pass, a similar process is done, which ends up generating a [pass hash](#HlmsRuntimeRenderingPreparePassHash) instead of a renderable hash. Pass data stores settings like number of shadow casting lights, number @@ -709,7 +711,7 @@ To create pieces (or read them) you need to pass your custom The recommended place to do this is in `Hlms::calculateHashForPreCreate` and `Hlms::calculateHashForPreCaster.` Both are virtual. The former gets called right before adding the set of properties, pieces and hash to the -cache, while the latter happens right before adding the similar set for +cache, while the latter happens right before adding a similar set for the shadow caster pass. In those two functions you get the chance to call setProperty to set @@ -745,11 +747,11 @@ For mobile, avoid `mat4` and do the math yourself. As for 4x3 matrices (i.e. skinning), perform the math manually as many GLES2 drivers have issues compiling valid glsl code. -Properties in `underscore_case` are set from C++; propierties in +Properties in `underscore_case` are set from C++; properties in `camelCase` are set from the template. -Propierties and pieces starting with `custom_` are for user -customizations of the template +Properties and pieces starting with `custom_` are for user +customizations of the template. TBD @@ -781,9 +783,9 @@ In many cases, users may want to slightly customize the shaders to achieve a particular look, implement a specific feature, or solve a unique problem; without having to rewrite the whole implementation. -Maximum flexibility can be get by directly modifying the original source +Maximum flexibility can be achieved by directly modifying the original source code. However this isn't modular, making it difficult to merge when the -original source code has changed. Most of of the customizations don't +original source code has changed. Most of the customizations don't require such intrusive approach. **Note:** For performance reasons, the listener interface does not allow @@ -821,32 +823,38 @@ customized: @end ``` -1. Via listener, through `HlmsListener`. This allows you to have access +2. Via listener, through `HlmsListener`. This allows you to have access to the buffer pass to fill extra information; or bind extra buffers to the shader. -2. Overload `HlmsPbs`. Useful for overriding only specific parts, or +3. Overload `HlmsPbs`. Useful for overriding only specific parts, or adding new functionality that requires storing extra information in a datablock (e.g. overload HlmsPbsDatablock to add more variables, and then overload `HlmsPbs::createDatablockImpl` to create these - custom datablocks) -3. Directly modify `HlmsPbs`, `HlmsPbsDatablock` and the template. + custom datablocks). +4. Directly modify `HlmsPbs`, `HlmsPbsDatablock` and the template. | Variable | Description | |----------|-------------| -| custom_passBuffer | Piece where users can add extra information for the pass buffer (only useful if the user is using HlmsListener or overloaded HlmsPbs. | -| custom_VStoPS | Piece where users can add more interpolants for passing data from the vertex to the pixel shader.| +| custom_passBuffer | Piece where users can add extra information for the pass buffer (only useful if the user is using HlmsListener or overloaded HlmsPbs. | +| custom_materialBuffer | TBD | +| custom_VStoPS | Piece where users can add more interpolants for passing data from the vertex to the pixel shader.| | custom_vs_attributes | Custom vertex shader attributes in the Vertex Shader (i.e. a special texcoord, etc).| | custom_vs_uniformDeclaration | Data declaration (textures, texture buffers, uniform buffers) in the Vertex Shader.| +| custom_vs_uniformStructDeclaration | TBD | +| custom_vs_posMaterialLoad | TBD | +| custom_vs_preTransform | TBD | | custom_vs_preExecution | Executed before Ogre's code from the Vertex Shader.| | custom_vs_posExecution | Executed after all code from the Vertex Shader has been performed. | | custom_ps_uniformDeclaration | Same as custom_vs_uniformDeclaration, but for the Pixel Shader| +| custom_ps_uniformStructDeclaration | TBD | | custom_ps_preExecution | Executed before Ogre's code from the Pixel Shader.| | custom_ps_posMaterialLoad | Executed right after loading material data; and before anything else. May not get executed if there is no relevant material data (i.e. doesn't have normals or QTangents for lighting calculation)| +| custom_ps_posSampleNormal | TBD | | custom_ps_preLights | Executed right before any light (i.e. to perform your own ambient / global illumination pass). All relevant texture data should be loaded by now.| | custom_ps_posExecution | Executed after all code from the Pixel Shader has been performed.| | custom_ps_uv_modifier_macros | PBS specific. Allows you to override the macros defined in Samples/Media/Hlms/Pbs/Any/UvModifierMacros_piece_ps.any so you can apply custom transformations to each UV. e.g. `#undef UV_DIFFUSE #define UV_DIFFUSE( x ) ((x) * 2.0)` | -| custom_ps_functions | Used to declare functions outside the main body of the shader | -| custom_ps_pixelData | Declare additional data in `struct PixelData` from Pixel Shader | +| custom_ps_functions | Used to declare functions outside the main body of the shader | +| custom_ps_pixelData | Declare additional data in `struct PixelData` from Pixel Shader | # Run-time rendering {#HlmsRuntimeRendering} @@ -964,8 +972,8 @@ named "Green". However only one can be visible to the manager; let's assume that the PBS one was made visible. When you call `Renderable::setDatablock( "Green" )`, the HlmsManager will -look the one that is visible to it. To assign the Unlit version of -"Green" instead of the PBS one, you will have call the overload that +look for the one that is visible to it. To assign the Unlit version of +"Green" instead of the PBS one, you will have to call the overload that specifies the pointer, and grab the datablock from the implementation itself: `Renderable::setDatablock( hlmsUnlit->getDatablock( "Green" ) )`; @@ -977,7 +985,7 @@ editors and other GUIs based on Ogre to display the material's name; since IdString destroys the original string in Release mode. HlmsParamVec is an array/vector of key-value string pairs to specify -custom parameters on creation. Valid values depends on the +custom parameters on creation. Valid values depend on the implementation. You should see the Constructor's documentation for more information on them. @@ -1055,7 +1063,7 @@ the texture combinations that can be packed together. When the texture is being loaded for the first time, the manager will try to insert it into the first available array/atlas it sees, or else create a new one. Several parameters affect the creation of the texture -array/atlas, which can be configured in +array/atlas, which can be configured in: ```cpp DefaultTextureParameters mDefaultTextureParameters[NUM_TEXTURE_TYPES]; @@ -1096,7 +1104,7 @@ The reasons to have multiple profiles are simple: (i.e. `PF_L8`) even if the original is stored as a 32-bit RGBA PNG file. Furthermore, sRGB (gamma correction) is disabled for these textures. -3. Detail maps & its normal maps are usually meant to be tileable. +3. Detail maps and their normal maps are usually meant to be tileable. Therefore on mobile, UV atlas is disabled. Desktop-only Hlms implementations already skip the use of @@ -1107,7 +1115,7 @@ since they're only useful in Mobile; and use `TEXTURE_TYPE_DIFFUSE` and ### Automatic parameters {#HlmsTextureManagerAutomaticBatchingAutoParams} The packing algorithm uses multiple criteria to determine whether it -should pack or not a texture: +should pack a texture or not: ```cpp /// Textures whose size are less or equal to minTextureSize @@ -1217,7 +1225,7 @@ The reasons to use texture packs are varied: - Improve loading time by baking as much information as possible offline. - Certain formats can't be batched at runtime for UV atlas (i.e. - PVRTC2) and thus needs to done offline. + PVRTC2) and thus it needs to be done offline. TBD @@ -1238,11 +1246,11 @@ To prevent this particular case, the `textureArraysTresholds` parameter will kick in; and will clamp `maxTexturesPerArray` to 1. Nonetheless, special attention needs to be taken to ensure maximum -occupancy of the each array. +occupancy of each array. The function `HlmsTextureManager::dumpMemoryUsage` is a powerful tool that will dump all loaded textures to the log in CSV format using '|' as -separator for further analysis on MS Excel or OpenOffice Calc. +separator for further analysis in MS Excel or OpenOffice Calc. The following is an example of the dump's output: diff --git a/Docs/src/manual/manual.md b/Docs/src/manual/manual.md index a251fc0b182..872936158b5 100644 --- a/Docs/src/manual/manual.md +++ b/Docs/src/manual/manual.md @@ -18,7 +18,7 @@ painful and traumatic as possible. - @subpage TerraSystem - @subpage TuningMemoryResources - @subpage Ogre22Changes -- @subpage BehavorStagingTextureD3D11 +- @subpage BehaviorStagingTextureD3D11 - @subpage Ogre23Changes - @subpage RootLayouts - @subpage ResolvingMergeConflicts30 From 90c2fa2f57eefa7551e6fef66aaab6cca612bfea Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 23 May 2023 23:22:17 -0300 Subject: [PATCH 09/58] Fix planar reflections' actor culling Thanks jwwalker for spotting these issues. See https://forums.ogre3d.org/viewtopic.php?p=554613 --- .../src/OgrePlanarReflections.cpp | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/Components/PlanarReflections/src/OgrePlanarReflections.cpp b/Components/PlanarReflections/src/OgrePlanarReflections.cpp index ef8075fbbed..c2e393a77a7 100644 --- a/Components/PlanarReflections/src/OgrePlanarReflections.cpp +++ b/Components/PlanarReflections/src/OgrePlanarReflections.cpp @@ -521,29 +521,32 @@ namespace Ogre ArrayMaskR vertexMask = ARRAY_MASK_ZERO; ArrayReal dotResult; - ArrayVector3 tangentDir, vertexPoint; + ArrayVector3 tangentDir, vertexPoint, xMidpoint, yMidpoint; - tangentDir = actorsPlanes->planeNormals.yAxis() * actorsPlanes->xyHalfSize[1]; + xMidpoint = actorsPlanes->planeNormals.xAxis() * actorsPlanes->xyHalfSize[0]; + yMidpoint = actorsPlanes->planeNormals.yAxis() * actorsPlanes->xyHalfSize[1]; + + tangentDir = xMidpoint + yMidpoint; vertexPoint = actorsPlanes->center + tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; + dotResult = frustums[k].normal.dotProduct( vertexPoint ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); vertexPoint = actorsPlanes->center - tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; + dotResult = frustums[k].normal.dotProduct( vertexPoint ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); - tangentDir = actorsPlanes->planeNormals.xAxis() * actorsPlanes->xyHalfSize[0]; + tangentDir = xMidpoint - yMidpoint; vertexPoint = actorsPlanes->center + tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; + dotResult = frustums[k].normal.dotProduct( vertexPoint ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); vertexPoint = actorsPlanes->center - tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; + dotResult = frustums[k].normal.dotProduct( vertexPoint ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); mask = Mathlib::And( mask, vertexMask ); } @@ -566,9 +569,9 @@ namespace Ogre // for( int l=0; l<8; ++l ) for( int l = 0; l < 4; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -578,21 +581,21 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l = 0; l < 8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); // North plane - actorPlaneNormal = actorsPlanes->planeNormals.yAxis(); + actorPlaneNormal = -actorsPlanes->planeNormals.yAxis(); actorPlaneNegD = actorsPlanes->planeNegD[1]; vertexMask = ARRAY_MASK_ZERO; for( int l = 0; l < 8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -602,21 +605,21 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l = 0; l < 8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); // East plane - actorPlaneNormal = actorsPlanes->planeNormals.xAxis(); + actorPlaneNormal = -actorsPlanes->planeNormals.xAxis(); actorPlaneNegD = actorsPlanes->planeNegD[3]; vertexMask = ARRAY_MASK_ZERO; for( int l = 0; l < 8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -626,9 +629,9 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l = 0; l < 8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); vertexMask = - Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, ARRAY_REAL_ZERO ) ); + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); } From e4972e15c07cdd6a92946c5c1ff3c151d3c389e7 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 23 May 2023 23:22:57 -0300 Subject: [PATCH 10/58] Show Planar Reflections' number of active actors Actors culled away are deactivated and the UI reflects this. --- .../PlanarReflections/include/OgrePlanarReflections.h | 2 ++ .../PlanarReflections/src/OgrePlanarReflections.cpp | 11 +++++++++++ .../PlanarReflections/PlanarReflectionsGameState.cpp | 1 + 3 files changed, 14 insertions(+) diff --git a/Components/PlanarReflections/include/OgrePlanarReflections.h b/Components/PlanarReflections/include/OgrePlanarReflections.h index 69afc16cf09..0d0cec17650 100644 --- a/Components/PlanarReflections/include/OgrePlanarReflections.h +++ b/Components/PlanarReflections/include/OgrePlanarReflections.h @@ -278,6 +278,8 @@ namespace Ogre uint8 getMaxNumMipmaps() const { return mMaxNumMipmaps; } + uint8 countActiveActors() const; + enum CustomParameterBits { // clang-format off diff --git a/Components/PlanarReflections/src/OgrePlanarReflections.cpp b/Components/PlanarReflections/src/OgrePlanarReflections.cpp index c2e393a77a7..54410eb59d8 100644 --- a/Components/PlanarReflections/src/OgrePlanarReflections.cpp +++ b/Components/PlanarReflections/src/OgrePlanarReflections.cpp @@ -928,4 +928,15 @@ namespace Ogre { return ( renderable->mCustomParameter & UseActiveActor ) != 0; } + //----------------------------------------------------------------------------------- + uint8 PlanarReflections::countActiveActors() const + { + uint8 numActors = 0u; + for( const PlanarReflectionActor *actor : mActiveActors ) + { + if( actor != &mDummyActor ) + ++numActors; + } + return numActors; + } } // namespace Ogre diff --git a/Samples/2.0/ApiUsage/PlanarReflections/PlanarReflectionsGameState.cpp b/Samples/2.0/ApiUsage/PlanarReflections/PlanarReflectionsGameState.cpp index 7115249b0a3..532215d2170 100644 --- a/Samples/2.0/ApiUsage/PlanarReflections/PlanarReflectionsGameState.cpp +++ b/Samples/2.0/ApiUsage/PlanarReflections/PlanarReflectionsGameState.cpp @@ -313,6 +313,7 @@ namespace Demo TutorialGameState::generateDebugText( timeSinceLast, outText ); outText += "\nPress F2 to toggle animation. "; outText += mAnimateObjects ? "[On]" : "[Off]"; + outText += "\nNum actors active: " + std::to_string( mPlanarReflections->countActiveActors() ); } //----------------------------------------------------------------------------------- void PlanarReflectionsGameState::keyReleased( const SDL_KeyboardEvent &arg ) From 773e4fd6e0fdc4e6bcff12d332a5f775d9f7fdeb Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 23 May 2023 23:22:17 -0300 Subject: [PATCH 11/58] Fix planar reflections' actor culling Thanks jwwalker for spotting these issues. See https://forums.ogre3d.org/viewtopic.php?p=554613 --- .../src/OgrePlanarReflections.cpp | 87 +++++++++---------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/Components/PlanarReflections/src/OgrePlanarReflections.cpp b/Components/PlanarReflections/src/OgrePlanarReflections.cpp index 4bd20ffc273..1f06c4b0f88 100644 --- a/Components/PlanarReflections/src/OgrePlanarReflections.cpp +++ b/Components/PlanarReflections/src/OgrePlanarReflections.cpp @@ -522,33 +522,32 @@ namespace Ogre ArrayMaskR vertexMask = ARRAY_MASK_ZERO; ArrayReal dotResult; - ArrayVector3 tangentDir, vertexPoint; + ArrayVector3 tangentDir, vertexPoint, xMidpoint, yMidpoint; - tangentDir = actorsPlanes->planeNormals.yAxis() * actorsPlanes->xyHalfSize[1]; + xMidpoint = actorsPlanes->planeNormals.xAxis() * actorsPlanes->xyHalfSize[0]; + yMidpoint = actorsPlanes->planeNormals.yAxis() * actorsPlanes->xyHalfSize[1]; + + tangentDir = xMidpoint + yMidpoint; vertexPoint = actorsPlanes->center + tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); vertexPoint = actorsPlanes->center - tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); - tangentDir = actorsPlanes->planeNormals.xAxis() * actorsPlanes->xyHalfSize[0]; + tangentDir = xMidpoint - yMidpoint; vertexPoint = actorsPlanes->center + tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); vertexPoint = actorsPlanes->center - tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); mask = Mathlib::And( mask, vertexMask ); } @@ -571,10 +570,9 @@ namespace Ogre //for( int l=0; l<8; ++l ) for( int l=0; l<4; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -584,23 +582,21 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); - //North plane - actorPlaneNormal = actorsPlanes->planeNormals.yAxis(); + // North plane + actorPlaneNormal = -actorsPlanes->planeNormals.yAxis(); actorPlaneNegD = actorsPlanes->planeNegD[1]; vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -610,23 +606,21 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); - //East plane - actorPlaneNormal = actorsPlanes->planeNormals.xAxis(); + // East plane + actorPlaneNormal = -actorsPlanes->planeNormals.xAxis(); actorPlaneNegD = actorsPlanes->planeNegD[3]; vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -636,10 +630,9 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); } From 8c05a5c260272b35bbcf1073a051735bf27b25c9 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 23 May 2023 23:22:17 -0300 Subject: [PATCH 12/58] Fix planar reflections' actor culling Thanks jwwalker for spotting these issues. See https://forums.ogre3d.org/viewtopic.php?p=554613 --- .../src/OgrePlanarReflections.cpp | 87 +++++++++---------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/Components/PlanarReflections/src/OgrePlanarReflections.cpp b/Components/PlanarReflections/src/OgrePlanarReflections.cpp index aeb8039d637..e60f16157a7 100644 --- a/Components/PlanarReflections/src/OgrePlanarReflections.cpp +++ b/Components/PlanarReflections/src/OgrePlanarReflections.cpp @@ -522,33 +522,32 @@ namespace Ogre ArrayMaskR vertexMask = ARRAY_MASK_ZERO; ArrayReal dotResult; - ArrayVector3 tangentDir, vertexPoint; + ArrayVector3 tangentDir, vertexPoint, xMidpoint, yMidpoint; - tangentDir = actorsPlanes->planeNormals.yAxis() * actorsPlanes->xyHalfSize[1]; + xMidpoint = actorsPlanes->planeNormals.xAxis() * actorsPlanes->xyHalfSize[0]; + yMidpoint = actorsPlanes->planeNormals.yAxis() * actorsPlanes->xyHalfSize[1]; + + tangentDir = xMidpoint + yMidpoint; vertexPoint = actorsPlanes->center + tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); vertexPoint = actorsPlanes->center - tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); - tangentDir = actorsPlanes->planeNormals.xAxis() * actorsPlanes->xyHalfSize[0]; + tangentDir = xMidpoint - yMidpoint; vertexPoint = actorsPlanes->center + tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); vertexPoint = actorsPlanes->center - tangentDir; - dotResult = frustums[k].normal.dotProduct( vertexPoint ) - frustums[k].negD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = frustums[k].normal.dotProduct( vertexPoint ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, frustums[k].negD ) ); mask = Mathlib::And( mask, vertexMask ); } @@ -571,10 +570,9 @@ namespace Ogre //for( int l=0; l<8; ++l ) for( int l=0; l<4; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -584,23 +582,21 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); - //North plane - actorPlaneNormal = actorsPlanes->planeNormals.yAxis(); + // North plane + actorPlaneNormal = -actorsPlanes->planeNormals.yAxis(); actorPlaneNegD = actorsPlanes->planeNegD[1]; vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -610,23 +606,21 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); - //East plane - actorPlaneNormal = actorsPlanes->planeNormals.xAxis(); + // East plane + actorPlaneNormal = -actorsPlanes->planeNormals.xAxis(); actorPlaneNegD = actorsPlanes->planeNegD[3]; vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); @@ -636,10 +630,9 @@ namespace Ogre vertexMask = ARRAY_MASK_ZERO; for( int l=0; l<8; ++l ) { - dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ) - actorPlaneNegD; - vertexMask = Mathlib::Or( vertexMask, - Mathlib::CompareGreater( dotResult, - ARRAY_REAL_ZERO ) ); + dotResult = actorPlaneNormal.dotProduct( worldSpaceCorners[l] ); + vertexMask = + Mathlib::Or( vertexMask, Mathlib::CompareGreater( dotResult, actorPlaneNegD ) ); } mask = Mathlib::And( mask, vertexMask ); } From 6196eb5cb1d0dee475f697c16b4dc63e8d9e92a9 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Wed, 24 May 2023 13:56:58 -0300 Subject: [PATCH 13/58] Fix clang format --- .../GL3Plus/src/OgreGL3PlusTextureGpu.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp index 86aa27a212e..a77741a019c 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp @@ -666,21 +666,21 @@ namespace Ogre static_cast( srcBox.getDepthOrSlices() ) ) ); } else if( support.checkExtension( "GL_NV_copy_image" ) ) - { - // Initialize the pointer only the first time + { + // Initialize the pointer only the first time PFNGLCOPYIMAGESUBDATANVPROC local_glCopyImageSubDataNV = nullptr; - if (!local_glCopyImageSubDataNV) + if( !local_glCopyImageSubDataNV ) { - local_glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)gl3wGetProcAddress("glCopyImageSubDataNV"); + local_glCopyImageSubDataNV = + (PFNGLCOPYIMAGESUBDATANVPROC)gl3wGetProcAddress( "glCopyImageSubDataNV" ); } - OCGE( local_glCopyImageSubDataNV( this->mFinalTextureName, this->mGlTextureTarget, - srcMipLevel, srcBox.x, srcBox.y, - srcBox.getZOrSlice() + this->getInternalSliceStart(), - dstGl->mFinalTextureName, dstGl->mGlTextureTarget, - dstMipLevel, dstBox.x, dstBox.y, - dstBox.getZOrSlice() + dstGl->getInternalSliceStart(), - srcBox.width, srcBox.height, srcBox.getDepthOrSlices() ) ); + OCGE( local_glCopyImageSubDataNV( + this->mFinalTextureName, this->mGlTextureTarget, srcMipLevel, srcBox.x, srcBox.y, + srcBox.getZOrSlice() + this->getInternalSliceStart(), dstGl->mFinalTextureName, + dstGl->mGlTextureTarget, dstMipLevel, dstBox.x, dstBox.y, + dstBox.getZOrSlice() + dstGl->getInternalSliceStart(), srcBox.width, srcBox.height, + srcBox.getDepthOrSlices() ) ); } /*TODO: These are for OpenGL ES 3.0+ else if( support.checkExtension( "GL_OES_copy_image" ) ) From bc6377730ddebf98dce9d3c71bbbc611dcc4b48f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 28 May 2023 17:06:43 -0300 Subject: [PATCH 14/58] HlmsPbsDatablock::setUserValue never calls scheduleConstBufferUpdate() --- Components/Hlms/Pbs/src/OgreHlmsPbsDatablock.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Components/Hlms/Pbs/src/OgreHlmsPbsDatablock.cpp b/Components/Hlms/Pbs/src/OgreHlmsPbsDatablock.cpp index 24c35e74ab3..cb8295514ec 100644 --- a/Components/Hlms/Pbs/src/OgreHlmsPbsDatablock.cpp +++ b/Components/Hlms/Pbs/src/OgreHlmsPbsDatablock.cpp @@ -960,6 +960,7 @@ namespace Ogre mUserValue[userValueIdx][1] = value.y; mUserValue[userValueIdx][2] = value.z; mUserValue[userValueIdx][3] = value.w; + scheduleConstBufferUpdate(); } //----------------------------------------------------------------------------------- Vector4 HlmsPbsDatablock::getUserValue(uint8 userValueIdx) const From 8b9c22955068eba1b92687a21e3fda9956c4b6ec Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 6 Jun 2023 11:28:42 -0300 Subject: [PATCH 15/58] List python 3 as a dependency --- Docs/src/SettingUpOgre/SettingUpOgreAndroid.md | 2 +- Docs/src/SettingUpOgre/SettingUpOgreWindows.md | 1 + README.md | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md b/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md index a06f7f44e82..dbe2f48dd52 100644 --- a/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md +++ b/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md @@ -7,7 +7,7 @@ - Git - Android Studio 4.0 - Android SDK & NDK - - Python 3.x (to build the samples) + - Python 3.x is needed to build shaderc dependency for Vulkan. - Vulkan-capable Android phone. - Android 8.0 or newer strongly recommended. Android 7.0 and 7.1 are supported, but most phones are bundled with very old and buggy drivers. diff --git a/Docs/src/SettingUpOgre/SettingUpOgreWindows.md b/Docs/src/SettingUpOgre/SettingUpOgreWindows.md index 6a9e3270d8c..0eac603c415 100644 --- a/Docs/src/SettingUpOgre/SettingUpOgreWindows.md +++ b/Docs/src/SettingUpOgre/SettingUpOgreWindows.md @@ -14,6 +14,7 @@ * Windows 7 or higher is highly recommended. For Windows Vista & 7, you need to have the [KB2670838 update](https://support.microsoft.com/en-us/kb/2670838) installed. **YOUR END USERS NEED THIS UPDATE AS WELL**. + * Python 3.x is needed to build shaderc dependency for Vulkan. * For HW & SW requirements, please visit http://www.ogre3d.org/developers/requirements @copydoc DownloadingOgreScriptsCommon diff --git a/README.md b/README.md index ffb68507517..be92c51bd4b 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ For a list of samples and their demonstrated features, refer to the [samples sec * Git * For HW & SW requirements, please visit http://www.ogre3d.org/developers/requirements * Our source dependencies are grouped in [ogre-next-deps](https://github.com/OGRECave/ogre-next-deps) repo +* Python 3.x is needed to build shaderc dependency for Vulkan. # Dependencies (Windows) From c95b4ef16474c1b42d0860a7ded6ef4daa1411ce Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 6 Jun 2023 19:48:34 -0300 Subject: [PATCH 16/58] [Metal] Check for BCn compression on macOS Big Sur Fill the vendor on iOS & M1 systems with GPU_APPLE --- .../Metal/src/OgreMetalRenderSystem.mm | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/RenderSystems/Metal/src/OgreMetalRenderSystem.mm b/RenderSystems/Metal/src/OgreMetalRenderSystem.mm index b78087c2085..2dbc8c32c3d 100644 --- a/RenderSystems/Metal/src/OgreMetalRenderSystem.mm +++ b/RenderSystems/Metal/src/OgreMetalRenderSystem.mm @@ -265,6 +265,10 @@ of this software and associated documentation files (the "Software"), to deal rsc->setDeviceName( mActiveDevice->mDevice.name.UTF8String ); +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS || OGRE_CPU == OGRE_CPU_ARM + rsc->setVendor( GPU_APPLE ); +#endif + rsc->setCapability( RSC_HWSTENCIL ); rsc->setStencilBufferBitDepth( 8 ); rsc->setNumTextureUnits( 16 ); @@ -280,9 +284,20 @@ of this software and associated documentation files (the "Software"), to deal rsc->setCapability( RSC_TEXTURE_COMPRESSION_ASTC ); #endif #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - rsc->setCapability( RSC_TEXTURE_COMPRESSION_DXT ); - rsc->setCapability( RSC_TEXTURE_COMPRESSION_BC4_BC5 ); - // rsc->setCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7); + // If the device is running macOS older than 11, + // then they are all x86 systems which all support BCn + bool supportsBCTextureCompression = true; + if( @available( macOS 11, * ) ) + { + supportsBCTextureCompression = mActiveDevice->mDevice.supportsBCTextureCompression + } + + if( supportsBCTextureCompression ) + { + rsc->setCapability( RSC_TEXTURE_COMPRESSION_DXT ); + rsc->setCapability( RSC_TEXTURE_COMPRESSION_BC4_BC5 ); + // rsc->setCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7); + } #else // Actually the limit is not the count but rather how many bytes are in the // GPU's internal TBDR cache (16 bytes for Family 1, 32 bytes for the rest) From 7404bd089612c39c42c5d623317f8196cbb60bd5 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Wed, 7 Jun 2023 17:42:51 +0200 Subject: [PATCH 17/58] DeflateStream can throw in close() > compressFinal() and then crash in .dtor() > close() > compressFinal() --- OgreMain/src/OgreDeflate.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OgreMain/src/OgreDeflate.cpp b/OgreMain/src/OgreDeflate.cpp index 0ad84ba11d6..5f285f079b2 100644 --- a/OgreMain/src/OgreDeflate.cpp +++ b/OgreMain/src/OgreDeflate.cpp @@ -286,6 +286,10 @@ namespace Ogre //--------------------------------------------------------------------- void DeflateStream::compressFinal() { + // Prevent reenterancy + if( !mTmpWriteStream ) + return; + // Close temp stream mTmpWriteStream->close(); mTmpWriteStream.reset(); From a0b840c9e481b307942a3835988f7e79a8869a05 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Wed, 7 Jun 2023 21:03:29 -0300 Subject: [PATCH 18/58] Fix derived Hlms materials not properly overriding base settings --- OgreMain/src/OgreScriptTranslator.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/OgreMain/src/OgreScriptTranslator.cpp b/OgreMain/src/OgreScriptTranslator.cpp index 23331d8b18a..fa756f954e4 100644 --- a/OgreMain/src/OgreScriptTranslator.cpp +++ b/OgreMain/src/OgreScriptTranslator.cpp @@ -680,9 +680,9 @@ namespace Ogre{ HlmsManager *hlmsManager = Root::getSingleton().getHlmsManager(); Hlms *hlms = 0; - HlmsParamVec paramVec; - - paramVec.reserve( obj->children.size() ); + // We need a map to deal with materials that define the same setting multiple times. + // The last defined version must win. + map::type paramMap; const IdString idType( type ); for( size_t i=0; iname, value ); + paramMap[prop->name] = value; } } } @@ -1239,7 +1239,10 @@ namespace Ogre{ } } - std::sort( paramVec.begin(), paramVec.end(), OrderParamVecByKey ); + HlmsParamVec paramVec; + paramVec.reserve( paramMap.size() ); + paramVec.insert( paramVec.begin(), paramMap.begin(), paramMap.end() ); + blendblock.calculateSeparateBlendMode(); hlms->createDatablock( obj->name, obj->name, macroblock, blendblock, paramVec, true, obj->file, compiler->getResourceGroup() ); From 12a0df6d3463f68e42bc6231d182c2ccc08accd0 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Wed, 7 Jun 2023 21:04:28 -0300 Subject: [PATCH 19/58] Fix clang format --- OgreMain/src/OgreDeflate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OgreMain/src/OgreDeflate.cpp b/OgreMain/src/OgreDeflate.cpp index 5f285f079b2..8bd4cfcff4c 100644 --- a/OgreMain/src/OgreDeflate.cpp +++ b/OgreMain/src/OgreDeflate.cpp @@ -289,7 +289,7 @@ namespace Ogre // Prevent reenterancy if( !mTmpWriteStream ) return; - + // Close temp stream mTmpWriteStream->close(); mTmpWriteStream.reset(); From f76c5154bd4277e3253d36c9db3d84835cf5e700 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 8 Jun 2023 13:28:54 +0200 Subject: [PATCH 20/58] fixed Mac build --- RenderSystems/Metal/src/OgreMetalRenderSystem.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RenderSystems/Metal/src/OgreMetalRenderSystem.mm b/RenderSystems/Metal/src/OgreMetalRenderSystem.mm index 2dbc8c32c3d..30a957cb1aa 100644 --- a/RenderSystems/Metal/src/OgreMetalRenderSystem.mm +++ b/RenderSystems/Metal/src/OgreMetalRenderSystem.mm @@ -289,7 +289,7 @@ of this software and associated documentation files (the "Software"), to deal bool supportsBCTextureCompression = true; if( @available( macOS 11, * ) ) { - supportsBCTextureCompression = mActiveDevice->mDevice.supportsBCTextureCompression + supportsBCTextureCompression = mActiveDevice->mDevice.supportsBCTextureCompression; } if( supportsBCTextureCompression ) From 8e86efe4419f3146cc2738cbdb0b958c03cd462c Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 8 Jun 2023 21:22:23 -0300 Subject: [PATCH 21/58] EmptyProject CMake script does not copy Atmosphere DLL (#391) Fix #391 --- .../EmptyProject/CMake/Dependencies/OGRE.cmake | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Samples/2.0/Tutorials/EmptyProject/CMake/Dependencies/OGRE.cmake b/Samples/2.0/Tutorials/EmptyProject/CMake/Dependencies/OGRE.cmake index 43cc4456890..23596b52293 100644 --- a/Samples/2.0/Tutorials/EmptyProject/CMake/Dependencies/OGRE.cmake +++ b/Samples/2.0/Tutorials/EmptyProject/CMake/Dependencies/OGRE.cmake @@ -135,6 +135,10 @@ macro( setupPluginFileFromTemplate BUILD_TYPE OGRE_USE_SCENE_FORMAT OGRE_USE_PLA set( OGRE_DLLS ${OGRE_DLLS} ${OGRE_NEXT}SceneFormat ) endif() + if( NOT OGRE_BUILD_COMPONENT_ATMOSPHERE EQUAL -1 ) + set( OGRE_DLLS ${OGRE_DLLS} ${OGRE_NEXT}Atmosphere ) + endif() + # Deal with OS and Ogre naming shenanigans: # * OgreMain.dll vs libOgreMain.so # * OgreMain_d.dll vs libOgreMain_d.so in Debug mode. @@ -231,12 +235,12 @@ else() endif() isOgreNext( OGRE_USE_NEW_NAME ) -message( STATUS ${OGRE_USE_NEW_NAME} ) if( ${OGRE_USE_NEW_NAME} ) set( OGRE_NEXT "OgreNext" ) else() set( OGRE_NEXT "Ogre" ) endif() +message( STATUS "OgreNext lib name prefix is ${OGRE_NEXT}" ) # Ogre config include_directories( "${OGRE_SOURCE}/OgreMain/include" ) @@ -259,13 +263,13 @@ set( OGRE_DEPENDENCY_LIBS "" ) file( READ "${OGRE_BINARIES}/include/OgreBuildSettings.h" OGRE_BUILD_SETTINGS_STR ) string( FIND "${OGRE_BUILD_SETTINGS_STR}" "#define OGRE_STATIC_LIB" OGRE_STATIC ) if( NOT OGRE_STATIC EQUAL -1 ) - message( STATUS "Detected static build of Ogre" ) + message( STATUS "Detected static build of OgreNext" ) set( OGRE_STATIC "Static" ) # Static builds must link against its dependencies addStaticDependencies( OGRE_SOURCE, OGRE_BINARIES, OGRE_BUILD_SETTINGS_STR, OGRE_DEPENDENCY_LIBS ) else() - message( STATUS "Detected DLL build of Ogre" ) + message( STATUS "Detected DLL build of OgreNext" ) unset( OGRE_STATIC ) endif() findOgreBuildSetting( ${OGRE_BUILD_SETTINGS_STR} OGRE_BUILD_RENDERSYSTEM_GL3PLUS ) From 8c146b4add88ee48536cc200a524247be6a3e104 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Mon, 12 Jun 2023 16:59:18 +0200 Subject: [PATCH 22/58] don't corrupt bytes outside destination area in TextureBox::copyFrom(const TextureBox &src), sometimes causing heap corruption --- OgreMain/include/OgreTextureBox.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OgreMain/include/OgreTextureBox.h b/OgreMain/include/OgreTextureBox.h index 1deb0afb891..1db3b4cc1fb 100644 --- a/OgreMain/include/OgreTextureBox.h +++ b/OgreMain/include/OgreTextureBox.h @@ -217,7 +217,7 @@ namespace Ogre { // Copy row by row, uncompressed. const uint32 finalHeight = this->height; - const size_t finalBytesPerRow = std::min( this->bytesPerRow, src.bytesPerRow ); + const size_t finalBytesPerRow = this->width * this->bytesPerPixel; for( size_t _z = 0; _z < finalDepthOrSlices; ++_z ) { for( size_t _y = 0; _y < finalHeight; ++_y ) @@ -233,11 +233,15 @@ namespace Ogre // Copy row of blocks by row of blocks, compressed. const PixelFormatGpu pixelFormat = getCompressedPixelFormat(); + const uint32 blockSize = PixelFormatGpuUtils::getCompressedBlockSize( pixelFormat ); + const uint32 blockWidth = + PixelFormatGpuUtils::getCompressedBlockWidth( pixelFormat, false ); const uint32 blockHeight = PixelFormatGpuUtils::getCompressedBlockHeight( pixelFormat, false ); const uint32 finalHeight = this->height; - const size_t finalBytesPerRow = std::min( this->bytesPerRow, src.bytesPerRow ); + const size_t finalBytesPerRow = + ( this->width + blockWidth - 1u ) / blockWidth * blockSize; for( size_t _z = 0; _z < finalDepthOrSlices; ++_z ) { for( size_t _y = 0; _y < finalHeight; _y += blockHeight ) From 8c05894668ca353b0e582d65d68ae9868ea98fd8 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 12 Jun 2023 20:40:32 -0300 Subject: [PATCH 23/58] Fix warnings --- OgreMain/include/OgreTextureBox.h | 2 +- RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/OgreMain/include/OgreTextureBox.h b/OgreMain/include/OgreTextureBox.h index 1db3b4cc1fb..75a48537479 100644 --- a/OgreMain/include/OgreTextureBox.h +++ b/OgreMain/include/OgreTextureBox.h @@ -233,7 +233,7 @@ namespace Ogre // Copy row of blocks by row of blocks, compressed. const PixelFormatGpu pixelFormat = getCompressedPixelFormat(); - const uint32 blockSize = PixelFormatGpuUtils::getCompressedBlockSize( pixelFormat ); + const size_t blockSize = PixelFormatGpuUtils::getCompressedBlockSize( pixelFormat ); const uint32 blockWidth = PixelFormatGpuUtils::getCompressedBlockWidth( pixelFormat, false ); const uint32 blockHeight = diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp index a77741a019c..1824125f6c9 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp @@ -676,11 +676,14 @@ namespace Ogre } OCGE( local_glCopyImageSubDataNV( - this->mFinalTextureName, this->mGlTextureTarget, srcMipLevel, srcBox.x, srcBox.y, - srcBox.getZOrSlice() + this->getInternalSliceStart(), dstGl->mFinalTextureName, - dstGl->mGlTextureTarget, dstMipLevel, dstBox.x, dstBox.y, - dstBox.getZOrSlice() + dstGl->getInternalSliceStart(), srcBox.width, srcBox.height, - srcBox.getDepthOrSlices() ) ); + this->mFinalTextureName, this->mGlTextureTarget, srcMipLevel, + static_cast( srcBox.x ), static_cast( srcBox.y ), + static_cast( srcBox.getZOrSlice() + this->getInternalSliceStart() ), + dstGl->mFinalTextureName, dstGl->mGlTextureTarget, dstMipLevel, + static_cast( dstBox.x ), static_cast( dstBox.y ), + static_cast( dstBox.getZOrSlice() + dstGl->getInternalSliceStart() ), + static_cast( srcBox.width ), static_cast( srcBox.height ), + static_cast( srcBox.getDepthOrSlices() ) ) ); } /*TODO: These are for OpenGL ES 3.0+ else if( support.checkExtension( "GL_OES_copy_image" ) ) From 34ed33c0a183449701a4675ae4ea8d393c87a501 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 12 Jun 2023 20:42:41 -0300 Subject: [PATCH 24/58] [Vk] Validation errors and crashes when trying to download the Window's contents to CPU. Implements Window::setWantsToDownload and Window::canDownloadData for Vulkan. --- .../Vulkan/include/OgreVulkanWindow.h | 8 +++++- RenderSystems/Vulkan/src/OgreVulkanQueue.cpp | 2 ++ .../src/OgreVulkanRenderPassDescriptor.cpp | 25 +++++++++++++++++++ .../Vulkan/src/OgreVulkanTextureGpuWindow.cpp | 4 +++ RenderSystems/Vulkan/src/OgreVulkanWindow.cpp | 25 ++++++++++++++++++- 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/RenderSystems/Vulkan/include/OgreVulkanWindow.h b/RenderSystems/Vulkan/include/OgreVulkanWindow.h index caf5db73458..7d0e5c8577a 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanWindow.h +++ b/RenderSystems/Vulkan/include/OgreVulkanWindow.h @@ -99,6 +99,7 @@ namespace Ogre bool mLowestLatencyVSync; bool mEnablePreTransform; bool mClosed; + bool mCanDownloadData; VkSurfaceKHR mSurfaceKHR; VkSwapchainKHR mSwapchain; @@ -121,7 +122,8 @@ namespace Ogre void acquireNextSwapchain(); public: - VulkanWindowSwapChainBased( const String &title, uint32 width, uint32 height, bool fullscreenMode ); + VulkanWindowSwapChainBased( const String &title, uint32 width, uint32 height, + bool fullscreenMode ); ~VulkanWindowSwapChainBased() override; void destroy() override; @@ -136,6 +138,10 @@ namespace Ogre void setVSync( bool vSync, uint32 vSyncInterval ) override; + void setWantsToDownload( bool bWantsToDownload ) override; + + bool canDownloadData() const override; + /// Tells our VulkanDevice that the next commitAndNextCommandBuffer call should present us /// Calling swapBuffers during the command buffer that is rendering to us is key for /// good performance; otherwise Ogre may split the commands that render to this window diff --git a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp index 97b805e3f7f..354262556f6 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp @@ -457,6 +457,8 @@ namespace Ogre imageMemBarrier.oldLayout = newTransferLayout; imageMemBarrier.newLayout = vkTexture->mNextLayout; + OGRE_ASSERT_LOW( imageMemBarrier.newLayout != VK_IMAGE_LAYOUT_UNDEFINED && + imageMemBarrier.newLayout != VK_IMAGE_LAYOUT_PREINITIALIZED ); mImageMemBarriers.push_back( imageMemBarrier ); mImageMemBarrierPtrs.push_back( vkTexture ); } diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp index cabc60c0613..74e0f5c5a4f 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp @@ -978,6 +978,31 @@ namespace Ogre return; } + if( mReadyWindowForPresent ) + { + const size_t numColourEntries = mNumColourEntries; + for( size_t i = 0u; i < numColourEntries; ++i ) + { + VulkanTextureGpu *texture; + + if( mColour[i].resolveTexture && mColour[i].resolveTexture->isRenderWindowSpecific() ) + { + OGRE_ASSERT_HIGH( dynamic_cast( mColour[i].resolveTexture ) ); + texture = static_cast( mColour[i].resolveTexture ); + texture->mCurrLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + texture->mNextLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + } + + if( mColour[i].texture && mColour[i].texture->isRenderWindowSpecific() ) + { + OGRE_ASSERT_HIGH( dynamic_cast( mColour[i].texture ) ); + texture = static_cast( mColour[i].texture ); + texture->mCurrLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + texture->mNextLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + } + } + } + // End (if exists) the render command encoder tied to this RenderPassDesc. // Another encoder will have to be created, and don't let ours linger // since mCurrentRenderPassDescriptor probably doesn't even point to 'this' diff --git a/RenderSystems/Vulkan/src/OgreVulkanTextureGpuWindow.cpp b/RenderSystems/Vulkan/src/OgreVulkanTextureGpuWindow.cpp index f50e0f91e65..f3dcfb6ccb0 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanTextureGpuWindow.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanTextureGpuWindow.cpp @@ -80,6 +80,10 @@ namespace Ogre { if( mSampleDescription.isMultisample() ) createMsaaSurface(); + + OGRE_ASSERT_LOW( !PixelFormatGpuUtils::isDepth( mPixelFormat ) && + !PixelFormatGpuUtils::isStencil( mPixelFormat ) ); + mNextLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } //----------------------------------------------------------------------------------- void VulkanTextureGpuWindow::destroyInternalResourcesImpl() diff --git a/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp b/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp index a2058ca6a91..e3fe3e449d1 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp @@ -182,6 +182,7 @@ namespace Ogre mLowestLatencyVSync( false ), mEnablePreTransform( true ), mClosed( false ), + mCanDownloadData( false ), mSurfaceKHR( 0 ), mSwapchain( 0 ), mSwapchainSemaphore( 0 ), @@ -394,6 +395,8 @@ namespace Ogre swapchainCreateInfo.imageExtent.height = getHeight(); swapchainCreateInfo.imageArrayLayers = 1u; swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + if( mCanDownloadData ) + swapchainCreateInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapchainCreateInfo.queueFamilyIndexCount = 0u; swapchainCreateInfo.pQueueFamilyIndices = 0; @@ -414,7 +417,8 @@ namespace Ogre } } #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 - if( mEnablePreTransform && surfaceCaps.currentTransform <= VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR ) + if( mEnablePreTransform && + surfaceCaps.currentTransform <= VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR ) { // We will manually rotate by adapting our projection matrices (fastest) // See https://arm-software.github.io/vulkan_best_practice_for_mobile_developers/samples/ @@ -614,6 +618,25 @@ namespace Ogre createSwapchain(); } //------------------------------------------------------------------------- + void VulkanWindowSwapChainBased::setWantsToDownload( bool bWantsToDownload ) + { + if( mCanDownloadData == bWantsToDownload ) + return; + + mCanDownloadData = bWantsToDownload; + + destroySwapchain(); + + if( mDepthBuffer ) + mDepthBuffer->_transitionTo( GpuResidency::OnStorage, (uint8 *)0 ); + if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) + mStencilBuffer->_transitionTo( GpuResidency::OnStorage, (uint8 *)0 ); + + createSwapchain(); + } + //------------------------------------------------------------------------- + bool VulkanWindowSwapChainBased::canDownloadData() const { return mCanDownloadData; } + //------------------------------------------------------------------------- void VulkanWindowSwapChainBased::swapBuffers() { if( mSwapchainStatus == SwapchainAcquired || mSwapchainStatus == SwapchainPendingSwap ) From d353c9a58d6c81d90b6847569eef66aa27582a66 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 13 Jun 2023 22:41:04 -0300 Subject: [PATCH 25/58] [Vk] Remove PVRTC support Turns out anything involving this format requires asking for a deprecated extension: VK_IMG_format_pvrtc However: 1. This extension is deprecated. 2. We have no way of testing the extension/functionality works and won't crash if OgreNext ever runs on PVRTC-enabled drivers. The oldest / most popular PVRTC GPU we can get is the PowerVR GE8320 and it doesn't expose this extension. --- .../Vulkan/src/OgreVulkanMappings.cpp | 23 ++++++++++++++----- .../Vulkan/src/OgreVulkanRenderSystem.cpp | 5 ---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp b/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp index 91d0a042481..c59ccfb0ecd 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanMappings.cpp @@ -366,12 +366,6 @@ namespace Ogre case PFG_BC7_UNORM: return VK_FORMAT_BC7_UNORM_BLOCK; case PFG_BC7_UNORM_SRGB: return VK_FORMAT_BC7_SRGB_BLOCK; case PFG_B4G4R4A4_UNORM: return VK_FORMAT_B4G4R4A4_UNORM_PACK16; - case PFG_PVRTC_RGB2: return VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG; - case PFG_PVRTC_RGBA2: return VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG; - case PFG_PVRTC_RGB4: return VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG; - case PFG_PVRTC_RGBA4: return VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG; - case PFG_PVRTC2_2BPP: return VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG; - case PFG_PVRTC2_4BPP: return VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG; case PFG_ETC1_RGB8_UNORM: return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; case PFG_ETC2_RGB8_UNORM: return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; case PFG_ETC2_RGB8_UNORM_SRGB: return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK; @@ -414,6 +408,23 @@ namespace Ogre case PFG_ASTC_RGBA_UNORM_12X10_sRGB:return VK_FORMAT_ASTC_12x10_SRGB_BLOCK; case PFG_ASTC_RGBA_UNORM_12X12_sRGB:return VK_FORMAT_ASTC_12x12_SRGB_BLOCK; + // PVRTC requires asking for extension VK_IMG_format_pvrtc before using + // VK_FORMAT_PVRTC* family of enums. + // + // However: + // 1. This extension is deprecated. + // 2. We have no way of testing the extension/functionality works and won't crash if OgreNext + // ever runs on PVRTC-enabled drivers. The oldest / most popular PVRTC GPU we can get is + // the PowerVR GE8320 and it doesn't expose this extension. + // + // PVRTC on Vulkan is dead. + case PFG_PVRTC_RGB2: + case PFG_PVRTC_RGBA2: + case PFG_PVRTC_RGB4: + case PFG_PVRTC_RGBA4: + case PFG_PVRTC2_2BPP: + case PFG_PVRTC2_4BPP: + case PFG_ATC_RGB: case PFG_ATC_RGBA_EXPLICIT_ALPHA: case PFG_ATC_RGBA_INTERPOLATED_ALPHA: diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index 69d03482924..c7340298dac 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -600,11 +600,6 @@ namespace Ogre rsc->setCapability( RSC_TEXTURE_COMPRESSION_ETC2 ); } - vkGetPhysicalDeviceFormatProperties( mDevice->mPhysicalDevice, - VulkanMappings::get( PFG_PVRTC_RGB2 ), &props ); - if( props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) - rsc->setCapability( RSC_TEXTURE_COMPRESSION_PVRTC ); - vkGetPhysicalDeviceFormatProperties( mDevice->mPhysicalDevice, VulkanMappings::get( PFG_ASTC_RGBA_UNORM_4X4_LDR ), &props ); if( props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) From b714421378e8083b4919b17dc56483b25360e765 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 15 Jun 2023 16:03:14 -0300 Subject: [PATCH 26/58] The documentation of BT_DEFAULT_SHARED now has a stern warning Previously it was too friendly which made it sound like it's something users should use; when in fact they should very likely not. Updated with a disclaimer to scare users away. --- OgreMain/include/Vao/OgreBufferPacked.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OgreMain/include/Vao/OgreBufferPacked.h b/OgreMain/include/Vao/OgreBufferPacked.h index 8de2022c796..0a18c098aed 100644 --- a/OgreMain/include/Vao/OgreBufferPacked.h +++ b/OgreMain/include/Vao/OgreBufferPacked.h @@ -50,6 +50,16 @@ namespace Ogre /** Read and write access from GPU/CPU. @remarks + !!! + SERIOUSLY DO NOT USE THIS FLAG UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING + IT HAS VERY SPECIFIC USES AND USING IT CARELESSLY CAN CAUSE GLITCHES OR CRASHES. + + THIS FLAG ASSUMSE YOU ARE FAMILIAR WITH HOW OGRE-NEXT WORKS INTERNALLY + AND HOW GPUs AND APIs WORK. + + IF YOU DON'T KNOW WHAT THIS FLAG IS, USE BT_IMMUTABLE OR BT_DEFAULT. + !!! + This functionality was written for UMA (Unified Memory Architecture), like the iPhone and most Android phones; and a few desktop iGPUs. @@ -73,7 +83,7 @@ namespace Ogre Ogre won't use any staging buffers to upload and download contents. It's fast on UMA and slow on other archs. - Theretically better synchronization could be implemented on top of this + Theoretically better synchronization could be implemented on top of this buffer type to be multi-purpose, but it would complicate things. Basically it's the perfect replacement for BT_IMMUTABLE if you want From 07c2b0a7abf5ca001fe702a228cedc3c0b67c6f3 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 18 Jun 2023 16:05:07 -0300 Subject: [PATCH 27/58] Fix memory leak if a mesh is destroyed but never loaded --- OgreMain/src/OgreMesh.cpp | 14 +++++++++++--- OgreMain/src/OgreMesh2.cpp | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/OgreMain/src/OgreMesh.cpp b/OgreMain/src/OgreMesh.cpp index 378a9f8a140..608c67cfbad 100644 --- a/OgreMain/src/OgreMesh.cpp +++ b/OgreMain/src/OgreMesh.cpp @@ -98,9 +98,17 @@ namespace Ogre //----------------------------------------------------------------------- Mesh::~Mesh() { - // have to call this here rather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); + if( !isLoaded() ) + { + // Even while unloaded we still may have stuff to free + unloadImpl(); + } + else + { + // have to call this here rather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } } //----------------------------------------------------------------------- HardwareBufferManagerBase *Mesh::getHardwareBufferManager() diff --git a/OgreMain/src/OgreMesh2.cpp b/OgreMain/src/OgreMesh2.cpp index ec2fb0b0241..4923de57acc 100644 --- a/OgreMain/src/OgreMesh2.cpp +++ b/OgreMain/src/OgreMesh2.cpp @@ -73,9 +73,17 @@ namespace Ogre //----------------------------------------------------------------------- Mesh::~Mesh() { - // have to call this here rather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); + if( !isLoaded() ) + { + // Even while unloaded we still may have stuff to free + unloadImpl(); + } + else + { + // have to call this here rather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } } //----------------------------------------------------------------------- SubMesh *Mesh::createSubMesh( size_t index ) From c2bed156d13d5b0a21be32079e0c2e9c778522d9 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 4 Jul 2023 13:25:23 -0300 Subject: [PATCH 28/58] Fix Area lights being mirrored around Y axis (0 is width -1) --- Components/Hlms/Pbs/src/OgreHlmsPbs.cpp | 2 +- .../ApiUsage/AreaApproxLights/AreaApproxLightsGameState.cpp | 2 +- .../UpdatingDecalsAndAreaLightTexGameState.cpp | 2 +- .../Tutorial_TextureBakingGameState.cpp | 2 +- Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp b/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp index de4df4f3439..ce070a12bae 100644 --- a/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp +++ b/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp @@ -2617,7 +2617,7 @@ namespace Ogre // vec4 areaApproxLights[numLights].tangent; Quaternion qRot = light->getParentNode()->_getDerivedOrientation(); - Vector3 xAxis = viewMatrix3 * qRot.xAxis(); + Vector3 xAxis = viewMatrix3 * -qRot.xAxis(); *light1BufferPtr++ = xAxis.x; *light1BufferPtr++ = xAxis.y; *light1BufferPtr++ = xAxis.z; diff --git a/Samples/2.0/ApiUsage/AreaApproxLights/AreaApproxLightsGameState.cpp b/Samples/2.0/ApiUsage/AreaApproxLights/AreaApproxLightsGameState.cpp index a999c8e54a8..2a12af2bb93 100644 --- a/Samples/2.0/ApiUsage/AreaApproxLights/AreaApproxLightsGameState.cpp +++ b/Samples/2.0/ApiUsage/AreaApproxLights/AreaApproxLightsGameState.cpp @@ -147,7 +147,7 @@ namespace Demo { Ogre::v1::MeshPtr lightPlaneMeshV1 = Ogre::v1::MeshManager::getSingleton().createPlane( "LightPlane v1", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::Plane( Ogre::Vector3::UNIT_Z, 0.0f ), 1.0f, 1.0f, 1, 1, true, 1, 1.0f, 1.0f, + Ogre::Plane( Ogre::Vector3::NEGATIVE_UNIT_Z, 0.0f ), 1.0f, 1.0f, 1, 1, true, 1, 1.0f, 1.0f, Ogre::Vector3::UNIT_Y, Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC ); Ogre::MeshPtr lightPlaneMesh = Ogre::MeshManager::getSingleton().createByImportingV1( diff --git a/Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp b/Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp index a7ab79deeb4..9ed76b06a80 100644 --- a/Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp +++ b/Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp @@ -171,7 +171,7 @@ namespace Demo { Ogre::v1::MeshPtr lightPlaneMeshV1 = Ogre::v1::MeshManager::getSingleton().createPlane( "LightPlane v1", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::Plane( Ogre::Vector3::UNIT_Z, 0.0f ), 1.0f, 1.0f, 1, 1, true, 1, 1.0f, 1.0f, + Ogre::Plane( Ogre::Vector3::NEGATIVE_UNIT_Z, 0.0f ), 1.0f, 1.0f, 1, 1, true, 1, 1.0f, 1.0f, Ogre::Vector3::UNIT_Y, Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC ); Ogre::MeshPtr lightPlaneMesh = Ogre::MeshManager::getSingleton().createByImportingV1( diff --git a/Samples/2.0/Tutorials/Tutorial_TextureBaking/Tutorial_TextureBakingGameState.cpp b/Samples/2.0/Tutorials/Tutorial_TextureBaking/Tutorial_TextureBakingGameState.cpp index 369a72f0eef..6e1cc92fb1b 100644 --- a/Samples/2.0/Tutorials/Tutorial_TextureBaking/Tutorial_TextureBakingGameState.cpp +++ b/Samples/2.0/Tutorials/Tutorial_TextureBaking/Tutorial_TextureBakingGameState.cpp @@ -73,7 +73,7 @@ namespace Demo { Ogre::v1::MeshPtr lightPlaneMeshV1 = Ogre::v1::MeshManager::getSingleton().createPlane( "LightPlane v1", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::Plane( Ogre::Vector3::UNIT_Z, 0.0f ), 1.0f, 1.0f, 1, 1, true, 1, 1.0f, 1.0f, + Ogre::Plane( Ogre::Vector3::NEGATIVE_UNIT_Z, 0.0f ), 1.0f, 1.0f, 1, 1, true, 1, 1.0f, 1.0f, Ogre::Vector3::UNIT_Y, Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC ); Ogre::MeshPtr lightPlaneMesh = Ogre::MeshManager::getSingleton().createByImportingV1( diff --git a/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any index e6a57a3c8cd..791075e1ed5 100644 --- a/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any @@ -53,8 +53,8 @@ /*&& dot( -lightDir, light1Buf.areaApproxLights[i].direction.xyz ) > 0*/ @insertpiece( andObjAreaApproxLightMaskCmp ) ) { projectedPosInPlane.xyz -= light1Buf.areaApproxLights[i].position.xyz; - float3 areaLightBitangent = cross( light1Buf.areaApproxLights[i].direction.xyz, - light1Buf.areaApproxLights[i].tangent.xyz ); + float3 areaLightBitangent = cross( light1Buf.areaApproxLights[i].tangent.xyz, + light1Buf.areaApproxLights[i].direction.xyz ); float2 invHalfRectSize = float2( light1Buf.areaApproxLights[i].direction.w, light1Buf.areaApproxLights[i].tangent.w ); //lightUV is in light space, in range [-0.5; 0.5] From 863e7792272e0aa82261017edc4f2206fd2949a8 Mon Sep 17 00:00:00 2001 From: mosfet80 Date: Sun, 9 Jul 2023 16:53:28 +0200 Subject: [PATCH 29/58] Update linux.build.yml (#394) Update upload-artifact and checkout to version 3 --- .github/workflows/linux.build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.build.yml b/.github/workflows/linux.build.yml index e4ebbd0e780..045e2a87047 100644 --- a/.github/workflows/linux.build.yml +++ b/.github/workflows/linux.build.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Run Linux C++11 working-directory: ./ run: ./Scripts/BuildScripts/build_ci_linux.sh @@ -24,7 +24,7 @@ jobs: if: ${{ (github.ref != 'refs/heads/master' && github.event_name == 'push') || (github.event_name == 'pull_request' && github.event.pull_request.base.ref != 'master') }} run: ./Scripts/BuildScripts/abi_checker.sh 2 $GITHUB_BASE_REF - name: ABI Checker Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: ${{ (github.ref != 'refs/heads/master' && github.event_name == 'push') || (github.event_name == 'pull_request' && github.event.pull_request.base.ref != 'master') }} with: name: abi-checker-reports From 3bda9a7c5cefd5227dce176d8684946a34beaec2 Mon Sep 17 00:00:00 2001 From: mosfet80 Date: Sun, 9 Jul 2023 16:53:42 +0200 Subject: [PATCH 30/58] Update main.yml (#395) Update actions/checkout to version 3 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 750b1cfecb1..3dce0ae315a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Generate Doxyfile # Replace CMake's ${ENV_VAR} to Doxygen's $(ENV_VAR) syntax From d0615e872cd244b5ee54ea6d2769a71a8f13e430 Mon Sep 17 00:00:00 2001 From: James Walker Date: Fri, 21 Jul 2023 18:10:30 -0700 Subject: [PATCH 31/58] Improve doc formatting for CompostitorManager2 and CompositorWorkspace. (#403) --- .../Compositor/OgreCompositorManager2.h | 38 ++++++++++++------- .../Compositor/OgreCompositorWorkspace.h | 28 ++++++++------ 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/OgreMain/include/Compositor/OgreCompositorManager2.h b/OgreMain/include/Compositor/OgreCompositorManager2.h index bc5cf315778..446a9ecaa5f 100644 --- a/OgreMain/include/Compositor/OgreCompositorManager2.h +++ b/OgreMain/include/Compositor/OgreCompositorManager2.h @@ -77,7 +77,7 @@ namespace Ogre + PASS_STENCIL + PASS_RESOLVE + Shadow Node - + A Node definition must be created first. Inside the Node Def. different passes can be defined including which targets they should render to. Once the definitions are set, a workspace instance must be created using addWorkspace @@ -104,7 +104,7 @@ namespace Ogre postprocessing), which enables the possibility of easily creating RSM (Reflective Shadow Maps) for Global Illumination calculations. @par - For more information @see CompositorNode & @see CompositorShadowNode + For more information @see CompositorNode @see CompositorShadowNode */ class _OgreExport CompositorManager2 : public OgreAllocatedObj { @@ -231,7 +231,7 @@ namespace Ogre /// Returns how many times _update has been called. size_t getFrameCount() const { return mFrameCount; } - /** Get an appropriately defined 'null' texture, i.e. one which will always + /** Get an appropriately defined 'null' texture, i.e., one which will always result in no shadows. */ TextureGpu *getNullShadowTexture( PixelFormatGpu format ); @@ -253,21 +253,24 @@ namespace Ogre a portion of the screen while using two (or more) workspaces without having to duplicate the nodes just to alter their viewport parameters. + @par viewportModifier controls how to stretch the viewport in each pass, vpModifierMask controls which passes will ignore the stretching, and executionMask controls which passes get skipped. + @par All passes have a default executionMask = 0xFF vpModifierMask = 0xFF except for clear passes which default to executionMask = 0x01 vpModifierMask = 0x00 + @par The reasoning behind this is that often you want to clear the whole renderTarget the first time (it's GPU-friendly to discard the entire buffer; aka vpModifierMask = 0), but the second time you don't want the clear to be executed at all to prevent overwritting the contents from the first pass (executionMask = 1). @par - Example, stereo (split screen): + @code //Render Eye0 to the left side of the screen m_workspaceEye0 = mgr->addWorkspace( sceneManager, renderTarget, eyeCamera0, "MainWorkspace", true, @@ -278,9 +281,11 @@ namespace Ogre eyeCamera1, "MainWorkspace", true, -1, Vector4( 0.5f, 0, 0.5f, 1 ), 0x02, 0x02 ); - @par + @endcode - Example, split screen, multiplayer, 4 players (e.g. Mario Kart (R)-like games) + @par + Example, split screen, multiplayer, 4 players (e.g. Mario Kart (R)-like games) + @code for( int i=0; i<4; ++i ) { Vector4 vpModifier( (i % 2) * 0.5f, (i >> 1) * 0.5f, 0.25f, 0.25f ); @@ -289,6 +294,7 @@ namespace Ogre -1, vpModifier, (1 << i), (1 << i) ); } + @endcode @param sceneManager The SceneManager this workspace will be associated with. You can have multiple @@ -298,10 +304,10 @@ namespace Ogre The final RT where the workspace will be rendered to. Usually the RenderWindow. We need this pointer in order to correctly create RTTs that depend on the final target's width, height, gamma & fsaa settings. - This pointer will be used for "connectOutput" channels - (@see CompositorWorkspaceDef::connectOutput) + This pointer will be used for "connectExternal" channels + (see CompositorWorkspaceDef::connectExternal) In theory if none of your nodes use width & height relative to final RT & - you don't use connectOutput, this pointer could be null. Although it's not + you don't use connectExternal, this pointer could be null. Although it's not recommended nor explicitly supported. @param defaultCam Default camera to use when a camera name wasn't specified explicitly in a @@ -333,19 +339,23 @@ namespace Ogre height *= vpOffsetScale.w; This affects both the viewport dimensions as well as the scissor rect. @param vpModifierMask + @parblock An 8-bit mask that will be AND'ed with the viewport modifier mask of each pass from every node. When the result is zero, the previous parameter "viewportModifier" isn't applied to that pass. This is useful when you want to apply a pass (like Clear) to the whole render target and not just to the scaled region. + @endparblock @param executionMask + @parblock An 8-bit mask that will be AND'ed with the execution mask of each pass from every node. When the result is zero, the pass isn't executed. See remarks on how to use this for efficient Stereo or split screen. This is useful when you want to skip a pass (like Clear) when rendering the second eye (or the second split from the second player). + @endparblock */ CompositorWorkspace *addWorkspace( SceneManager *sceneManager, TextureGpu *finalRenderTarget, Camera *defaultCam, IdString definitionName, bool bEnabled, @@ -366,7 +376,7 @@ namespace Ogre /// Removes the given workspace. Pointer is no longer valid after this call void removeWorkspace( CompositorWorkspace *workspace ); - /// Removes all workspaces. Make sure you don't hold any reference to a CompositorWorkpace! + /// Removes all workspaces. Make sure you don't hold any reference to a CompositorWorkspace ! void removeAllWorkspaces(); void removeAllWorkspaceDefinitions(); @@ -374,22 +384,22 @@ namespace Ogre /** Removes all shadow nodes defs. Make sure there are no active nodes using the definition! @remarks - Call removeAllWorkspaceDefinitions first + Call removeAllWorkspaceDefinitions() first */ void removeAllShadowNodeDefinitions(); /** Removes all node defs. Make sure there are no active nodes using the definition! @remarks - Call removeAllWorkspaceDefinitions first + Call removeAllWorkspaceDefinitions() first */ void removeAllNodeDefinitions(); - /// Calls @see CompositorNode::_validateAndFinish on all objects who aren't yet validated + /// Calls CompositorShadowNodeDef::_validateAndFinish on all objects who aren't yet validated void validateAllNodes(); BarrierSolver &getBarrierSolver() { return mBarrierSolver; } - /// Will call the renderSystem which in turns calls _updateImplementation + /// Will call the renderSystem which in turns calls _updateImplementation() void _update(); /// This should be called by the render system to diff --git a/OgreMain/include/Compositor/OgreCompositorWorkspace.h b/OgreMain/include/Compositor/OgreCompositorWorkspace.h index 3c98e67fa80..cb990a0c434 100644 --- a/OgreMain/include/Compositor/OgreCompositorWorkspace.h +++ b/OgreMain/include/Compositor/OgreCompositorWorkspace.h @@ -61,7 +61,7 @@ namespace Ogre (i.e. multiple monitors, stereo 3D, etc), while they all will share the same definition. A workspace definition (see CompositorWorkspaceDef) contains all the information needed by this CompositorWorkspace to instantiate and know which nodes to create and how to connect - them. @see CompositorNodeDef + them. (See CompositorNodeDef) A workspace may define global textures that are visible to all of its Node instances. @par If you want to have (e.g.) two monitors rendering the same but with different compositor @@ -174,9 +174,9 @@ namespace Ogre void setAmalgamatedProfiling( bool bEnabled ) { mAmalgamatedProfiling = bEnabled; } bool getAmalgamatedProfiling() const { return mAmalgamatedProfiling; } - /// @deprecated use addListener and removeListener instead + /// @deprecated use addListener() and removeListener() instead void setListener( CompositorWorkspaceListener *listener ); - /// @deprecated use getListeners instead + /// @deprecated use getListeners() instead CompositorWorkspaceListener *getListener() const; void addListener( CompositorWorkspaceListener *listener ); @@ -199,7 +199,7 @@ namespace Ogre Name of the node instance (they're unique) @param includeShadowNodes When true, also looks for ShadowNodes with that name, if the instance doesn't exists, - it will not be created (default: false). @see findShadowNode + it will not be created (default: false). (See findShadowNode()) When a Node has the same name of a Shadow Node, the Node takes precedence. @return Regular version: Valid pointer. Throws exception if not found. @@ -222,22 +222,24 @@ namespace Ogre */ void reconnectAllNodes(); - /** Resets the number of passes left for every pass (@see CompositorPassDef::mNumInitialPasses) + /** Resets the number of passes left for every pass (see CompositorPassDef::mNumInitialPasses) Useful when you have a few starting 'initialization' passes and you want to reset them. */ void resetAllNumPassesLeft(); - /** Call before _update unless the final render target is not a render window + /** Call before _update() unless the final render target is not a render window @param forceBeginFrame Forces a beginFrame call to the D3D9 API, even if the final render target is not a RenderWindow (not recommended). To avoid forcing extra begin/end frame pairs, update your manual workspaces inside CompositorWorkspaceListener::workspacePreUpdate (performance optimization) @param bInsideAutoreleasePool + @parblock If manually updating the workspace, leave this to default. Relevant only in Metal: If we're not inside an autorelease pool, we automatically wrap the call into one. Otherwise we will leak + @endparblock */ void _beginUpdate( bool forceBeginFrame, const bool bInsideAutoreleasePool = false ); @@ -248,25 +250,29 @@ namespace Ogre You might also need to enclose the _update calls with _beginUpdate( true ) and _endUpdate( true ) if you're having issues. @param bInsideAutoreleasePool + @parblock If manually updating the workspace, leave this to default. Relevant only in Metal: If we're not inside an autorelease pool, we automatically wrap the call into one. Otherwise we will leak + @endparblock */ void _update( const bool bInsideAutoreleasePool = false ); - /** Call after _update unless the final render target is not a render window + /** Call after _update() unless the final render target is not a render window @param forceEndFrame - @see _beginUpdate + (See beginUpdate()) !!!WARNING!!! Forcing an end frame can cause API issues w/ D3D9 if Ogre had already issued a begin frame automatically (i.e. if you're calling from inside a RenderTarget or CompositorWorkspace listener). These API issues may not manifest on all HW/Driver combinations, making it hard to detect (if you're on D3D, use the Debug Runtimes) @param bInsideAutoreleasePool + @parblock If manually updating the workspace, leave this to default. Relevant only in Metal: If we're not inside an autorelease pool, we - automatically wrap the call into one. Otherwise we will leak + automatically wrap the call into one. Otherwise we will leak. + @endparblock */ void _endUpdate( bool forceEndFrame, const bool bInsideAutoreleasePool = false ); @@ -274,7 +280,7 @@ namespace Ogre In the case of RenderTextures, resolves FSAA (unless it's tagged as explicit resolve, or its contents haven't changed since the last resolve) @remarks - Call this after _endUpdate + Call this after _endUpdate() */ void _swapFinalTarget( vector::type &swappedTargets ); @@ -296,7 +302,7 @@ namespace Ogre */ CompositorShadowNode *findShadowNode( IdString nodeDefName ) const; - /** Finds a shadow node given it's definition name. If it doesn't exist, creates one. + /** Finds a shadow node given its definition name. If it doesn't exist, creates one. Note that unlike nodes, there can only be one ShadowNode instance per definition (in the same workspace) @remarks From 49f2756f5450f986b87ab5495ddb963d3b13ca59 Mon Sep 17 00:00:00 2001 From: mosfet80 Date: Sat, 22 Jul 2023 17:02:51 +0200 Subject: [PATCH 32/58] remove unused tools (#397) * Delete Tools/rcapsdump/src directory remove unused file with folders (already removed in ogre) * Delete Tools/BitmapFontBuilderTool directory tools in not necessary . it' s possible use other 2 methods https://www.ogre3d.org/docs/manual18/manual_44.html ( already removed in ogre) --- Tools/BitmapFontBuilderTool/main.cpp | 105 ------------------- Tools/rcapsdump/src/main.cpp | 146 --------------------------- 2 files changed, 251 deletions(-) delete mode 100644 Tools/BitmapFontBuilderTool/main.cpp delete mode 100644 Tools/rcapsdump/src/main.cpp diff --git a/Tools/BitmapFontBuilderTool/main.cpp b/Tools/BitmapFontBuilderTool/main.cpp deleted file mode 100644 index 577d1e9c7fa..00000000000 --- a/Tools/BitmapFontBuilderTool/main.cpp +++ /dev/null @@ -1,105 +0,0 @@ - -/** Tool designed to take the binary width files from BitmapFontBuilder - http://www.lmnopc.com/bitmapfontbuilder/ and convert them into - Ogre .fontdef 'glyph' statements. - Highly inelegant, but it works! -*/ - -#include -#include -#include -#include -using namespace std; - -int main(int argc, char** argv) -{ - int size; - std::string datName, newName, fontName, imageName, genGlyph; - int addLeftPixels, addRightPixels, addTopPixels, addBottomPixels; - - cout << "Enter unique font name: "; - cin >> fontName; - cout << "Enter font image name: "; - cin >> imageName; - cout << "Enter size of texture(Example: 256): "; - cin >> size; - cout << "Enter name of file containing binary widths: "; - cin >> datName; - - cout << endl; - cout << "If you've modified the output from BitmapFontBuilder, e.g. by adding a\n" - "dropshadow, you'll need to widen the glyphs a little. If you used\n" - "BitmapFontBuilder's output directly, just answer 0 in the following two\n" - "questions.\n"; - cout << "Enter number of pixels to add to the left of all glyphs: "; - cin >> addLeftPixels; - cout << "Enter number of pixels to add to the right of all glyphs: "; - cin >> addRightPixels; - cout << "Enter number of pixels to add to the top of all glyphs: "; - cin >> addTopPixels; - cout << "Enter number of pixels to add to the bottom of all glyphs: "; - cin >> addBottomPixels; - cout << endl; - - cout << "Generate all glyph statements (Select yes for extended ASCII characters)(Y/N): "; - cin >> genGlyph; - cout << "Enter name of new text file to create: "; - cin >> newName; - - int charSize = size / 16; - int halfWidth = charSize / 2; - FILE *fp = fopen(datName.c_str(), "rb"); - - ofstream o(newName.c_str()); - - o << fontName << endl; - o << "{" << "\n\n"; - o << "\ttype\timage" << endl; - o << "\tsource\t" << imageName << "\n\n\n"; - - int posx = 0; - int posy = 0; - int colcount = 0; - for (int c = 0; c < 256; c++, colcount++) - { - if (colcount == 16) - { - colcount = 0; - posx = 0; - posy += charSize; - } - - // Read width from binary file - int w1 = fgetc(fp) & 0xFF; // NOTE: These two fgetc() have to be in seperate statements to ensure ordering! - int w2 = fgetc(fp) & 0xFF; - int width = w1 + (w2 << 8); // Little endian only, but this tool isn't available for OSX anyway - - float thisx_start = float(posx + halfWidth - (width / 2) - addLeftPixels); - float thisx_end = float(posx + halfWidth + (width / 2) + addRightPixels); - - float u1, u2, v1, v2; - u1 = thisx_start / (float)(size) ; - u2 = thisx_end / (float)(size); - v1 = (float)(posy - addTopPixels) / (float)(size); - v2 = (float)(posy + charSize + addBottomPixels) / (float)(size); - - if((genGlyph.at(0) == 'N' || genGlyph.at(0) == 'n') && c >= '!' && c <= '~') - { - std::string s = " "; - s.at(0) = c; - o << "\tglyph " << s << " " << u1 << " " << v1 << " " << u2 << " " << v2 << std::endl; - } - - if((genGlyph.at(0) != 'N' && genGlyph.at(0) != 'n')) - { - o << "\tglyph u" << c << " " << u1 << " " << v1 << " " << u2 << " " << v2 << std::endl; - } - posx += charSize; - - } - o << endl; - o << "}" << endl; - fclose(fp); - - return 0; -} diff --git a/Tools/rcapsdump/src/main.cpp b/Tools/rcapsdump/src/main.cpp deleted file mode 100644 index c24337e80b8..00000000000 --- a/Tools/rcapsdump/src/main.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE-Next - (Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org/ - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ - - - -#include "Ogre.h" -#include "OgreRenderSystemCapabilitiesSerializer.h" -#include -#include - -using namespace std; -using namespace Ogre; - - -void help(void) -{ - // Print help message - cout << endl << "rcapsdump: Queries GPU capabilities and dumps them into .rendercaps files" << endl; - - cout << endl << "Usage: rcapsdump" << endl; -} - - - -void setUpGLRenderSystemOptions(Ogre::RenderSystem* rs) -{ - using namespace Ogre; - ConfigOptionMap options = rs->getConfigOptions(); - // set default options - // this should work on every semi-normal system - rs->setConfigOption(String("Colour Depth"), String("32")); - rs->setConfigOption(String("FSAA"), String("0")); - rs->setConfigOption(String("Full Screen"), String("No")); - rs->setConfigOption(String("VSync"), String("No")); - rs->setConfigOption(String("Video Mode"), String("800 x 600")); - - // use the best RTT - ConfigOption optionRTT = options["RTT Preferred Mode"]; - - if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "FBO") != optionRTT.possibleValues.end()) - { - rs->setConfigOption(String("RTT Preferred Mode"), String("FBO")); - } - else if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "PBuffer") != optionRTT.possibleValues.end()) - { - rs->setConfigOption(String("RTT Preferred Mode"), String("PBuffer")); - } - else - rs->setConfigOption(String("RTT Preferred Mode"), String("Copy")); -} - - -void setUpD3D9RenderSystemOptions(Ogre::RenderSystem* rs) -{ - using namespace Ogre; - ConfigOptionMap options = rs->getConfigOptions(); - // set default options - // this should work on every semi-normal system - rs->setConfigOption(String("Anti aliasing"), String("None")); - rs->setConfigOption(String("Full Screen"), String("No")); - rs->setConfigOption(String("VSync"), String("No")); - rs->setConfigOption(String("Video Mode"), String("800 x 600 @ 32-bit colour")); - - // pick first available device - ConfigOption optionDevice = options["Rendering Device"]; - - rs->setConfigOption(optionDevice.name, optionDevice.currentValue); -} - - -int main(int numargs, char** args) -{ - if (numargs != 1) - { - help(); - return -1; - } - - RenderSystemCapabilities* glCaps = 0; - RenderSystemCapabilities* d3d9Caps = 0; - - RenderSystemCapabilitiesSerializer serializer; - - // query openGL for caps if available - Root* root = new Root("plugins.cfg"); - RenderSystem* rsGL = root->getRenderSystemByName("OpenGL Rendering Subsystem"); - if(rsGL) - { - setUpGLRenderSystemOptions(rsGL); - root->setRenderSystem(rsGL); - root->initialise(true, "OGRE rcapsdump GL Window"); - glCaps = const_cast(rsGL->getCapabilities()); - } - if(glCaps) - { - serializer.writeScript(glCaps, glCaps->getDeviceName(), "rcapsdump_gl.rendercaps"); - } - - delete root; - - // query D3D9 for caps if available - root = new Root("plugins.cfg"); - RenderSystem* rsD3D9 = root->getRenderSystemByName("Direct3D9 Rendering Subsystem"); - if(rsD3D9) - { - setUpD3D9RenderSystemOptions(rsD3D9); - root->setRenderSystem(rsD3D9); - root->initialise(true, "OGRE rcapsdump D3D9 Window"); - d3d9Caps = const_cast(rsD3D9->getCapabilities()); - } - if(d3d9Caps) - { - serializer.writeScript(d3d9Caps, d3d9Caps->getDeviceName(), "rcapsdump_d3d9.rendercaps"); - } - - delete root; - - return 0; - -} - From 6362a42338b512caaab80f6c6536731e0a17ab2e Mon Sep 17 00:00:00 2001 From: prlw1 Date: Sat, 22 Jul 2023 16:28:19 +0100 Subject: [PATCH 33/58] Two portability / build fixes (#401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * OgreSilentMemory.h defines "silent" versions of memset and friends for use with the GCC compiler. It correctly tests for "__GNUC__" for use. However, "nonnull" in gcc is an attribute spellt something like __attribute__((nunnull(1,2))). The functions here instead use glibc macros from sys/cdefs.h like __nonnull, so also test for the availability of those macros. (MING32 was presumably listed because it doesn't define those glibc macros. The way forward is not to list all operating systems which don't use glibc.) * OgreMain/include/OgreBitwise.h defines bswapNN functions. Some operating systems already define macros with those names. Rather than list all operating systems for which this true, undefine those macros for the duration of OgreBitwise.h and redefine them at the end. * OgreSceneFormatExporter.cpp: Build fix Recent compilers fail with .../ogre-next/Components/SceneFormat/src/OgreSceneFormatExporter.cpp: In member function ‘const char* Ogre::SceneFormatExporter::encodeDouble(double)’: .../ogre-next/Components/SceneFormat/src/OgreSceneFormatExporter.cpp:171:17: error: ‘isfinite’ was not declared in this scope; did you mean ‘std::isfinite’? Simplest fix is to drop support for MSVC < version 1800. (see pull request 372) --- .../src/OgreSceneFormatExporter.cpp | 22 ++++----------- OgreMain/include/OgreBitwise.h | 28 ++++++++++++++----- OgreMain/include/OgreSilentMemory.h | 2 +- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/Components/SceneFormat/src/OgreSceneFormatExporter.cpp b/Components/SceneFormat/src/OgreSceneFormatExporter.cpp index 67e736db1eb..6f29d95a2f0 100644 --- a/Components/SceneFormat/src/OgreSceneFormatExporter.cpp +++ b/Components/SceneFormat/src/OgreSceneFormatExporter.cpp @@ -50,22 +50,10 @@ THE SOFTWARE. #include "OgreSceneManager.h" #include "OgreTextureGpuManager.h" -#include "math.h" - +#include #include #include -#if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_COMP_VER < 1800 -inline float isfinite( float x ) -{ - return _finite( x ) == 0; -} -inline float isinf( float x ) -{ - return x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity(); -} -#endif - #define SceneFormatExporterNumFloatBins \ ( sizeof( mFloatBinTmpString ) / sizeof( mFloatBinTmpString[0] ) ) #define SceneFormatExporterFloatBinStrLength sizeof( mFloatBinTmpString[0] ) @@ -144,11 +132,11 @@ namespace Ogre strValue.a( encodeFloatBin( value ) ); else { - if( isfinite( value ) ) + if( std::isfinite( value ) ) strValue.a( LwString::Float( value, 9 ) ); else { - if( isinf( value ) ) + if( std::isinf( value ) ) strValue.a( value > 0 ? "\"inf\"" : "\"-inf\"" ); else strValue.a( "\"nan\"" ); @@ -168,11 +156,11 @@ namespace Ogre strValue.a( encodeDoubleBin( value ) ); else { - if( isfinite( value ) ) + if( std::isfinite( value ) ) strValue.a( LwString::Float( (float)value, 18 ) ); else { - if( isinf( value ) ) + if( std::isinf( value ) ) strValue.a( value > 0 ? "\"inf\"" : "\"-inf\"" ); else strValue.a( "\"nan\"" ); diff --git a/OgreMain/include/OgreBitwise.h b/OgreMain/include/OgreBitwise.h index 4bcec241f18..46fa624dc56 100644 --- a/OgreMain/include/OgreBitwise.h +++ b/OgreMain/include/OgreBitwise.h @@ -37,10 +37,17 @@ THE SOFTWARE. # define __has_builtin( x ) 0 #endif -#if OGRE_PLATFORM == OGRE_PLATFORM_FREEBSD -/// Undefine in defined bswap macros for FreeBSD +/// bswapNN may be defined as macros in or +#ifdef bswap16 +# define bswap16_sav bswap16 # undef bswap16 +#endif +#ifdef bswap32 +# define bswap32_sav bswap32 # undef bswap32 +#endif +#ifdef bswap64 +# define bswap64_sav bswap64 # undef bswap64 #endif @@ -554,12 +561,19 @@ namespace Ogre } // namespace Ogre -/** Redefine in defined bswap macros for FreeBSD +/** Redefine bswap macros temporarily undefined above */ -#if OGRE_PLATFORM == OGRE_PLATFORM_FREEBSD -# define bswap16( x ) __bswap16( x ) -# define bswap32( x ) __bswap32( x ) -# define bswap64( x ) __bswap64( x ) +#ifdef bswap16_sav +# define bswap16 bswap16_sav +# undef bswap16_sav +#endif +#ifdef bswap32_sav +# define bswap32 bswap32_sav +# undef bswap32_sav +#endif +#ifdef bswap64_sav +# define bswap64 bswap64_sav +# undef bswap64_sav #endif #endif diff --git a/OgreMain/include/OgreSilentMemory.h b/OgreMain/include/OgreSilentMemory.h index dad503db863..80d1a29ff00 100644 --- a/OgreMain/include/OgreSilentMemory.h +++ b/OgreMain/include/OgreSilentMemory.h @@ -34,7 +34,7 @@ THE SOFTWARE. #include -#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __MINGW32__ ) +#if defined( __GNUC__ ) && !defined( __clang__ ) && defined( __nonnull ) && defined( __fortify_function ) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wclass-memaccess" From b3dd69a4920348551d48ea923aeafb70608b875c Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 4 Aug 2023 20:17:21 -0300 Subject: [PATCH 34/58] Remove forward declaration of non-existent class --- OgreMain/include/Math/Array/C/OgreArrayVector3.h | 2 -- OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/OgreMain/include/Math/Array/C/OgreArrayVector3.h b/OgreMain/include/Math/Array/C/OgreArrayVector3.h index 714c5bd3387..eca08267fc2 100644 --- a/OgreMain/include/Math/Array/C/OgreArrayVector3.h +++ b/OgreMain/include/Math/Array/C/OgreArrayVector3.h @@ -38,8 +38,6 @@ THE SOFTWARE. namespace Ogre { - class ArrayInterQuaternion; - /** \addtogroup Core * @{ */ diff --git a/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.h b/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.h index 592ecc21db1..385f327734a 100644 --- a/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.h +++ b/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.h @@ -38,8 +38,6 @@ THE SOFTWARE. namespace Ogre { - class ArrayInterQuaternion; - /** \addtogroup Core * @{ */ From 9004c38fba17a85515c87accf8e79bc0ca67afb3 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 4 Aug 2023 19:19:39 -0300 Subject: [PATCH 35/58] Update Android sample to newer Gradle --- .../Template/app/build.gradle | 7 +- .../Template/app/src/main/AndroidManifest.xml | 4 +- .../AndroidAppTemplate/Template/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - .../2.0/AndroidAppTemplate/Template/gradlew | 164 ------------------ .../AndroidAppTemplate/Template/gradlew.bat | 90 ---------- 7 files changed, 9 insertions(+), 264 deletions(-) delete mode 100644 Samples/2.0/AndroidAppTemplate/Template/gradle/wrapper/gradle-wrapper.jar delete mode 100644 Samples/2.0/AndroidAppTemplate/Template/gradle/wrapper/gradle-wrapper.properties delete mode 100755 Samples/2.0/AndroidAppTemplate/Template/gradlew delete mode 100644 Samples/2.0/AndroidAppTemplate/Template/gradlew.bat diff --git a/Samples/2.0/AndroidAppTemplate/Template/app/build.gradle b/Samples/2.0/AndroidAppTemplate/Template/app/build.gradle index f9cf8741a98..f1eb3365b7f 100644 --- a/Samples/2.0/AndroidAppTemplate/Template/app/build.gradle +++ b/Samples/2.0/AndroidAppTemplate/Template/app/build.gradle @@ -1,12 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 24 + compileSdkVersion 33 + ndkVersion "25.2.9519653" defaultConfig { applicationId "com.ogre3d.%%sampleName%%" minSdkVersion 24 - targetSdkVersion 24 + targetSdkVersion 33 versionCode 1 versionName "0.0.1" externalNativeBuild { @@ -41,6 +42,8 @@ android { } } } + + namespace "$android.defaultConfig.applicationId" } dependencies { diff --git a/Samples/2.0/AndroidAppTemplate/Template/app/src/main/AndroidManifest.xml b/Samples/2.0/AndroidAppTemplate/Template/app/src/main/AndroidManifest.xml index 6db0c0959f3..e7efda1bca5 100644 --- a/Samples/2.0/AndroidAppTemplate/Template/app/src/main/AndroidManifest.xml +++ b/Samples/2.0/AndroidAppTemplate/Template/app/src/main/AndroidManifest.xml @@ -6,7 +6,9 @@ - + diff --git a/Samples/2.0/AndroidAppTemplate/Template/build.gradle b/Samples/2.0/AndroidAppTemplate/Template/build.gradle index 97047034f3d..7aa6aec7c8e 100644 --- a/Samples/2.0/AndroidAppTemplate/Template/build.gradle +++ b/Samples/2.0/AndroidAppTemplate/Template/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.0.1' + classpath 'com.android.tools.build:gradle:8.0.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/Samples/2.0/AndroidAppTemplate/Template/gradle/wrapper/gradle-wrapper.jar b/Samples/2.0/AndroidAppTemplate/Template/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49896 zcmagFb986H(k`5d^NVfUwr$(C?M#x1ZQHiZiEVpg+jrjgoQrerx!>1o_ul)D>ebz~ zs=Mmxr&>W81QY-S1PKWQ%N-;H^tS;2*XwVA`dej1RRn1z<;3VgfE4~kaG`A%QSPsR z#ovnZe+tS9%1MfeDyz`RirvdjPRK~p(#^q2(^5@O&NM19EHdvN-A&StN>0g6QA^VN z0Gx%Gq#PD$QMRFzmK+utjS^Y1F0e8&u&^=w5K<;4Rz|i3A=o|IKLY+g`iK6vfr9?+ z-`>gmU&i?FGSL5&F?TXFu`&Js6h;15QFkXp2M1H9|Eq~bpov-GU(uz%mH0n55wUl- zv#~ccAz`F5wlQ>e_KlJS3@{)B?^v*EQM=IxLa&76^y51a((wq|2-`qON>+4dLc{Oo z51}}o^Zen(oAjxDK7b++9_Yg`67p$bPo3~BCpGM7uAWmvIhWc5Gi+gQZ|Pwa-Gll@<1xmcPy z|NZmu6m)g5Ftu~BG&Xdxclw7Cij{xbBMBn-LMII#Slp`AElb&2^Hw+w>(3crLH!;I zN+Vk$D+wP1#^!MDCiad@vM>H#6+`Ct#~6VHL4lzmy;lSdk>`z6)=>Wh15Q2)dQtGqvn0vJU@+(B5{MUc*qs4!T+V=q=wy)<6$~ z!G>e_4dN@lGeF_$q9`Ju6Ncb*x?O7=l{anm7Eahuj_6lA{*#Gv*TaJclevPVbbVYu z(NY?5q+xxbO6%g1xF0r@Ix8fJ~u)VRUp`S%&rN$&e!Od`~s+64J z5*)*WSi*i{k%JjMSIN#X;jC{HG$-^iX+5f5BGOIHWAl*%15Z#!xntpk($-EGKCzKa zT7{siZ9;4TICsWQ$pu&wKZQTCvpI$Xvzwxoi+XkkpeE&&kFb!B?h2hi%^YlXt|-@5 zHJ~%AN!g_^tmn1?HSm^|gCE#!GRtK2(L{9pL#hp0xh zME}|DB>(5)`iE7CM)&_+S}-Bslc#@B5W4_+k4Cp$l>iVyg$KP>CN?SVGZ(&02>iZK zB<^HP$g$Lq*L$BWd?2(F?-MUbNWTJVQdW7$#8a|k_30#vHAD1Z{c#p;bETk0VnU5A zBgLe2HFJ3032$G<`m*OB!KM$*sdM20jm)It5OSru@tXpK5LT>#8)N!*skNu1$TpIw zufjjdp#lyH5bZ%|Iuo|iu9vG1HrIVWLH>278xo>aVBkPN3V$~!=KnlXQ4eDqS7%E% zQ!z^$Q$b^6Q)g#cLpwur(|<0gWHo6A6jc;n`t(V9T;LzTAU{IAu*uEQ%Ort1k+Kn+f_N`9|bxYC+~Z1 zCC1UCWv*Orx$_@ydv9mIe(liLfOr7mhbV@tKw{6)q^1DH1nmvZ0cj215R<~&I<4S| zgnr;9Cdjqpz#o8i0CQjtl`}{c*P)aSdH|abxGdrR)-3z+02-eX(k*B)Uqv6~^nh** z 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/Samples/2.0/AndroidAppTemplate/Template/gradlew.bat b/Samples/2.0/AndroidAppTemplate/Template/gradlew.bat deleted file mode 100644 index 8a0b282aa68..00000000000 --- a/Samples/2.0/AndroidAppTemplate/Template/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega From 8b9a82ca7cf79d9a2f9266f1e75583556d3a0b69 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 3 Aug 2023 22:31:26 -0300 Subject: [PATCH 36/58] Fix NEON versions of ArrayVector3::collapseMin & collapseMax not working as advertised. --- .../Array/NEON/Single/OgreArrayVector3.inl | 75 ++----------------- 1 file changed, 8 insertions(+), 67 deletions(-) diff --git a/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl b/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl index b2a8132b193..e5f117cc5a0 100644 --- a/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl +++ b/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl @@ -524,77 +524,18 @@ namespace Ogre //----------------------------------------------------------------------------------- inline Vector3 ArrayVector3::collapseMin() const { - OGRE_ALIGNED_DECL( Real, vals[4], OGRE_SIMD_ALIGNMENT ); -// ArrayReal aosVec0, aosVec1, aosVec2, aosVec3; - Real min0 = MathlibNEON::CollapseMin(mChunkBase[0]); - Real min1 = MathlibNEON::CollapseMin(mChunkBase[1]); - Real min2 = MathlibNEON::CollapseMin(mChunkBase[2]); - - float32x4_ct minArray = { min0, min1, min2, std::numeric_limits::infinity() }; - Real min = MathlibNEON::CollapseMin(minArray); -// min = vminq_f32(mChunkBase[0], mChunkBase[1]); -// min = vminq_f32(min, mChunkBase[2]); - -// ArrayReal a_lo, a_hi, min; -// a_lo = vget_low_f32(a); -// a_hi = vget_high_f32(a); -// min = vpmin_f32(a_lo, a_hi); -// min = vpmin_f32(min, min); -// -// return vget_lane_f32(min, 0); - - //Transpose XXXX YYYY ZZZZ to XYZZ XYZZ XYZZ XYZZ -// ArrayReal tmp2, tmp0; -// tmp0 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0x44 ); -// tmp2 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0xEE ); -// -// aosVec0 = vshuf_f32( tmp0, mChunkBase[2], 0x08 ); -// aosVec1 = vshuf_f32( tmp0, mChunkBase[2], 0x5D ); -// aosVec2 = vshuf_f32( tmp2, mChunkBase[2], 0xA8 ); -// aosVec3 = vshuf_f32( tmp2, mChunkBase[2], 0xFD ); -// -// //Do the actual operation -// aosVec0 = vminq_f32( aosVec0, aosVec1 ); -// aosVec2 = vminq_f32( aosVec2, aosVec3 ); -// aosVec0 = vminq_f32( aosVec0, aosVec2 ); - - vst1q_f32( vals, vdupq_n_f32(min) ); - - return Vector3( vals[0], vals[1], vals[2] ); + Real min0 = MathlibNEON::CollapseMin( mChunkBase[0] ); + Real min1 = MathlibNEON::CollapseMin( mChunkBase[1] ); + Real min2 = MathlibNEON::CollapseMin( mChunkBase[2] ); + return Vector3( min0, min1, min2 ); } //----------------------------------------------------------------------------------- inline Vector3 ArrayVector3::collapseMax() const { - OGRE_ALIGNED_DECL( Real, vals[4], OGRE_SIMD_ALIGNMENT ); -// ArrayReal aosVec0, aosVec1, aosVec2, aosVec3; - Real max0 = MathlibNEON::CollapseMax(mChunkBase[0]); - Real max1 = MathlibNEON::CollapseMax(mChunkBase[1]); - Real max2 = MathlibNEON::CollapseMax(mChunkBase[2]); - - float32x4_ct maxArray = { max0, max1, max2, -std::numeric_limits::infinity() }; - Real max = MathlibNEON::CollapseMax(maxArray); -// ArrayReal max; -// max = vmaxq_f32(mChunkBase[0], mChunkBase[1]); -// max = vmaxq_f32(max, mChunkBase[2]); - - //Transpose XXXX YYYY ZZZZ to XYZZ XYZZ XYZZ XYZZ -// ArrayReal tmp2, tmp0; -// tmp0 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0x44 ); -// tmp2 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0xEE ); -// -// aosVec0 = vshuf_f32( tmp0, mChunkBase[2], 0x08 ); -// aosVec1 = vshuf_f32( tmp0, mChunkBase[2], 0x5D ); -// aosVec2 = vshuf_f32( tmp2, mChunkBase[2], 0xA8 ); -// aosVec3 = vshuf_f32( tmp2, mChunkBase[2], 0xFD ); -// -// //Do the actual operation -// aosVec0 = vmaxq_f32( aosVec0, aosVec1 ); -// aosVec2 = vmaxq_f32( aosVec2, aosVec3 ); -// aosVec0 = vmaxq_f32( aosVec0, aosVec2 ); - - vst1q_f32( vals, vdupq_n_f32(max) ); - - return Vector3( vals[0], vals[1], vals[2] ); + Real max0 = MathlibNEON::CollapseMax( mChunkBase[0] ); + Real max1 = MathlibNEON::CollapseMax( mChunkBase[1] ); + Real max2 = MathlibNEON::CollapseMax( mChunkBase[2] ); + return Vector3( max0, max1, max2 ); } //----------------------------------------------------------------------------------- inline void ArrayVector3::Cmov4( ArrayMaskR mask, const ArrayVector3 &replacement ) From 0d996cb14c96af6f5cfab5b4fc8dd86460601691 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 4 Aug 2023 20:57:39 -0300 Subject: [PATCH 37/58] Add new Unit Test "Internal Core" --- CMakeLists.txt | 1 - Samples/2.0/AndroidAppTemplate/GenTemplate.py | 3 +- Samples/2.0/CMakeLists.txt | 1 + .../2.0/Tests/InternalCore/InternalCore.cpp | 55 ++++++++++++++++++ Samples/2.0/Tests/InternalCore/InternalCore.h | 0 .../InternalCore/InternalCoreGameState.cpp | 57 +++++++++++++++++++ .../InternalCore/InternalCoreGameState.h | 22 +++++++ 7 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 Samples/2.0/Tests/InternalCore/InternalCore.cpp create mode 100644 Samples/2.0/Tests/InternalCore/InternalCore.h create mode 100644 Samples/2.0/Tests/InternalCore/InternalCoreGameState.cpp create mode 100644 Samples/2.0/Tests/InternalCore/InternalCoreGameState.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6aa790f9c22..b5bb57d8970 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -357,7 +357,6 @@ elseif (ANDROID) set(OGRE_BUILD_COMPONENT_PAGING FALSE CACHE BOOL "Disable paging component on Android ES1" FORCE) endif() - set(OGRE_BUILD_TESTS FALSE CACHE BOOL "Disable tests on Android" FORCE) set(OGRE_BUILD_TOOLS FALSE CACHE BOOL "Disable tools on Android" FORCE) set(OGRE_STATIC TRUE CACHE BOOL "Forcing static build for Android" FORCE) set(OGRE_SIMD FALSE CACHE BOOL "Disable SIMD on Android" FORCE) diff --git a/Samples/2.0/AndroidAppTemplate/GenTemplate.py b/Samples/2.0/AndroidAppTemplate/GenTemplate.py index 59012b3f2cd..40d421b1211 100644 --- a/Samples/2.0/AndroidAppTemplate/GenTemplate.py +++ b/Samples/2.0/AndroidAppTemplate/GenTemplate.py @@ -55,7 +55,8 @@ "V1Interfaces", "V2ManualObject", "V2Mesh", - ["Readback", True] + ["InternalCore", True], + ["Readback", True], ] templateFiles = list() diff --git a/Samples/2.0/CMakeLists.txt b/Samples/2.0/CMakeLists.txt index ec9a6b25601..c5e604bd5b3 100644 --- a/Samples/2.0/CMakeLists.txt +++ b/Samples/2.0/CMakeLists.txt @@ -220,6 +220,7 @@ endif() if( OGRE_BUILD_TESTS ) add_subdirectory(Tests/ArrayTextures) add_subdirectory(Tests/BillboardTest) + add_subdirectory(Tests/InternalCore) add_subdirectory(Tests/MemoryCleanup) add_subdirectory(Tests/NearFarProjection) add_subdirectory(Tests/Readback) diff --git a/Samples/2.0/Tests/InternalCore/InternalCore.cpp b/Samples/2.0/Tests/InternalCore/InternalCore.cpp new file mode 100644 index 00000000000..059c3f1d35d --- /dev/null +++ b/Samples/2.0/Tests/InternalCore/InternalCore.cpp @@ -0,0 +1,55 @@ + +#include "GraphicsSystem.h" +#include "InternalCoreGameState.h" + +// Declares WinMain / main +#include "MainEntryPointHelper.h" +#include "System/MainEntryPoints.h" + +#if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID +# if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 +INT WINAPI WinMainApp( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow ) +# else +int mainApp( int argc, const char *argv[] ) +# endif +{ + return Demo::MainEntryPoints::mainAppSingleThreaded( DEMO_MAIN_ENTRY_PARAMS ); +} +#endif + +namespace Demo +{ + class InternalCore final : public GraphicsSystem + { + public: + InternalCore( GameState *gameState ) : GraphicsSystem( gameState ) + { + mAlwaysAskForConfig = false; + } + }; + + void MainEntryPoints::createSystems( GameState **outGraphicsGameState, + GraphicsSystem **outGraphicsSystem, + GameState **outLogicGameState, LogicSystem **outLogicSystem ) + { + InternalCoreGameState *gfxGameState = new InternalCoreGameState( + "This tests covers basic class functionality works as desired.\n" + "It's not for graphics." ); + + GraphicsSystem *graphicsSystem = new InternalCore( gfxGameState ); + + gfxGameState->_notifyGraphicsSystem( graphicsSystem ); + + *outGraphicsGameState = gfxGameState; + *outGraphicsSystem = graphicsSystem; + } + + void MainEntryPoints::destroySystems( GameState *graphicsGameState, GraphicsSystem *graphicsSystem, + GameState *logicGameState, LogicSystem *logicSystem ) + { + delete graphicsSystem; + delete graphicsGameState; + } + + const char *MainEntryPoints::getWindowTitle() { return "Internal Core"; } +} // namespace Demo diff --git a/Samples/2.0/Tests/InternalCore/InternalCore.h b/Samples/2.0/Tests/InternalCore/InternalCore.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Samples/2.0/Tests/InternalCore/InternalCoreGameState.cpp b/Samples/2.0/Tests/InternalCore/InternalCoreGameState.cpp new file mode 100644 index 00000000000..0574c7b311c --- /dev/null +++ b/Samples/2.0/Tests/InternalCore/InternalCoreGameState.cpp @@ -0,0 +1,57 @@ + +#include "InternalCoreGameState.h" + +#include "GraphicsSystem.h" + +#include "Math/Array/OgreArrayVector3.h" + +using namespace Demo; + +InternalCoreGameState::InternalCoreGameState( const Ogre::String &helpDescription ) : + TutorialGameState( helpDescription ) +{ +} +//----------------------------------------------------------------------------------- +void InternalCoreGameState::createScene01() +{ + TutorialGameState::createScene01(); + + using namespace Ogre; + + Vector3 scalarA[ARRAY_PACKED_REALS]; + Vector3 minCollapsed( std::numeric_limits::max() ); + Vector3 maxCollapsed( -std::numeric_limits::max() ); + ArrayVector3 packedVec; + for( int i = 0; i < ARRAY_PACKED_REALS; ++i ) + { + scalarA[i].x = Real( i * 3 - ARRAY_PACKED_REALS ) * 17.67f; + scalarA[i].y = Real( i * 3 + 1 - ARRAY_PACKED_REALS ) * 31.11f; + scalarA[i].z = Real( i * 3 + 2 - ARRAY_PACKED_REALS ) * 5.84f; + + minCollapsed.makeFloor( scalarA[i] ); + maxCollapsed.makeCeil( scalarA[i] ); + + packedVec.setFromVector3( scalarA[i], (size_t)i ); + } + + for( int i = 0; i < ARRAY_PACKED_REALS; ++i ) + { + Vector3 output; + packedVec.getAsVector3( output, (size_t)i ); + OGRE_ASSERT( output == scalarA[i] ); + if( (size_t)i != ARRAY_PACKED_REALS - (size_t)i - 1u ) + { + packedVec.getAsVector3( output, ARRAY_PACKED_REALS - (size_t)i - 1u ); + OGRE_ASSERT( output != scalarA[i] ); + } + } + + { + const Vector3 collapsedMinToTest = packedVec.collapseMin(); + const Vector3 collapsedMaxToTest = packedVec.collapseMax(); + OGRE_ASSERT( collapsedMinToTest == minCollapsed ); + OGRE_ASSERT( collapsedMaxToTest == maxCollapsed ); + } + + mGraphicsSystem->setQuit(); +} diff --git a/Samples/2.0/Tests/InternalCore/InternalCoreGameState.h b/Samples/2.0/Tests/InternalCore/InternalCoreGameState.h new file mode 100644 index 00000000000..79fbc507952 --- /dev/null +++ b/Samples/2.0/Tests/InternalCore/InternalCoreGameState.h @@ -0,0 +1,22 @@ + +#ifndef Demo_InternalCoreGameState_H +#define Demo_InternalCoreGameState_H + +#include "OgrePrerequisites.h" + +#include "TutorialGameState.h" + +namespace Demo +{ + class InternalCoreGameState : public TutorialGameState + { + Ogre::SceneNode *mSceneNode; + + public: + InternalCoreGameState( const Ogre::String &helpDescription ); + + void createScene01() override; + }; +} // namespace Demo + +#endif From 3c6edf4eb48de34afb5bc9fa76b5f8362696a9d1 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 4 Aug 2023 21:03:21 -0300 Subject: [PATCH 38/58] Forgot to push this file. --- Samples/2.0/Tests/InternalCore/CMakeLists.txt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Samples/2.0/Tests/InternalCore/CMakeLists.txt diff --git a/Samples/2.0/Tests/InternalCore/CMakeLists.txt b/Samples/2.0/Tests/InternalCore/CMakeLists.txt new file mode 100644 index 00000000000..a816a5e261c --- /dev/null +++ b/Samples/2.0/Tests/InternalCore/CMakeLists.txt @@ -0,0 +1,22 @@ +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE-Next +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- + +macro( add_recursive dir retVal ) + file( GLOB_RECURSE ${retVal} ${dir}/*.h ${dir}/*.cpp ${dir}/*.c ) +endmacro() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + +add_recursive( ./ SOURCE_FILES ) + +ogre_add_executable(Test_InternalCore WIN32 MACOSX_BUNDLE ${SOURCE_FILES} ${SAMPLE_COMMON_RESOURCES}) + +target_link_libraries(Test_InternalCore ${OGRE_LIBRARIES} ${OGRE_SAMPLES_LIBRARIES}) +ogre_config_sample_lib(Test_InternalCore) +ogre_config_sample_pkg(Test_InternalCore) From 26d43e4f9e4c365934f72cf72536a0df962379d2 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 3 Aug 2023 22:31:26 -0300 Subject: [PATCH 39/58] Fix NEON versions of ArrayVector3::collapseMin & collapseMax not working as advertised. --- .../Array/NEON/Single/OgreArrayVector3.inl | 75 ++----------------- 1 file changed, 8 insertions(+), 67 deletions(-) diff --git a/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl b/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl index 62a3fa08384..e2f42c742e9 100644 --- a/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl +++ b/OgreMain/include/Math/Array/NEON/Single/OgreArrayVector3.inl @@ -524,77 +524,18 @@ namespace Ogre //----------------------------------------------------------------------------------- inline Vector3 ArrayVector3::collapseMin( void ) const { - OGRE_ALIGNED_DECL( Real, vals[4], OGRE_SIMD_ALIGNMENT ); -// ArrayReal aosVec0, aosVec1, aosVec2, aosVec3; - Real min0 = MathlibNEON::CollapseMin(mChunkBase[0]); - Real min1 = MathlibNEON::CollapseMin(mChunkBase[1]); - Real min2 = MathlibNEON::CollapseMin(mChunkBase[2]); - - float32x4_ct minArray = { min0, min1, min2, std::numeric_limits::infinity() }; - Real min = MathlibNEON::CollapseMin(minArray); -// min = vminq_f32(mChunkBase[0], mChunkBase[1]); -// min = vminq_f32(min, mChunkBase[2]); - -// ArrayReal a_lo, a_hi, min; -// a_lo = vget_low_f32(a); -// a_hi = vget_high_f32(a); -// min = vpmin_f32(a_lo, a_hi); -// min = vpmin_f32(min, min); -// -// return vget_lane_f32(min, 0); - - //Transpose XXXX YYYY ZZZZ to XYZZ XYZZ XYZZ XYZZ -// ArrayReal tmp2, tmp0; -// tmp0 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0x44 ); -// tmp2 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0xEE ); -// -// aosVec0 = vshuf_f32( tmp0, mChunkBase[2], 0x08 ); -// aosVec1 = vshuf_f32( tmp0, mChunkBase[2], 0x5D ); -// aosVec2 = vshuf_f32( tmp2, mChunkBase[2], 0xA8 ); -// aosVec3 = vshuf_f32( tmp2, mChunkBase[2], 0xFD ); -// -// //Do the actual operation -// aosVec0 = vminq_f32( aosVec0, aosVec1 ); -// aosVec2 = vminq_f32( aosVec2, aosVec3 ); -// aosVec0 = vminq_f32( aosVec0, aosVec2 ); - - vst1q_f32( vals, vdupq_n_f32(min) ); - - return Vector3( vals[0], vals[1], vals[2] ); + Real min0 = MathlibNEON::CollapseMin( mChunkBase[0] ); + Real min1 = MathlibNEON::CollapseMin( mChunkBase[1] ); + Real min2 = MathlibNEON::CollapseMin( mChunkBase[2] ); + return Vector3( min0, min1, min2 ); } //----------------------------------------------------------------------------------- inline Vector3 ArrayVector3::collapseMax( void ) const { - OGRE_ALIGNED_DECL( Real, vals[4], OGRE_SIMD_ALIGNMENT ); -// ArrayReal aosVec0, aosVec1, aosVec2, aosVec3; - Real max0 = MathlibNEON::CollapseMax(mChunkBase[0]); - Real max1 = MathlibNEON::CollapseMax(mChunkBase[1]); - Real max2 = MathlibNEON::CollapseMax(mChunkBase[2]); - - float32x4_ct maxArray = { max0, max1, max2, -std::numeric_limits::infinity() }; - Real max = MathlibNEON::CollapseMax(maxArray); -// ArrayReal max; -// max = vmaxq_f32(mChunkBase[0], mChunkBase[1]); -// max = vmaxq_f32(max, mChunkBase[2]); - - //Transpose XXXX YYYY ZZZZ to XYZZ XYZZ XYZZ XYZZ -// ArrayReal tmp2, tmp0; -// tmp0 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0x44 ); -// tmp2 = vshuf_f32( mChunkBase[0], mChunkBase[1], 0xEE ); -// -// aosVec0 = vshuf_f32( tmp0, mChunkBase[2], 0x08 ); -// aosVec1 = vshuf_f32( tmp0, mChunkBase[2], 0x5D ); -// aosVec2 = vshuf_f32( tmp2, mChunkBase[2], 0xA8 ); -// aosVec3 = vshuf_f32( tmp2, mChunkBase[2], 0xFD ); -// -// //Do the actual operation -// aosVec0 = vmaxq_f32( aosVec0, aosVec1 ); -// aosVec2 = vmaxq_f32( aosVec2, aosVec3 ); -// aosVec0 = vmaxq_f32( aosVec0, aosVec2 ); - - vst1q_f32( vals, vdupq_n_f32(max) ); - - return Vector3( vals[0], vals[1], vals[2] ); + Real max0 = MathlibNEON::CollapseMax( mChunkBase[0] ); + Real max1 = MathlibNEON::CollapseMax( mChunkBase[1] ); + Real max2 = MathlibNEON::CollapseMax( mChunkBase[2] ); + return Vector3( max0, max1, max2 ); } //----------------------------------------------------------------------------------- inline void ArrayVector3::Cmov4( ArrayMaskR mask, const ArrayVector3 &replacement ) From edf427112c1c599752455ead35f5203197d13868 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 10 Aug 2023 21:06:17 -0300 Subject: [PATCH 40/58] Tell MSVC to report a newer cplusplus See https://forums.ogre3d.org/viewtopic.php?t=97086 See https://developercommunity.visualstudio.com/t/msvc-incorrectly-defines-cplusplus/139261 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5bb57d8970..efb7d9930b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,7 +180,7 @@ if (MSVC) # set variable to state that we are using jom makefiles set(JOM TRUE) endif () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast /Zc:cplusplus") if (NOT OGRE_PLATFORM_X64) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2") endif() From 205710277c274c71f256d81d6b16fc65268721d9 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 14 Aug 2023 17:49:48 -0300 Subject: [PATCH 41/58] [Android] Fix Timer::getMilliseconds randomly returning large numbers Also make iOS match Android & Linux just in case. --- OgreMain/src/Android/OgreTimer.cpp | 6 +++--- OgreMain/src/iOS/OgreTimer.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OgreMain/src/Android/OgreTimer.cpp b/OgreMain/src/Android/OgreTimer.cpp index 0fd92ee1535..add813c9e85 100644 --- a/OgreMain/src/Android/OgreTimer.cpp +++ b/OgreMain/src/Android/OgreTimer.cpp @@ -53,8 +53,8 @@ uint64 Timer::getMilliseconds() { struct timeval now; gettimeofday( &now, NULL ); - return static_cast( now.tv_sec - start.tv_sec ) * 1000 + - static_cast( now.tv_usec - start.tv_usec ) / 1000; + return static_cast( now.tv_sec - start.tv_sec ) * 1000ul + + static_cast( ( now.tv_usec - start.tv_usec ) / 1000l ); } //--------------------------------------------------------------------------------// @@ -62,7 +62,7 @@ uint64 Timer::getMicroseconds() { struct timeval now; gettimeofday( &now, NULL ); - return static_cast( now.tv_sec - start.tv_sec ) * 1000000 + + return static_cast( now.tv_sec - start.tv_sec ) * 1000000ul + static_cast( now.tv_usec - start.tv_usec ); } diff --git a/OgreMain/src/iOS/OgreTimer.cpp b/OgreMain/src/iOS/OgreTimer.cpp index 6de2641abc1..add813c9e85 100644 --- a/OgreMain/src/iOS/OgreTimer.cpp +++ b/OgreMain/src/iOS/OgreTimer.cpp @@ -53,8 +53,8 @@ uint64 Timer::getMilliseconds() { struct timeval now; gettimeofday( &now, NULL ); - return static_cast( now.tv_sec - start.tv_sec ) * 1000 + - static_cast( ( now.tv_usec - start.tv_usec ) / 1000 ); + return static_cast( now.tv_sec - start.tv_sec ) * 1000ul + + static_cast( ( now.tv_usec - start.tv_usec ) / 1000l ); } //--------------------------------------------------------------------------------// @@ -62,7 +62,7 @@ uint64 Timer::getMicroseconds() { struct timeval now; gettimeofday( &now, NULL ); - return static_cast( now.tv_sec - start.tv_sec ) * 1000000 + + return static_cast( now.tv_sec - start.tv_sec ) * 1000000ul + static_cast( now.tv_usec - start.tv_usec ); } From 55191f659be0fd240539b1d71ae4bb042d930db2 Mon Sep 17 00:00:00 2001 From: cryham Date: Thu, 13 Jul 2023 14:28:05 +0200 Subject: [PATCH 42/58] Tutorial Terrain faster camera speed etc --- Samples/2.0/Common/include/CameraController.h | 2 -- .../Tutorial_Terrain/src/Tutorial_TerrainGameState.cpp | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Samples/2.0/Common/include/CameraController.h b/Samples/2.0/Common/include/CameraController.h index c08fc9a3d0d..a2feb9eda98 100644 --- a/Samples/2.0/Common/include/CameraController.h +++ b/Samples/2.0/Common/include/CameraController.h @@ -19,8 +19,6 @@ namespace Demo public: float mCameraBaseSpeed; - - public: float mCameraSpeedBoost; private: diff --git a/Samples/2.0/Tutorials/Tutorial_Terrain/src/Tutorial_TerrainGameState.cpp b/Samples/2.0/Tutorials/Tutorial_Terrain/src/Tutorial_TerrainGameState.cpp index c392e4be9e8..8191be9f31e 100644 --- a/Samples/2.0/Tutorials/Tutorial_Terrain/src/Tutorial_TerrainGameState.cpp +++ b/Samples/2.0/Tutorials/Tutorial_Terrain/src/Tutorial_TerrainGameState.cpp @@ -137,12 +137,14 @@ namespace Demo Ogre::AtmosphereNpr *atmosphere = static_cast( sceneManager->getAtmosphere() ); Ogre::AtmosphereNpr::Preset p = atmosphere->getPreset(); - p.fogDensity = 0.0005f; + p.fogDensity = 0.00004f; p.fogBreakMinBrightness = 0.05f; atmosphere->setPreset( p ); #endif mCameraController = new CameraController( mGraphicsSystem, false ); + mCameraController->mCameraBaseSpeed = 200.f; + mCameraController->mCameraSpeedBoost = 3.0f; mGraphicsSystem->getCamera()->setFarClipDistance( 100000.0f ); mGraphicsSystem->getCamera()->setPosition( -10.0f, 80.0f, 10.0f ); @@ -329,6 +331,7 @@ namespace Demo hlmsManager->getDatablock( "TerraExampleMaterial" ) ); datablock->setDetailTriplanarDiffuseEnabled( mTriplanarMappingEnabled ); + datablock->setDetailTriplanarNormalEnabled( mTriplanarMappingEnabled ); datablock->setDetailTriplanarRoughnessEnabled( mTriplanarMappingEnabled ); datablock->setDetailTriplanarMetalnessEnabled( mTriplanarMappingEnabled ); From 8c89911c7a3e9364ee1bd998920b03680fa068f9 Mon Sep 17 00:00:00 2001 From: cryham Date: Thu, 31 Aug 2023 18:33:39 +0200 Subject: [PATCH 43/58] Fix Terra shaders w/o metalness or roughness map(s) --- Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any index cf72f44131f..9d937f5a06d 100644 --- a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any @@ -142,7 +142,7 @@ material.detailOffsetScale[@n].xy, texIndex_detailMetalnessIdx@n ).x; @else - midf metalness@n = _h( 0 ); + midf metalness@n = _h( 1.0 ); @end @end @@ -167,7 +167,7 @@ material.detailOffsetScale[@n].xy, texIndex_detailRoughnessIdx@n ).x; @else - midf roughness@n = _h( 0 ); + midf roughness@n = _h( 1.0 ); @end @end From 888e3e05be728f0a6b9d2968dbe6aa6460a5c2cc Mon Sep 17 00:00:00 2001 From: cryham Date: Sun, 3 Sep 2023 20:28:17 +0200 Subject: [PATCH 44/58] fix spelling --- Samples/2.0/Common/include/CameraController.h | 2 +- Samples/2.0/Common/src/CameraController.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Samples/2.0/Common/include/CameraController.h b/Samples/2.0/Common/include/CameraController.h index a2feb9eda98..4b7ec22ac7c 100644 --- a/Samples/2.0/Common/include/CameraController.h +++ b/Samples/2.0/Common/include/CameraController.h @@ -11,7 +11,7 @@ namespace Demo { bool mUseSceneNode; - bool mSpeedMofifier; + bool mSpeedModifier; bool mWASD[4]; bool mSlideUpDown[2]; float mCameraYaw; diff --git a/Samples/2.0/Common/src/CameraController.cpp b/Samples/2.0/Common/src/CameraController.cpp index 439f69e0867..072f61e5248 100644 --- a/Samples/2.0/Common/src/CameraController.cpp +++ b/Samples/2.0/Common/src/CameraController.cpp @@ -12,7 +12,7 @@ namespace Demo { CameraController::CameraController( GraphicsSystem *graphicsSystem, bool useSceneNode ) : mUseSceneNode( useSceneNode ), - mSpeedMofifier( false ), + mSpeedModifier( false ), mCameraYaw( 0 ), mCameraPitch( 0 ), mCameraBaseSpeed( 10 ), @@ -58,7 +58,7 @@ namespace Demo (Ogre::Real)camMovementZ ); camMovementDir.normalise(); camMovementDir *= - timeSinceLast * mCameraBaseSpeed * ( 1 + mSpeedMofifier * mCameraSpeedBoost ); + timeSinceLast * mCameraBaseSpeed * ( 1 + mSpeedModifier * mCameraSpeedBoost ); if( mUseSceneNode ) { @@ -75,7 +75,7 @@ namespace Demo bool CameraController::keyPressed( const SDL_KeyboardEvent &arg ) { if( arg.keysym.scancode == SDL_SCANCODE_LSHIFT ) - mSpeedMofifier = true; + mSpeedModifier = true; if( arg.keysym.scancode == SDL_SCANCODE_W ) mWASD[0] = true; @@ -98,7 +98,7 @@ namespace Demo bool CameraController::keyReleased( const SDL_KeyboardEvent &arg ) { if( arg.keysym.scancode == SDL_SCANCODE_LSHIFT ) - mSpeedMofifier = false; + mSpeedModifier = false; if( arg.keysym.scancode == SDL_SCANCODE_W ) mWASD[0] = false; From 4efe05799543f96740f5a3559c1ba1eeec944839 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 12 Sep 2023 19:52:32 -0300 Subject: [PATCH 45/58] [Vk] Fix dangling pointer after destroying TextureGpu (#416) Fixes #416 --- RenderSystems/Vulkan/src/OgreVulkanQueue.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp index 5f640d7db30..592460c41b9 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp @@ -1051,10 +1051,14 @@ namespace Ogre if( mEncoderState == EncoderCopyOpen ) { bool needsToFlush = false; + bool mustRemoveFromBarrier = false; TextureGpuDownloadMap::const_iterator itor = mCopyDownloadTextures.find( texture ); if( itor != mCopyDownloadTextures.end() ) + { needsToFlush = true; + mustRemoveFromBarrier = true; + } else { FastArray::const_iterator it2 = @@ -1072,6 +1076,14 @@ namespace Ogre OGRE_ASSERT_LOW( texture->mCurrLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL || texture->mCurrLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ); endCopyEncoder(); + + if( mustRemoveFromBarrier ) + { + // endCopyEncoder() just called solver.assumeTransition() on this texture + // but we're destroying the texture. Remove the dangling pointer. + BarrierSolver &solver = mRenderSystem->getBarrierSolver(); + solver.textureDeleted( texture ); + } } } } From afee2d2266d9dca9b92025fa4afb0290fb35c4a1 Mon Sep 17 00:00:00 2001 From: "Dmytro Yunchyk(aka DimA)" Date: Thu, 14 Sep 2023 12:21:44 +0200 Subject: [PATCH 46/58] Ogre: fixed Metal rendering on Simulator running on Arm Mac --- RenderSystems/Metal/src/OgreMetalRenderSystem.mm | 8 ++++---- RenderSystems/Metal/src/Vao/OgreMetalVaoManager.mm | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/RenderSystems/Metal/src/OgreMetalRenderSystem.mm b/RenderSystems/Metal/src/OgreMetalRenderSystem.mm index 30a957cb1aa..4d37423f0db 100644 --- a/RenderSystems/Metal/src/OgreMetalRenderSystem.mm +++ b/RenderSystems/Metal/src/OgreMetalRenderSystem.mm @@ -2277,7 +2277,7 @@ of this software and associated documentation files (the "Software"), to deal } // Setup baseInstance. -# if TARGET_OS_SIMULATOR == 0 +# if TARGET_OS_SIMULATOR == 0 || OGRE_CPU == OGRE_CPU_ARM [mActiveRenderEncoder setVertexBufferOffset:drawCmd->baseInstance * 4u atIndex:15]; # else [mActiveRenderEncoder setVertexBufferOffset:drawCmd->baseInstance * 256u atIndex:15]; @@ -2324,7 +2324,7 @@ of this software and associated documentation files (the "Software"), to deal { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // Setup baseInstance. -# if TARGET_OS_SIMULATOR == 0 +# if TARGET_OS_SIMULATOR == 0 || OGRE_CPU == OGRE_CPU_ARM [mActiveRenderEncoder setVertexBufferOffset:drawCmd->baseInstance * 4u atIndex:15]; # else [mActiveRenderEncoder setVertexBufferOffset:drawCmd->baseInstance * 256u atIndex:15]; @@ -2407,7 +2407,7 @@ of this software and associated documentation files (the "Software"), to deal # endif // Setup baseInstance. -# if TARGET_OS_SIMULATOR == 0 +# if TARGET_OS_SIMULATOR == 0 || OGRE_CPU == OGRE_CPU_ARM [mActiveRenderEncoder setVertexBufferOffset:cmd->baseInstance * 4u atIndex:15]; # else [mActiveRenderEncoder setVertexBufferOffset:cmd->baseInstance * 256u atIndex:15]; @@ -2437,7 +2437,7 @@ of this software and associated documentation files (the "Software"), to deal { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // Setup baseInstance. -# if TARGET_OS_SIMULATOR == 0 +# if TARGET_OS_SIMULATOR == 0 || OGRE_CPU == OGRE_CPU_ARM [mActiveRenderEncoder setVertexBufferOffset:cmd->baseInstance * 4u atIndex:15]; # else [mActiveRenderEncoder setVertexBufferOffset:cmd->baseInstance * 256u atIndex:15]; diff --git a/RenderSystems/Metal/src/Vao/OgreMetalVaoManager.mm b/RenderSystems/Metal/src/Vao/OgreMetalVaoManager.mm index 72980aa6d6a..e51baca21f0 100644 --- a/RenderSystems/Metal/src/Vao/OgreMetalVaoManager.mm +++ b/RenderSystems/Metal/src/Vao/OgreMetalVaoManager.mm @@ -138,7 +138,7 @@ of this software and associated documentation files (the "Software"), to deal // On iOS alignment must match "the maximum accessed object" type. e.g. // if it's all float, then alignment = 4. if it's a float2, then alignment = 8. // The max. object is float4, so alignment = 16 -# if TARGET_OS_SIMULATOR == 0 +# if TARGET_OS_SIMULATOR == 0 || OGRE_CPU == OGRE_CPU_ARM mConstBufferAlignment = 16; mTexBufferAlignment = 16; # else @@ -200,7 +200,7 @@ of this software and associated documentation files (the "Software"), to deal mSupportsPersistentMapping = true; const uint32 maxNumInstances = 4096u * 2u; -#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS && TARGET_OS_SIMULATOR == 0 +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS && (TARGET_OS_SIMULATOR == 0 || OGRE_CPU == OGRE_CPU_ARM) uint32 *drawIdPtr = static_cast( OGRE_MALLOC_SIMD( maxNumInstances * sizeof( uint32 ), MEMCATEGORY_GEOMETRY ) ); for( uint32 i = 0; i < maxNumInstances; ++i ) From 5c85ef50c43e64b68ddfa00e914baef27ce099fe Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 14 Sep 2023 13:41:44 +0200 Subject: [PATCH 47/58] Hlms property to emulate user clip planes on devices without HW support, like Google Pixel 7 Pro --- Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp | 3 +++ OgreMain/include/OgreHlms.h | 1 + OgreMain/src/OgreHlms.cpp | 4 ++++ .../Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl | 4 ++++ .../Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any | 5 +++++ .../Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any | 7 +++++++ Samples/Media/Hlms/Pbs/GLSL/VertexShader_vs.glsl | 2 +- Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any | 7 +++++++ Samples/Media/Hlms/Terra/GLSL/VertexShader_vs.glsl | 2 +- .../Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any | 5 +++++ Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any | 7 +++++++ Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl | 2 +- 12 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp b/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp index 493377ae224..cf228909e97 100644 --- a/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp +++ b/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp @@ -630,6 +630,9 @@ namespace Ogre int32 numClipDist = std::max( getProperty( HlmsBaseProp::PsoClipDistances ), 1 ); setProperty( HlmsBaseProp::PsoClipDistances, numClipDist ); setProperty( HlmsBaseProp::GlobalClipPlanes, 1 ); + // some Android devices(e.g. Mali-G77, Google Pixel 7 Pro) do not support Vulkan shaderClipDistance feature + if(!mRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + setProperty(HlmsBaseProp::EmulateClipDistances, 1); //turn on emulation of clipDistances } mListener->preparePassHash( shadowNode, casterPass, dualParaboloid, sceneManager, this ); diff --git a/OgreMain/include/OgreHlms.h b/OgreMain/include/OgreHlms.h index 54624c949db..2713986cb9c 100644 --- a/OgreMain/include/OgreHlms.h +++ b/OgreMain/include/OgreHlms.h @@ -952,6 +952,7 @@ namespace Ogre // Change per scene pass static const IdString PsoClipDistances; static const IdString GlobalClipPlanes; + static const IdString EmulateClipDistances; static const IdString DualParaboloidMapping; static const IdString InstancedStereo; static const IdString StaticBranchLights; diff --git a/OgreMain/src/OgreHlms.cpp b/OgreMain/src/OgreHlms.cpp index 0bfc30a7249..f1e87135d92 100644 --- a/OgreMain/src/OgreHlms.cpp +++ b/OgreMain/src/OgreHlms.cpp @@ -127,6 +127,7 @@ namespace Ogre // Change per scene pass const IdString HlmsBaseProp::PsoClipDistances = IdString( "hlms_pso_clip_distances" ); const IdString HlmsBaseProp::GlobalClipPlanes = IdString( "hlms_global_clip_planes" ); + const IdString HlmsBaseProp::EmulateClipDistances = IdString( "hlms_emulate_clip_distances" ); const IdString HlmsBaseProp::DualParaboloidMapping = IdString( "hlms_dual_paraboloid_mapping" ); const IdString HlmsBaseProp::InstancedStereo = IdString( "hlms_instanced_stereo" ); const IdString HlmsBaseProp::StaticBranchLights = IdString( "hlms_static_branch_lights" ); @@ -3252,6 +3253,9 @@ namespace Ogre { setProperty( HlmsBaseProp::PsoClipDistances, 1 ); setProperty( HlmsBaseProp::GlobalClipPlanes, 1 ); + // some Android devices(e.g. Mali-G77, Google Pixel 7 Pro) do not support Vulkan shaderClipDistance feature + if(!mRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + setProperty(HlmsBaseProp::EmulateClipDistances, 1); //turn on emulation of clipDistances } const RenderPassDescriptor *renderPassDesc = mRenderSystem->getCurrentPassDescriptor(); diff --git a/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl b/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl index 07c645077c3..f3930a6a98f 100644 --- a/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl +++ b/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl @@ -237,7 +237,11 @@ #define outVs_Position gl_Position #define outVs_viewportIndex gl_ViewportIndex +@property( hlms_emulate_clip_distances ) +#define outVs_clipDistance0 outVs.clipDistance0 +@else #define outVs_clipDistance0 gl_ClipDistance[0] +@end #define gl_SampleMaskIn0 gl_SampleMaskIn[0] #define reversebits bitfieldReverse diff --git a/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any index b8a4ab70d6e..f9443f3082b 100644 --- a/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any @@ -457,5 +457,10 @@ struct Material @end @end @end + @property( hlms_emulate_clip_distances && hlms_pso_clip_distances ) + @foreach( hlms_pso_clip_distances, n ) + INTERPOLANT( float clipDistance@n, @counter(texcoord) ); + @end + @end @insertpiece( custom_VStoPS ) @end diff --git a/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any index 3549dfc7472..911571bbd10 100644 --- a/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any @@ -748,6 +748,13 @@ @property( !hlms_shadowcaster ) @piece( DefaultBodyPS ) + @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk ) + @foreach( hlms_pso_clip_distances, n ) + if( inPs.clipDistance@n < 0.0 ) + discard; + @end + @end + @property( hlms_screen_pos_uv ) float2 screenPosUv = gl_FragCoord.xy * passBuf.invWindowRes.xy; @end diff --git a/Samples/Media/Hlms/Pbs/GLSL/VertexShader_vs.glsl b/Samples/Media/Hlms/Pbs/GLSL/VertexShader_vs.glsl index 8bbe2bc8154..3082b996c7d 100644 --- a/Samples/Media/Hlms/Pbs/GLSL/VertexShader_vs.glsl +++ b/Samples/Media/Hlms/Pbs/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; diff --git a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any index 9d937f5a06d..8e8aa3b5656 100644 --- a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any @@ -211,6 +211,13 @@ @piece( DefaultTerraBodyPS ) PixelData pixelData; + @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk) + @foreach( hlms_pso_clip_distances, n ) + if( inPs.clipDistance@n < 0.0 ) + discard; + @end + @end + @insertpiece( LoadMaterial ) @insertpiece( UnpackTextureIndices0 ) @insertpiece( UnpackTextureIndices1 ) diff --git a/Samples/Media/Hlms/Terra/GLSL/VertexShader_vs.glsl b/Samples/Media/Hlms/Terra/GLSL/VertexShader_vs.glsl index 6c8a1cee01f..35d9bf77f99 100644 --- a/Samples/Media/Hlms/Terra/GLSL/VertexShader_vs.glsl +++ b/Samples/Media/Hlms/Terra/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; diff --git a/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any b/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any index 2a0f9bdba26..db07171fa1b 100644 --- a/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any +++ b/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any @@ -114,6 +114,11 @@ @end @end @end + @property( hlms_emulate_clip_distances && hlms_pso_clip_distances ) + @foreach( hlms_pso_clip_distances, n ) + INTERPOLANT( float clipDistance@n, @counter(texcoord) ); + @end + @end @insertpiece( custom_VStoPS ) @end diff --git a/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any index 3609c2aab2b..61aa1f5e45b 100644 --- a/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any @@ -54,6 +54,13 @@ @end @piece( DefaultBodyPS ) + @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk) + @foreach( hlms_pso_clip_distances, n ) + if( inPs.clipDistance@n < 0.0 ) + discard; + @end + @end + midf4 diffuseCol = midf4_c( 1.0f, 1.0f, 1.0f, 1.0f ); @property( diffuse_map || alpha_test || diffuse ) diff --git a/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl b/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl index 9a6f4d57fb5..4411e686b7f 100644 --- a/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl +++ b/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; From e444329657f00308a395ad9ce3dd3c64e7a5abd7 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 14 Sep 2023 13:51:51 +0200 Subject: [PATCH 48/58] fixed clang format --- Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp | 6 +++--- OgreMain/src/OgreHlms.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp b/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp index cf228909e97..3fb627afa7b 100644 --- a/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp +++ b/Components/Hlms/Unlit/src/OgreHlmsUnlit.cpp @@ -630,9 +630,9 @@ namespace Ogre int32 numClipDist = std::max( getProperty( HlmsBaseProp::PsoClipDistances ), 1 ); setProperty( HlmsBaseProp::PsoClipDistances, numClipDist ); setProperty( HlmsBaseProp::GlobalClipPlanes, 1 ); - // some Android devices(e.g. Mali-G77, Google Pixel 7 Pro) do not support Vulkan shaderClipDistance feature - if(!mRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - setProperty(HlmsBaseProp::EmulateClipDistances, 1); //turn on emulation of clipDistances + // some Android devices(e.g. Mali-G77, Google Pixel 7 Pro) do not support user clip planes + if( !mRenderSystem->getCapabilities()->hasCapability( RSC_USER_CLIP_PLANES ) ) + setProperty( HlmsBaseProp::EmulateClipDistances, 1 ); } mListener->preparePassHash( shadowNode, casterPass, dualParaboloid, sceneManager, this ); diff --git a/OgreMain/src/OgreHlms.cpp b/OgreMain/src/OgreHlms.cpp index f1e87135d92..0fec61cf890 100644 --- a/OgreMain/src/OgreHlms.cpp +++ b/OgreMain/src/OgreHlms.cpp @@ -3253,9 +3253,9 @@ namespace Ogre { setProperty( HlmsBaseProp::PsoClipDistances, 1 ); setProperty( HlmsBaseProp::GlobalClipPlanes, 1 ); - // some Android devices(e.g. Mali-G77, Google Pixel 7 Pro) do not support Vulkan shaderClipDistance feature - if(!mRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - setProperty(HlmsBaseProp::EmulateClipDistances, 1); //turn on emulation of clipDistances + // some Android devices(e.g. Mali-G77, Google Pixel 7 Pro) do not support user clip planes + if( !mRenderSystem->getCapabilities()->hasCapability( RSC_USER_CLIP_PLANES ) ) + setProperty( HlmsBaseProp::EmulateClipDistances, 1 ); } const RenderPassDescriptor *renderPassDesc = mRenderSystem->getCurrentPassDescriptor(); From 2eb8af69722be7b37b07ef2f8a66e7f89cccc4a7 Mon Sep 17 00:00:00 2001 From: "Dmytro Yunchyk(aka DimA)" Date: Thu, 14 Sep 2023 14:02:44 +0200 Subject: [PATCH 49/58] Relax assert to allow changing orientaionMode for resident square RTT - usefull for reflections rendering on rotated Android devices --- RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp | 3 ++- RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp index 1824125f6c9..f1712e5c843 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp @@ -859,7 +859,8 @@ namespace Ogre //----------------------------------------------------------------------------------- void GL3PlusTextureGpuRenderTarget::setOrientationMode( OrientationMode orientationMode ) { - OGRE_ASSERT_LOW( mResidencyStatus == GpuResidency::OnStorage || isRenderWindowSpecific() ); + OGRE_ASSERT_LOW( mResidencyStatus == GpuResidency::OnStorage || isRenderWindowSpecific() || + isRenderToTexture() && mWidth == mHeight ); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 mOrientationMode = orientationMode; #endif diff --git a/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp b/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp index 8d3bb1d2699..6a30fba7284 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp @@ -1014,7 +1014,8 @@ namespace Ogre //----------------------------------------------------------------------------------- void VulkanTextureGpuRenderTarget::setOrientationMode( OrientationMode orientationMode ) { - OGRE_ASSERT_LOW( mResidencyStatus == GpuResidency::OnStorage || isRenderWindowSpecific() ); + OGRE_ASSERT_LOW( mResidencyStatus == GpuResidency::OnStorage || isRenderWindowSpecific() || + isRenderToTexture() && mWidth == mHeight ); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 mOrientationMode = orientationMode; #endif From 07fb831cbf5ef236b9e7ccbf58fdbd712c9a0541 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 14 Sep 2023 14:45:28 +0200 Subject: [PATCH 50/58] better max resolutions detection on Vulkan --- RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index f0be721c39f..aebd12ea953 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -615,8 +615,9 @@ namespace Ogre } const VkPhysicalDeviceLimits &deviceLimits = mDevice->mDeviceProperties.limits; - rsc->setMaximumResolutions( deviceLimits.maxImageDimension2D, deviceLimits.maxImageDimension3D, - deviceLimits.maxImageDimensionCube ); + rsc->setMaximumResolutions( std::min( deviceLimits.maxImageDimension2D, 16384u ), + std::min( deviceLimits.maxImageDimension3D, 4096u ), + std::min( deviceLimits.maxImageDimensionCube, 16384u ) ); rsc->setMaxThreadsPerThreadgroupAxis( deviceLimits.maxComputeWorkGroupSize ); rsc->setMaxThreadsPerThreadgroup( deviceLimits.maxComputeWorkGroupInvocations ); @@ -673,7 +674,6 @@ namespace Ogre rsc->setCapability( RSC_EXPLICIT_API ); rsc->setMaxPointSize( 256 ); - rsc->setMaximumResolutions( 16384, 4096, 16384 ); rsc->setVertexProgramConstantFloatCount( 256u ); rsc->setVertexProgramConstantIntCount( 256u ); From b5417b31b1c3f785d5b96cba9cefbcdca877222c Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 14 Sep 2023 14:51:56 +0200 Subject: [PATCH 51/58] detect RSC_UMA on Vulkan --- .../Vulkan/src/OgreVulkanRenderSystem.cpp | 11 +++++++++++ .../Vulkan/src/Vao/OgreVulkanBufferInterface.cpp | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index aebd12ea953..0d9aa88f8a7 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -674,6 +674,17 @@ namespace Ogre rsc->setCapability( RSC_EXPLICIT_API ); rsc->setMaxPointSize( 256 ); + const VkPhysicalDeviceMemoryProperties &memoryProperties = mDevice->mDeviceMemoryProperties; + for( uint32_t typeIndex = 0; typeIndex < memoryProperties.memoryTypeCount; ++typeIndex ) + { + const VkMemoryType &memoryType = memoryProperties.memoryTypes[typeIndex]; + if( ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ) != 0 && + ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ) != 0 && + ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) != 0 ) + { + rsc->setCapability( RSC_UMA ); + } + } rsc->setVertexProgramConstantFloatCount( 256u ); rsc->setVertexProgramConstantIntCount( 256u ); diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanBufferInterface.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanBufferInterface.cpp index ae37005bad4..21f0a82198c 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanBufferInterface.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanBufferInterface.cpp @@ -142,6 +142,15 @@ namespace Ogre //----------------------------------------------------------------------------------- size_t VulkanBufferInterface::advanceFrame( bool bAdvanceFrame ) { + if( mBuffer->mBufferType == BT_DEFAULT_SHARED ) + { + if( bAdvanceFrame ) + { + mBuffer->mFinalBufferStart = mBuffer->mInternalBufferStart; + } + return 0; + } + VulkanVaoManager *vaoManager = static_cast( mBuffer->mVaoManager ); size_t dynamicCurrentFrame = mBuffer->mFinalBufferStart - mBuffer->mInternalBufferStart; dynamicCurrentFrame /= mBuffer->_getInternalNumElements(); @@ -159,6 +168,12 @@ namespace Ogre //----------------------------------------------------------------------------------- void VulkanBufferInterface::regressFrame() { + if( mBuffer->mBufferType == BT_DEFAULT_SHARED ) + { + mBuffer->mFinalBufferStart = mBuffer->mInternalBufferStart; + return; + } + VulkanVaoManager *vaoManager = static_cast( mBuffer->mVaoManager ); size_t dynamicCurrentFrame = mBuffer->mFinalBufferStart - mBuffer->mInternalBufferStart; dynamicCurrentFrame /= mBuffer->_getInternalNumElements(); From 7109650bc5f54935d8a6bf4b408e9f23e69d54f4 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 14 Sep 2023 16:23:36 +0200 Subject: [PATCH 52/58] fixed hasMinVersion(major, minor, release) --- OgreMain/include/OgreRenderSystemCapabilities.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OgreMain/include/OgreRenderSystemCapabilities.h b/OgreMain/include/OgreRenderSystemCapabilities.h index 37707dafbc8..740a41a6989 100644 --- a/OgreMain/include/OgreRenderSystemCapabilities.h +++ b/OgreMain/include/OgreRenderSystemCapabilities.h @@ -332,7 +332,7 @@ namespace Ogre bool hasMinVersion( int minMajor, int minMinor, int minRel ) const { return major > minMajor || ( major == minMajor && minor >= minMinor ) || - ( major == minMajor && minor >= minMinor && release == minRel ); + ( major == minMajor && minor == minMinor && release >= minRel ); } }; From a5f83b285a85403e3069b593e24649920d622274 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 14 Sep 2023 17:02:26 +0200 Subject: [PATCH 53/58] Use VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT as heuristic to enable RSC_IS_TILER codepath of buffers clearing. It is a prerequisite to support memory-less aka VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT depth/stencil textures. --- RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index 0d9aa88f8a7..222cbe39fb2 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -674,6 +674,7 @@ namespace Ogre rsc->setCapability( RSC_EXPLICIT_API ); rsc->setMaxPointSize( 256 ); + // check memory properties to determine, if we can use UMA and/or TBDR optimizations const VkPhysicalDeviceMemoryProperties &memoryProperties = mDevice->mDeviceMemoryProperties; for( uint32_t typeIndex = 0; typeIndex < memoryProperties.memoryTypeCount; ++typeIndex ) { @@ -684,6 +685,13 @@ namespace Ogre { rsc->setCapability( RSC_UMA ); } + // VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT is a prerequisite for TBDR, and is probably a good + // heuristic that TBDR mode of buffers clearing is supported efficiently, i.e. RSC_IS_TILER. + if( ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT ) != 0 ) + { + rsc->setCapability( RSC_IS_TILER ); + rsc->setCapability( RSC_TILER_CAN_CLEAR_STENCIL_REGION ); + } } rsc->setVertexProgramConstantFloatCount( 256u ); From a55f69a64accbe7fc184fba6d3a7cabb6c8aea9f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 17 Sep 2023 21:10:36 -0300 Subject: [PATCH 54/58] Do not treat dGPUs as UMA When the BIOS & GPU has Resizable BAR enabled, x86 GPUs will expose DEVICE_LOCAL_BIT + HOST_VISIBLE_BIT + HOST_COHERENT_BIT memory. That doesn't mean they're UMA, and we definitely do NOT want to mess with the can of worms that is dealing with that memory type. And if Resizable BAR is disabled, that memory type may still be exposed but limited to 256MB (which is globally shared by the entire OS, if the OS runs out of it bad things happen). There's still the question of what to do with AMD iGPUs though (e.g. Vega and RDNA2 iGPUs will expose these flags and we will consider them UMAs. Technically this is correct. Is it a good idea? I don't know). --- .../Vulkan/src/OgreVulkanRenderSystem.cpp | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index 222cbe39fb2..e4f274483ed 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -676,21 +676,27 @@ namespace Ogre // check memory properties to determine, if we can use UMA and/or TBDR optimizations const VkPhysicalDeviceMemoryProperties &memoryProperties = mDevice->mDeviceMemoryProperties; - for( uint32_t typeIndex = 0; typeIndex < memoryProperties.memoryTypeCount; ++typeIndex ) + if( mDevice->mDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU || + mDevice->mDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU ) { - const VkMemoryType &memoryType = memoryProperties.memoryTypes[typeIndex]; - if( ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ) != 0 && - ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ) != 0 && - ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) != 0 ) + for( uint32_t typeIndex = 0; typeIndex < memoryProperties.memoryTypeCount; ++typeIndex ) { - rsc->setCapability( RSC_UMA ); - } - // VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT is a prerequisite for TBDR, and is probably a good - // heuristic that TBDR mode of buffers clearing is supported efficiently, i.e. RSC_IS_TILER. - if( ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT ) != 0 ) - { - rsc->setCapability( RSC_IS_TILER ); - rsc->setCapability( RSC_TILER_CAN_CLEAR_STENCIL_REGION ); + const VkMemoryType &memoryType = memoryProperties.memoryTypes[typeIndex]; + if( ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ) != 0 && + ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ) != 0 && + ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) != 0 ) + { + rsc->setCapability( RSC_UMA ); + } + + // VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT is a prerequisite for TBDR, and is probably + // a good heuristic that TBDR mode of buffers clearing is supported efficiently, + // i.e. RSC_IS_TILER. + if( ( memoryType.propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT ) != 0 ) + { + rsc->setCapability( RSC_IS_TILER ); + rsc->setCapability( RSC_TILER_CAN_CLEAR_STENCIL_REGION ); + } } } @@ -1926,8 +1932,8 @@ namespace Ogre { #if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_64 VkSampler textureSampler = static_cast( samplerblock->mRsData ); -#else // VK handles are always 64bit, even on 32bit systems - VkSampler textureSampler = *static_cast( samplerblock->mRsData ); +#else // VK handles are always 64bit, even on 32bit systems + VkSampler textureSampler = *static_cast( samplerblock->mRsData ); #endif if( mGlobalTable.samplers[texUnit].sampler != textureSampler ) { @@ -3410,8 +3416,8 @@ namespace Ogre #if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_64 newBlock->mRsData = textureSampler; -#else // VK handles are always 64bit, even on 32bit systems - newBlock->mRsData = new uint64(textureSampler); +#else // VK handles are always 64bit, even on 32bit systems + newBlock->mRsData = new uint64( textureSampler ); #endif } //------------------------------------------------------------------------- @@ -3420,9 +3426,9 @@ namespace Ogre assert( block->mRsData ); #if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_64 VkSampler textureSampler = static_cast( block->mRsData ); -#else // VK handles are always 64bit, even on 32bit systems - VkSampler textureSampler = *static_cast( block->mRsData ); - delete (uint64*)block->mRsData; +#else // VK handles are always 64bit, even on 32bit systems + VkSampler textureSampler = *static_cast( block->mRsData ); + delete(uint64 *)block->mRsData; #endif delayed_vkDestroySampler( mVaoManager, mActiveDevice->mDevice, textureSampler, 0 ); } From b99d69459e5cb9777e5ef189e3d6de8e740f448f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 17 Sep 2023 21:15:05 -0300 Subject: [PATCH 55/58] Fix inconsistent indentation --- .../Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any | 2 +- Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any | 4 ++-- Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any | 4 ++-- Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any | 2 +- Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any | 4 ++-- Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any index f9443f3082b..c225d94afdf 100644 --- a/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any @@ -460,7 +460,7 @@ struct Material @property( hlms_emulate_clip_distances && hlms_pso_clip_distances ) @foreach( hlms_pso_clip_distances, n ) INTERPOLANT( float clipDistance@n, @counter(texcoord) ); - @end + @end @end @insertpiece( custom_VStoPS ) @end diff --git a/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any index 911571bbd10..99752eb78ca 100644 --- a/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any @@ -751,8 +751,8 @@ @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk ) @foreach( hlms_pso_clip_distances, n ) if( inPs.clipDistance@n < 0.0 ) - discard; - @end + discard; + @end @end @property( hlms_screen_pos_uv ) diff --git a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any index 8e8aa3b5656..fff0d10f965 100644 --- a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any @@ -214,8 +214,8 @@ @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk) @foreach( hlms_pso_clip_distances, n ) if( inPs.clipDistance@n < 0.0 ) - discard; - @end + discard; + @end @end @insertpiece( LoadMaterial ) diff --git a/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any b/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any index db07171fa1b..05bca8a5847 100644 --- a/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any +++ b/Samples/Media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any @@ -117,7 +117,7 @@ @property( hlms_emulate_clip_distances && hlms_pso_clip_distances ) @foreach( hlms_pso_clip_distances, n ) INTERPOLANT( float clipDistance@n, @counter(texcoord) ); - @end + @end @end @insertpiece( custom_VStoPS ) @end diff --git a/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any b/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any index 61aa1f5e45b..5b061d9f7c1 100644 --- a/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any @@ -57,8 +57,8 @@ @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk) @foreach( hlms_pso_clip_distances, n ) if( inPs.clipDistance@n < 0.0 ) - discard; - @end + discard; + @end @end midf4 diffuseCol = midf4_c( 1.0f, 1.0f, 1.0f, 1.0f ); diff --git a/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl b/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl index 4411e686b7f..1978c8465de 100644 --- a/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl +++ b/Samples/Media/Hlms/Unlit/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; From 75539ac1d3a39e3780da1ba190c0cce98fb8e4bc Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 17 Sep 2023 21:17:28 -0300 Subject: [PATCH 56/58] Fix warning --- RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp | 2 +- RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp index f1712e5c843..ee124d5cba9 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusTextureGpu.cpp @@ -860,7 +860,7 @@ namespace Ogre void GL3PlusTextureGpuRenderTarget::setOrientationMode( OrientationMode orientationMode ) { OGRE_ASSERT_LOW( mResidencyStatus == GpuResidency::OnStorage || isRenderWindowSpecific() || - isRenderToTexture() && mWidth == mHeight ); + ( isRenderToTexture() && mWidth == mHeight ) ); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 mOrientationMode = orientationMode; #endif diff --git a/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp b/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp index 6a30fba7284..ffdd6bc7cf3 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanTextureGpu.cpp @@ -1015,7 +1015,7 @@ namespace Ogre void VulkanTextureGpuRenderTarget::setOrientationMode( OrientationMode orientationMode ) { OGRE_ASSERT_LOW( mResidencyStatus == GpuResidency::OnStorage || isRenderWindowSpecific() || - isRenderToTexture() && mWidth == mHeight ); + ( isRenderToTexture() && mWidth == mHeight ) ); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 mOrientationMode = orientationMode; #endif From 0c8a67d269181de673c17a94680d2df8dcf4864f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 18 Sep 2023 20:56:37 -0300 Subject: [PATCH 57/58] Remove ancient Instancing documentation that no longer applies --- Docs/src/manual/threading.md | 71 +----------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/Docs/src/manual/threading.md b/Docs/src/manual/threading.md index 29c0d0b0420..16a43bc3e1a 100644 --- a/Docs/src/manual/threading.md +++ b/Docs/src/manual/threading.md @@ -2,7 +2,7 @@ Threading {#threading} ========= -Ogre 2.0 uses synchronous threading for some of its operations. This +OgreNext uses synchronous threading for some of its operations. This means the main thread wakes up the worker threads, and waits for all worker threads to finish. It also means users don't have to be worried that Ogre is using CPU cores while the application is outside a @@ -47,75 +47,6 @@ case the ideal number of threads becomes number\_of\_logical\_cores – 1 Whether increasing the number of threads to include hyperthreading cores improves performance or not remains to be tested. -## More info about InstancingThreadedCullingMethod {#ThreadingInitializingCullingMethod} - -There are two Instancing techniques that perform culling of their own: - -- HW Basic -- HW VTF - -Frustum culling is highly parallelizable & scalable. However, we first -cull InstanceBatches & regular entities, then ask the culled -InstanceBatches to perform their culling to the InstancedEntities they -own. - -This results performance boost for skipping large amounts of instanced -entities when the whole batch isn't visible. However, this also means -threading frustum culling of instanced entities got harder. - -There were four possible approaches: - -- Ask all existing batches to frustum cull. Then use only the ones we - want. Sheer brute force. Scales very well with cores, but sacrifices - performance unnecessary when only a few batches are visible. This - approach is not taken by Ogre. -- Sync every time an InstanceBatchHW or InstanceBatchHW\_VTF tries to - frustum cull to delegate the job on worker threads. Considering - there could be hundreds of InstanceBatches, this would cause a huge - amount of thread synchronization overhead & context switches. This - approach is not taken by Ogre. -- Each thread after having culled all InstancedBatches & Entities, - will parse the culled list to ask all MovableObjects to perform - culling of their own. Entities will ignore this call (however they - add to a small overhead for traversing them and calling a virtual - function) while InstanceBatchHW & InstanceBatchHW\_VTF will perform - their own culling from within the multiple threads. This approach - scales well with cores and only visible batches. However load - balancing may be an issue for certain scenes: eg. an InstanceBatch - with 5000 InstancedEntities in one thread, while the other three - threads get one InstanceBatch each with 50 InstancedEntities. The - first thread will have considerably more work to do than the other - three. This approach is a good balance when compared to the first - two. **This is the approach taken by Ogre when - INSTANCING\_CULLING\_THREADED is on** -- Don't multithread instanced entitites' frustum culling. Only the - InstanceBatch & Entity's frustum culling will be threaded. **This is - what happens when INSTANCING\_CULLING\_SINGLE is on**. - -Whether INSTANCING\_CULLING\_THREADED improves or degrades performance -depends highly on your scene. - -When to use INSTANCING\_CULLING\_SINGLETHREAD? - -If your scene doesn't use HW Basic or HW VTF instancing techniques, or -you have very few Instanced entities compared to the amount of regular -Entities. - -Turning threading on, you'll be wasting your time traversing the list -from multiple threads in search of InstanceBatchHW & -InstanceBatchHW\_VTF - -When to use INSTANCING\_CULLING\_THREADED? - -If your scene makes intensive use of HW Basic and/or HW VTF instancing -techniques. Note that threaded culling is performed in SCENE\_STATIC -instances too. The most advantage is seen when the instances per batch -is very high and when doing many PASS\_SCENE, which require frustum -culling multiple times per frame (eg. pssm shadows, multiple light -sources with shadows, very advanced compositing, etc) - -Note that unlike the number of threads, you can switch between methods -at any time at runtime. # What tasks are threaded in Ogre {#ThreadingInOgre} From f01c889c0f20975e0a13872aafe51363a4019892 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 18 Sep 2023 20:57:36 -0300 Subject: [PATCH 58/58] OgreNext 2.4 never existed --- Docs/src/manual/Ogre3.0.Changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/src/manual/Ogre3.0.Changes.md b/Docs/src/manual/Ogre3.0.Changes.md index 3444c915fa5..d764cfacad8 100644 --- a/Docs/src/manual/Ogre3.0.Changes.md +++ b/Docs/src/manual/Ogre3.0.Changes.md @@ -46,4 +46,4 @@ Make sure to upgrade to latest CMake scripts if you're using them; to be ready f Default material BRDF settings have changed in 3.0; thus materials will look different. -See [PBR / PBS Changes in 3.0](@ref PBSChangesIn30) to how make them look like they did in 2.4 and what these changes mean. \ No newline at end of file +See [PBR / PBS Changes in 3.0](@ref PBSChangesIn30) to how make them look like they did in 2.3 and what these changes mean. \ No newline at end of file