From f3d0747568976c2a9e5c2531beb633d4855decf7 Mon Sep 17 00:00:00 2001 From: Th3V1kt0r <98119869+Th3V1kt0r@users.noreply.github.com> Date: Thu, 4 May 2023 19:28:10 +0200 Subject: [PATCH 001/124] bugfix: memory leak due to undeleted stereo driver bridge Stereo driver must be freed after device is created. This bug is probably also included in Ogre1. --- RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp index 5f6baca4296..de88e7f1673 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp @@ -206,6 +206,12 @@ namespace Ogre mHLSLProgramFactory = 0; } +#if OGRE_NO_QUAD_BUFFER_STEREO == 0 + // Stereo driver must be freed after device is created + D3D11StereoDriverBridge* stereoBridge = D3D11StereoDriverBridge::getSingletonPtr(); + OGRE_DELETE stereoBridge; +#endif + LogManager::getSingleton().logMessage( "D3D11: " + getName() + " destroyed." ); } //--------------------------------------------------------------------- From 393868018c39335c2e43d5d29039ae6916a9c530 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 6 May 2023 11:39:03 -0300 Subject: [PATCH 002/124] Fix clang format --- RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp index de88e7f1673..7183537d500 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp @@ -208,7 +208,7 @@ namespace Ogre #if OGRE_NO_QUAD_BUFFER_STEREO == 0 // Stereo driver must be freed after device is created - D3D11StereoDriverBridge* stereoBridge = D3D11StereoDriverBridge::getSingletonPtr(); + D3D11StereoDriverBridge *stereoBridge = D3D11StereoDriverBridge::getSingletonPtr(); OGRE_DELETE stereoBridge; #endif From ea857d214c98bc303ee6073ae1acd9f64a8b9c55 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 6 May 2023 13:32:20 -0300 Subject: [PATCH 003/124] Fix planar reflections in Terra --- Samples/Media/Hlms/Terra/Any/800.VertexShader_piece_vs.any | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Samples/Media/Hlms/Terra/Any/800.VertexShader_piece_vs.any b/Samples/Media/Hlms/Terra/Any/800.VertexShader_piece_vs.any index 726bd23e605..383e6e688f6 100644 --- a/Samples/Media/Hlms/Terra/Any/800.VertexShader_piece_vs.any +++ b/Samples/Media/Hlms/Terra/Any/800.VertexShader_piece_vs.any @@ -152,6 +152,10 @@ outVs.zwDepth.xy = outVs_Position.zw; @end + @property( hlms_global_clip_planes ) + outVs_clipDistance0 = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); + @end + @property( hlms_instanced_stereo ) outVs_viewportIndex = int( inVs_stereoDrawId & 0x01u ); @end From 41a20df172bbadce9dee4f3e8a5eff16b7255256 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 11 May 2023 01:09:39 +0200 Subject: [PATCH 004/124] Uniform cmake_min_Version into ogre_next --- CMake/Templates/SDK_CMakeLists.txt.in | 8 +------- .../2.0/AndroidAppTemplate/Template/app/CMakeLists.txt | 2 +- Samples/2.0/Tutorials/EmptyProject/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/CMake/Templates/SDK_CMakeLists.txt.in b/CMake/Templates/SDK_CMakeLists.txt.in index ebda95e9b20..3df8832f728 100644 --- a/CMake/Templates/SDK_CMakeLists.txt.in +++ b/CMake/Templates/SDK_CMakeLists.txt.in @@ -11,16 +11,10 @@ # OGRE SAMPLES BUILD SYSTEM ###################################################################### -cmake_minimum_required(VERSION 2.6.2) +cmake_minimum_required(VERSION 3.5.1) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE) cmake_policy(SET CMP0003 NEW) -# CMake 2.8.2 has a bug that creates unusable Xcode projects when using ARCHS_STANDARD_32_BIT -# to specify both armv6 and armv7. -if(OGRE_BUILD_PLATFORM_APPLE_IOS AND (CMAKE_VERSION VERSION_EQUAL 2.8.2) AND (CMAKE_GENERATOR STREQUAL "Xcode")) - message(FATAL_ERROR "CMake 2.8.2 cannot create compatible Xcode projects for iOS, please download the latest version or an older release from http://www.cmake.org/files/") -endif() - # Just debug / release since that's all that's included in SDK. Only release for iOS/OS X if(APPLE) set (CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE) diff --git a/Samples/2.0/AndroidAppTemplate/Template/app/CMakeLists.txt b/Samples/2.0/AndroidAppTemplate/Template/app/CMakeLists.txt index f165c1ec904..2467bd359b4 100644 --- a/Samples/2.0/AndroidAppTemplate/Template/app/CMakeLists.txt +++ b/Samples/2.0/AndroidAppTemplate/Template/app/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.4.1) +cmake_minimum_required(VERSION 3.5.1) # build native_app_glue as a static lib set( APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue ) diff --git a/Samples/2.0/Tutorials/EmptyProject/CMakeLists.txt b/Samples/2.0/Tutorials/EmptyProject/CMakeLists.txt index 63bc6b733a3..56c665d2299 100644 --- a/Samples/2.0/Tutorials/EmptyProject/CMakeLists.txt +++ b/Samples/2.0/Tutorials/EmptyProject/CMakeLists.txt @@ -10,7 +10,7 @@ #set( CMAKE_TOOLCHAIN_FILE CMake/iOS.cmake ) -cmake_minimum_required( VERSION 3.0 ) +cmake_minimum_required( VERSION 3.5.1 ) project( EmptyProject ) set( EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}" ) From b85e1a64bbb9d539042a08924990235aaa5e825f Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 11 May 2023 19:08:03 +0200 Subject: [PATCH 005/124] [Vk] Fixed assert "Delayed buffer must be destroyed in the last buffered frame!" - new command buffers could happen without frame advancing, causing unexpected mFrameCount incrementing not compensated by undo code --- .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 608f71cbee9..5fa4672a77d 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -1951,10 +1951,6 @@ namespace Ogre } } - VaoManager::_update(); - // Undo the increment from VaoManager::_update. This is done by _notifyNewCommandBuffer - --mFrameCount; - mUsedDescriptorPools.clear(); uint64 currentTimeMs = mTimer->getMilliseconds(); @@ -1999,6 +1995,14 @@ namespace Ogre } } + if( !mFenceFlushed ) + { + // We could only reach here if _update() was called + // twice in a row without completing a full frame. + // Without this, waitForTailFrameToFinish becomes unsafe. + mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); + } + if( !mUsedSemaphores.empty() ) { waitForTailFrameToFinish(); @@ -2049,22 +2053,15 @@ namespace Ogre deallocateEmptyVbos( false ); - if( !mFenceFlushed ) - { - // We could only reach here if _update() was called - // twice in a row without completing a full frame. - // Without this, waitForTailFrameToFinish becomes unsafe. - mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); - } + VaoManager::_update(); mFenceFlushed = false; + mDynamicBufferCurrentFrame = ( mDynamicBufferCurrentFrame + 1 ) % mDynamicBufferMultiplier; } //----------------------------------------------------------------------------------- void VulkanVaoManager::_notifyNewCommandBuffer() { mFenceFlushed = true; - mDynamicBufferCurrentFrame = ( mDynamicBufferCurrentFrame + 1 ) % mDynamicBufferMultiplier; - ++mFrameCount; } //----------------------------------------------------------------------------------- void VulkanVaoManager::getAvailableSempaphores( VkSemaphoreArray &semaphoreArray, From 288ed7c624922ae12f1fb1fadc131a116f157494 Mon Sep 17 00:00:00 2001 From: Dmytro Yunchyk Date: Fri, 12 May 2023 13:58:17 +0200 Subject: [PATCH 006/124] [D3D11] flush when we destroy resources while changing FSAA --- RenderSystems/Direct3D11/src/OgreD3D11Window.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Window.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Window.cpp index e747b3bfd17..0058fca2aec 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Window.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Window.cpp @@ -329,6 +329,10 @@ namespace Ogre _destroySizeDependedD3DResources(); + // Call flush to ensure destruction of resources. + // not doing so may result in 'Out of memory' exception. + mDevice.GetImmediateContext()->Flush(); + if( mUseFlipMode ) { // swapchain is not multisampled in flip sequential mode, so we reuse it From 588104c04cccaf94ca8ff80ea7aaabf24f726afc Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Fri, 12 May 2023 15:27:15 +0200 Subject: [PATCH 007/124] [Vk] Added miscParams["preTransform"] bool option. This optimisation is useful and enabled by default, but for example is not compatible with rendering to a non-fullscreen android.view.SurfaceView --- Docs/src/SettingUpOgre/SettingUpOgreAndroid.md | 2 +- RenderSystems/Vulkan/include/OgreVulkanWindow.h | 1 + RenderSystems/Vulkan/src/OgreVulkanWindow.cpp | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md b/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md index 8d7330bf27b..64e3de1640c 100644 --- a/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md +++ b/Docs/src/SettingUpOgre/SettingUpOgreAndroid.md @@ -142,7 +142,7 @@ Open these projects in Android Studio and deploy the APK. > (but ocassionally does manifest even in portrait). > > If you suspect this is the cause of your bugs, edit the CMakeLists.txt file so that -> OGRE_CONFIG_ENABLE_VIEWPORT_ORIENTATIONMODE is no longer force-enabled. +> OGRE_CONFIG_ENABLE_VIEWPORT_ORIENTATIONMODE is no longer force-enabled, or pass miscParams["preTransform"] = "false" to the window. > > You can debug viewport orientation bugs on Desktop by enabling OGRE_CONFIG_ENABLE_VIEWPORT_ORIENTATIONMODE > in your Desktop build, and manually editing OgreVulkanWindow.cpp and set: diff --git a/RenderSystems/Vulkan/include/OgreVulkanWindow.h b/RenderSystems/Vulkan/include/OgreVulkanWindow.h index 8b0e24cf77d..caf5db73458 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanWindow.h +++ b/RenderSystems/Vulkan/include/OgreVulkanWindow.h @@ -97,6 +97,7 @@ namespace Ogre }; bool mLowestLatencyVSync; + bool mEnablePreTransform; bool mClosed; VkSurfaceKHR mSurfaceKHR; diff --git a/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp b/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp index 7a7952d2b4e..a2058ca6a91 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanWindow.cpp @@ -180,6 +180,7 @@ namespace Ogre uint32 height, bool fullscreenMode ) : VulkanWindow( title, width, height, fullscreenMode ), mLowestLatencyVSync( false ), + mEnablePreTransform( true ), mClosed( false ), mSurfaceKHR( 0 ), mSwapchain( 0 ), @@ -216,6 +217,9 @@ namespace Ogre opt = miscParams->find( "vsync_method" ); if( opt != end ) mLowestLatencyVSync = opt->second == "Lowest Latency"; + opt = miscParams->find( "preTransform" ); + if( opt != end ) + mEnablePreTransform = StringConverter::parseBool( opt->second ); } //------------------------------------------------------------------------- PixelFormatGpu VulkanWindowSwapChainBased::chooseSurfaceFormat( bool hwGamma ) @@ -410,7 +414,7 @@ namespace Ogre } } #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 - if( 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/ From b9b4de3f5bde5fdb750f56ba09264519182e243b Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 13 May 2023 12:59:22 -0300 Subject: [PATCH 008/124] Fix bugs in PBS objects w/ both Terrain & Planar reflections on GL3+ would show overdarkened objects Vulkan would have missing terrain shadows --- .../src/Terra/Hlms/PbsListener/OgreHlmsPbsTerraShadows.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/PbsListener/OgreHlmsPbsTerraShadows.cpp b/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/PbsListener/OgreHlmsPbsTerraShadows.cpp index 52c1a770e3d..eef8c8c0753 100644 --- a/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/PbsListener/OgreHlmsPbsTerraShadows.cpp +++ b/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/PbsListener/OgreHlmsPbsTerraShadows.cpp @@ -86,8 +86,10 @@ namespace Ogre if( hlms->_getProperty( HlmsBaseProp::ShadowCaster ) == 0 && hlms->_getProperty( PbsTerraProperty::TerraEnabled ) != 0 ) { - int32 texUnit = hlms->_getProperty( PbsProperty::Set0TextureSlotEnd ); - hlms->_setTextureReg( VertexShader, "terrainShadows", texUnit - 1 ); + int32 texUnit = hlms->_getProperty( PbsProperty::Set0TextureSlotEnd ) - 1; + if( hlms->_getProperty( PbsProperty::HasPlanarReflections ) ) + --texUnit; + hlms->_setTextureReg( VertexShader, "terrainShadows", texUnit ); } } //----------------------------------------------------------------------------------- From bb40519a10c3ebdf6ec721bb65544816b3b518ab Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 15 May 2023 14:13:41 -0700 Subject: [PATCH 009/124] 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 010/124] [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 011/124] [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 012/124] 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 013/124] [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 014/124] 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 015/124] [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 016/124] 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 017/124] 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 018/124] 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 019/124] 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 020/124] 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 021/124] 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 022/124] 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 023/124] 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 024/124] [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 025/124] 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 026/124] 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 027/124] 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 028/124] 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 029/124] 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 030/124] 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 031/124] 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 032/124] [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 033/124] [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 034/124] 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 035/124] 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 036/124] 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 037/124] 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 038/124] 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 039/124] 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 040/124] 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 041/124] 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 042/124] 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 043/124] 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 044/124] 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 045/124] 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 046/124] 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 047/124] 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 048/124] 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 049/124] [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 ca7c2746566fca24a1470930e85f8f76677f3788 Mon Sep 17 00:00:00 2001 From: cryham Date: Thu, 31 Aug 2023 18:26:09 +0200 Subject: [PATCH 050/124] Add sortByName to HlmsJson::saveMaterials --- OgreMain/include/OgreHlmsJson.h | 3 ++- OgreMain/src/OgreHlmsJson.cpp | 42 ++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/OgreMain/include/OgreHlmsJson.h b/OgreMain/include/OgreHlmsJson.h index 8db60d0b11d..5a61d8e9f84 100644 --- a/OgreMain/include/OgreHlmsJson.h +++ b/OgreMain/include/OgreHlmsJson.h @@ -170,7 +170,8 @@ namespace Ogre Leave it blank if you don't know what to put */ void saveMaterials( const Hlms *hlms, String &outString, - const String &additionalTextureExtension ); + const String &additionalTextureExtension, + bool sortByName = false); /** Saves a single datablock to a string @param datablock diff --git a/OgreMain/src/OgreHlmsJson.cpp b/OgreMain/src/OgreHlmsJson.cpp index 8909a08b01a..8ec9f72e709 100644 --- a/OgreMain/src/OgreHlmsJson.cpp +++ b/OgreMain/src/OgreHlmsJson.cpp @@ -27,6 +27,7 @@ THE SOFTWARE. */ #include "OgreStableHeaders.h" +#include "OgreIdString.h" #if !OGRE_NO_JSON @@ -1012,7 +1013,8 @@ namespace Ogre } //----------------------------------------------------------------------------------- void HlmsJson::saveMaterials( const Hlms *hlms, String &outString, - const String &additionalTextureExtension ) + const String &additionalTextureExtension, + bool sortByName ) { outString += "{"; @@ -1113,14 +1115,42 @@ namespace Ogre Hlms::HlmsDatablockMap::const_iterator itor = datablockMap.begin(); Hlms::HlmsDatablockMap::const_iterator endt = datablockMap.end(); + + if (sortByName) + { + std::map sortedMap; + while( itor != endt ) + { + sortedMap[itor->second.name] = itor->first; + ++itor; + } - while( itor != endt ) + std::map::const_iterator itor2 = sortedMap.begin(); + std::map::const_iterator endt2 = sortedMap.end(); + + while( itor2 != endt2 ) + { + Hlms::HlmsDatablockMap::const_iterator itorFind = datablockMap.find(itor2->second); + if (itorFind != endt) + { + const HlmsDatablock *datablock = itorFind->second.datablock; + + if( datablock != defaultDatablock ) + saveDatablock( itorFind->second.name, datablock, outString, additionalTextureExtension ); + } + ++itor2; + } + } + else { - const HlmsDatablock *datablock = itor->second.datablock; + while( itor != endt ) + { + const HlmsDatablock *datablock = itor->second.datablock; - if( datablock != defaultDatablock ) - saveDatablock( itor->second.name, datablock, outString, additionalTextureExtension ); - ++itor; + if( datablock != defaultDatablock ) + saveDatablock( itor->second.name, datablock, outString, additionalTextureExtension ); + ++itor; + } } if( numDatablocks > 1u ) From 55191f659be0fd240539b1d71ae4bb042d930db2 Mon Sep 17 00:00:00 2001 From: cryham Date: Thu, 13 Jul 2023 14:28:05 +0200 Subject: [PATCH 051/124] 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 052/124] 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 053/124] 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 054/124] [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 055/124] 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 056/124] 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 057/124] 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 058/124] 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 059/124] 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 060/124] 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 061/124] 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 062/124] 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 063/124] 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 064/124] 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 065/124] 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 066/124] 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 067/124] 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 From 5afb6b8a182c814a7aa22f3b3291ede94cf48a48 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 5 Oct 2023 14:48:42 +0200 Subject: [PATCH 068/124] warning: variable 'lastHlmsCacheHash' set but not used --- OgreMain/src/OgreRenderQueue.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/OgreMain/src/OgreRenderQueue.cpp b/OgreMain/src/OgreRenderQueue.cpp index 38d4a825e22..1bef210844b 100644 --- a/OgreMain/src/OgreRenderQueue.cpp +++ b/OgreMain/src/OgreRenderQueue.cpp @@ -912,7 +912,6 @@ namespace Ogre const RenderQueueGroup &renderQueueGroup ) { HlmsCache const *lastHlmsCache = &c_dummyCache; - uint32 lastHlmsCacheHash = 0; const QueuedRenderableArray &queuedRenderables = renderQueueGroup.mQueuedRenderables; @@ -927,7 +926,6 @@ namespace Ogre Hlms *hlms = mHlmsManager->getHlms( static_cast( datablock->mType ) ); - lastHlmsCacheHash = lastHlmsCache->hash; hlms->getMaterial( lastHlmsCache, passCache[datablock->mType], queuedRenderable, casterPass ); ++itor; From d26475c25d10e3409cceed8fdc10a144de721f52 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 5 Oct 2023 14:58:06 +0200 Subject: [PATCH 069/124] warning: argument 'passCache' of type 'HlmsCache[8]' with mismatched bound warning: argument 'vertexElements' of type 'const VertexElement2 *[]' with mismatched bound warning: argument 'srcData' of type 'const uint8 *[]' (aka 'const unsigned char *[]') with mismatched bound warning: argument 'srcOffset' of type 'const size_t[]' (aka 'const unsigned long[]') with mismatched bound warning: argument 'srcBytesPerVertex' of type 'const size_t[]' (aka 'const unsigned long[]') with mismatched bound --- OgreMain/include/OgreRenderQueue.h | 4 ++-- OgreMain/src/OgreVertexShadowMapHelper.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OgreMain/include/OgreRenderQueue.h b/OgreMain/include/OgreRenderQueue.h index c15c7ae0366..4bd9fce5631 100644 --- a/OgreMain/include/OgreRenderQueue.h +++ b/OgreMain/include/OgreRenderQueue.h @@ -186,8 +186,8 @@ namespace Ogre Renderable *pRend, const MovableObject *pMovableObject, bool isV1 ); - void renderES2( RenderSystem *rs, bool casterPass, bool dualParaboloid, HlmsCache passCache[], - const RenderQueueGroup &renderQueueGroup ); + void renderES2( RenderSystem *rs, bool casterPass, bool dualParaboloid, + HlmsCache passCache[HLMS_MAX], const RenderQueueGroup &renderQueueGroup ); /// Renders in a compatible way with GL 3.3 and D3D11. Can only render V2 objects /// (i.e. Items, VertexArrayObject) diff --git a/OgreMain/src/OgreVertexShadowMapHelper.cpp b/OgreMain/src/OgreVertexShadowMapHelper.cpp index 45052742734..bd4ccf7b9ad 100644 --- a/OgreMain/src/OgreVertexShadowMapHelper.cpp +++ b/OgreMain/src/OgreVertexShadowMapHelper.cpp @@ -256,9 +256,9 @@ namespace Ogre } //--------------------------------------------------------------------- uint32 VertexShadowMapHelper::shrinkVertexBuffer( - uint8 *dstData, const VertexElement2 *vertexElements[], - FastArray &vertexConversionLutArg, bool hasIndexBuffer, const uint8 *srcData[], - const size_t srcOffset[], const size_t srcBytesPerVertex[], uint32 numVertices ) + uint8 *dstData, const VertexElement2 *vertexElements[3], + FastArray &vertexConversionLutArg, bool hasIndexBuffer, const uint8 *srcData[3], + const size_t srcOffset[3], const size_t srcBytesPerVertex[3], uint32 numVertices ) { size_t elementOffset[3]; size_t elementSize[3]; From 7f381c6d42651d7c013df26cf1dcc191496ae755 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 5 Oct 2023 15:15:06 +0200 Subject: [PATCH 070/124] warning: use of bitwise '|' with boolean operands [-Wbitwise-instead-of-logical] --- OgreMain/src/OgreRootLayout.cpp | 10 ++++++---- RenderSystems/Vulkan/src/OgreVulkanRootLayout.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/OgreMain/src/OgreRootLayout.cpp b/OgreMain/src/OgreRootLayout.cpp index acab061e97f..835fb231340 100644 --- a/OgreMain/src/OgreRootLayout.cpp +++ b/OgreMain/src/OgreRootLayout.cpp @@ -220,8 +220,9 @@ namespace Ogre } } - const bool texTypesInUse = mDescBindingRanges[i][DescBindingTypes::TexBuffer].isInUse() | - mDescBindingRanges[i][DescBindingTypes::Texture].isInUse(); + const bool texTypesInUse = + (int)mDescBindingRanges[i][DescBindingTypes::TexBuffer].isInUse() | + (int)mDescBindingRanges[i][DescBindingTypes::Texture].isInUse(); if( texTypesInUse ) { if( !bakedSetsSeenTexTypes ) @@ -253,8 +254,9 @@ namespace Ogre } } - const bool uavTypesInUse = mDescBindingRanges[i][DescBindingTypes::UavBuffer].isInUse() | - mDescBindingRanges[i][DescBindingTypes::UavTexture].isInUse(); + const bool uavTypesInUse = + (int)mDescBindingRanges[i][DescBindingTypes::UavBuffer].isInUse() | + (int)mDescBindingRanges[i][DescBindingTypes::UavTexture].isInUse(); if( uavTypesInUse ) { if( !bakedSetsSeenUavTypes ) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRootLayout.cpp b/RenderSystems/Vulkan/src/OgreVulkanRootLayout.cpp index 50549187e03..3088006a600 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRootLayout.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRootLayout.cpp @@ -500,13 +500,13 @@ namespace Ogre } else { - bDirty |= - table.dirtyBakedTextures & ( ranges[DescBindingTypes::ReadOnlyBuffer].isInUse() | - ranges[DescBindingTypes::TexBuffer].isInUse() | - ranges[DescBindingTypes::Texture].isInUse() ); + bDirty |= table.dirtyBakedTextures & + ( (int)ranges[DescBindingTypes::ReadOnlyBuffer].isInUse() | + (int)ranges[DescBindingTypes::TexBuffer].isInUse() | + (int)ranges[DescBindingTypes::Texture].isInUse() ); bDirty |= table.dirtyBakedSamplers & ranges[DescBindingTypes::Sampler].isInUse(); - bDirty |= table.dirtyBakedUavs & ( ranges[DescBindingTypes::UavBuffer].isInUse() | - ranges[DescBindingTypes::UavTexture].isInUse() ); + bDirty |= table.dirtyBakedUavs & ( (int)ranges[DescBindingTypes::UavBuffer].isInUse() | + (int)ranges[DescBindingTypes::UavTexture].isInUse() ); } if( bDirty ) From 07303b453a74c14d647963a2d313a5a5234cacb6 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Thu, 5 Oct 2023 18:59:11 +0200 Subject: [PATCH 071/124] WinRT: Prefer Ogre::filesystemPathFromString to convert from narrow string encoding to UTF-16. Currently CP_UTF8 is selected as narrow pathes encoding via #define _OGRE_FILESYSTEM_ARCHIVE_UNICODE, so behavior was not changed --- OgreMain/include/OgreDynLib.h | 2 +- OgreMain/src/OgreDynLib.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OgreMain/include/OgreDynLib.h b/OgreMain/include/OgreDynLib.h index d3d8d2bd41b..b72a912dc34 100644 --- a/OgreMain/include/OgreDynLib.h +++ b/OgreMain/include/OgreDynLib.h @@ -44,7 +44,7 @@ typedef struct HINSTANCE__ *hInstance; #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT # define DYNLIB_HANDLE hInstance -# define DYNLIB_LOAD( a ) LoadPackagedLibrary( UTFString( a ).asWStr_c_str(), 0 ) +# define DYNLIB_LOAD( a ) LoadPackagedLibrary( Ogre::fileSystemPathFromString( a ).c_str(), 0 ) # define DYNLIB_GETSYM( a, b ) GetProcAddress( a, b ) # define DYNLIB_UNLOAD( a ) !FreeLibrary( a ) diff --git a/OgreMain/src/OgreDynLib.cpp b/OgreMain/src/OgreDynLib.cpp index aead325f185..c5d93d74b06 100644 --- a/OgreMain/src/OgreDynLib.cpp +++ b/OgreMain/src/OgreDynLib.cpp @@ -42,7 +42,7 @@ THE SOFTWARE. #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# include "OgreUTFString.h" +# include "OgreFileSystem.h" #endif #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS From 8fd92e4e9c909d744299b3ec9cbf298fbf120e18 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 5 Oct 2023 19:10:38 -0300 Subject: [PATCH 072/124] Fix clang format --- OgreMain/include/OgreHlmsJson.h | 3 +-- OgreMain/src/OgreHlmsJson.cpp | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/OgreMain/include/OgreHlmsJson.h b/OgreMain/include/OgreHlmsJson.h index 5a61d8e9f84..fbd4e83a139 100644 --- a/OgreMain/include/OgreHlmsJson.h +++ b/OgreMain/include/OgreHlmsJson.h @@ -170,8 +170,7 @@ namespace Ogre Leave it blank if you don't know what to put */ void saveMaterials( const Hlms *hlms, String &outString, - const String &additionalTextureExtension, - bool sortByName = false); + const String &additionalTextureExtension, bool sortByName = false ); /** Saves a single datablock to a string @param datablock diff --git a/OgreMain/src/OgreHlmsJson.cpp b/OgreMain/src/OgreHlmsJson.cpp index 8ec9f72e709..8c13d370598 100644 --- a/OgreMain/src/OgreHlmsJson.cpp +++ b/OgreMain/src/OgreHlmsJson.cpp @@ -27,7 +27,6 @@ THE SOFTWARE. */ #include "OgreStableHeaders.h" -#include "OgreIdString.h" #if !OGRE_NO_JSON @@ -36,6 +35,7 @@ THE SOFTWARE. # include "OgreHlms.h" # include "OgreHlmsJsonCompute.h" # include "OgreHlmsManager.h" +# include "OgreIdString.h" # include "OgreLogManager.h" # include "OgreLwString.h" # include "OgreRenderSystem.h" @@ -1013,8 +1013,7 @@ namespace Ogre } //----------------------------------------------------------------------------------- void HlmsJson::saveMaterials( const Hlms *hlms, String &outString, - const String &additionalTextureExtension, - bool sortByName ) + const String &additionalTextureExtension, bool sortByName ) { outString += "{"; @@ -1115,8 +1114,8 @@ namespace Ogre Hlms::HlmsDatablockMap::const_iterator itor = datablockMap.begin(); Hlms::HlmsDatablockMap::const_iterator endt = datablockMap.end(); - - if (sortByName) + + if( sortByName ) { std::map sortedMap; while( itor != endt ) @@ -1130,13 +1129,14 @@ namespace Ogre while( itor2 != endt2 ) { - Hlms::HlmsDatablockMap::const_iterator itorFind = datablockMap.find(itor2->second); - if (itorFind != endt) + Hlms::HlmsDatablockMap::const_iterator itorFind = datablockMap.find( itor2->second ); + if( itorFind != endt ) { const HlmsDatablock *datablock = itorFind->second.datablock; if( datablock != defaultDatablock ) - saveDatablock( itorFind->second.name, datablock, outString, additionalTextureExtension ); + saveDatablock( itorFind->second.name, datablock, outString, + additionalTextureExtension ); } ++itor2; } @@ -1148,7 +1148,8 @@ namespace Ogre const HlmsDatablock *datablock = itor->second.datablock; if( datablock != defaultDatablock ) - saveDatablock( itor->second.name, datablock, outString, additionalTextureExtension ); + saveDatablock( itor->second.name, datablock, outString, + additionalTextureExtension ); ++itor; } } From 27a8328fac1f5c6a5d94703ac7f7c1be6d0c0246 Mon Sep 17 00:00:00 2001 From: cryham Date: Mon, 9 Oct 2023 20:20:07 +0200 Subject: [PATCH 073/124] Add sortByName to HlmsManager::saveMaterials --- OgreMain/include/OgreHlmsJson.h | 3 +++ OgreMain/include/OgreHlmsManager.h | 5 ++++- OgreMain/src/OgreHlmsManager.cpp | 6 ++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/OgreMain/include/OgreHlmsJson.h b/OgreMain/include/OgreHlmsJson.h index fbd4e83a139..7f15892477e 100644 --- a/OgreMain/include/OgreHlmsJson.h +++ b/OgreMain/include/OgreHlmsJson.h @@ -168,6 +168,9 @@ namespace Ogre if texture name is "mytex.png" and additionalTextureExtension = ".dds" then the actual texture saved will be "mytex.png.dds" Leave it blank if you don't know what to put + @param sortByName + Use true if output JSON should have materials sorted alphabetically + by name (case sensitive). */ void saveMaterials( const Hlms *hlms, String &outString, const String &additionalTextureExtension, bool sortByName = false ); diff --git a/OgreMain/include/OgreHlmsManager.h b/OgreMain/include/OgreHlmsManager.h index ff4e5a26aa5..ba055b8424f 100644 --- a/OgreMain/include/OgreHlmsManager.h +++ b/OgreMain/include/OgreHlmsManager.h @@ -354,9 +354,12 @@ namespace Ogre Hlms type. The type must be registered, otherwise it may crash. @param filename Valid file path. + @param sortByName + Use true if output JSON should have materials sorted alphabetically + by name (case sensitive). */ void saveMaterials( HlmsTypes hlmsType, const String &filename, HlmsJsonListener *listener, - const String &additionalTextureExtension ); + const String &additionalTextureExtension, bool sortByName = false ); /** Saves a specific Hlms material at the given file location. @param datablock diff --git a/OgreMain/src/OgreHlmsManager.cpp b/OgreMain/src/OgreHlmsManager.cpp index 17eee44f53a..3bab0f5975e 100644 --- a/OgreMain/src/OgreHlmsManager.cpp +++ b/OgreMain/src/OgreHlmsManager.cpp @@ -874,14 +874,16 @@ namespace Ogre //----------------------------------------------------------------------------------- void HlmsManager::saveMaterials( HlmsTypes hlmsType, const String &filename, HlmsJsonListener *listener, - const String &additionalTextureExtension ) + const String &additionalTextureExtension, + bool sortByName ) { assert( hlmsType != HLMS_MAX ); assert( hlmsType != HLMS_LOW_LEVEL ); String jsonString; HlmsJson hlmsJson( this, listener ); - hlmsJson.saveMaterials( mRegisteredHlms[hlmsType], jsonString, additionalTextureExtension ); + hlmsJson.saveMaterials( mRegisteredHlms[hlmsType], jsonString, + additionalTextureExtension, sortByName ); std::ofstream file( filename.c_str(), std::ios::binary | std::ios::out ); if( file.is_open() ) From a8087e58e5742a7b927ef2e2679de0c2b0647df2 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 9 Oct 2023 15:54:28 -0300 Subject: [PATCH 074/124] Fix clang format --- OgreMain/src/OgreHlmsManager.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OgreMain/src/OgreHlmsManager.cpp b/OgreMain/src/OgreHlmsManager.cpp index 3bab0f5975e..fa028a19113 100644 --- a/OgreMain/src/OgreHlmsManager.cpp +++ b/OgreMain/src/OgreHlmsManager.cpp @@ -874,16 +874,15 @@ namespace Ogre //----------------------------------------------------------------------------------- void HlmsManager::saveMaterials( HlmsTypes hlmsType, const String &filename, HlmsJsonListener *listener, - const String &additionalTextureExtension, - bool sortByName ) + const String &additionalTextureExtension, bool sortByName ) { assert( hlmsType != HLMS_MAX ); assert( hlmsType != HLMS_LOW_LEVEL ); String jsonString; HlmsJson hlmsJson( this, listener ); - hlmsJson.saveMaterials( mRegisteredHlms[hlmsType], jsonString, - additionalTextureExtension, sortByName ); + hlmsJson.saveMaterials( mRegisteredHlms[hlmsType], jsonString, additionalTextureExtension, + sortByName ); std::ofstream file( filename.c_str(), std::ios::binary | std::ios::out ); if( file.is_open() ) From e53f57096bf3306c1eb07cda4d0379a325ca5a34 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 10 Oct 2023 21:01:22 -0300 Subject: [PATCH 075/124] [VK] Fix wrong heap chosen on fallback code path w/ high memory pressure VulkanVaoManager would fallback to using less-desired memory pools if it runs out of memory in the best pools. The code for that path was flawed and could potentially chose the wrong heap. --- .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 2e5b73aecc7..7af8c7d8bef 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -982,9 +982,8 @@ namespace Ogre { // Found one! size_t defaultPoolSize = - std::min( mDefaultPoolSize[vboFlag], - memHeaps[memTypes[*itMemTypeIdx].heapIndex].size - - mUsedHeapMemory[heapIdx] ); + std::min( (VkDeviceSize)mDefaultPoolSize[vboFlag], + memHeaps[heapIdx].size - mUsedHeapMemory[heapIdx] ); poolSize = std::max( defaultPoolSize, sizeBytes ); break; } @@ -1010,14 +1009,13 @@ namespace Ogre { // We didn't try this memory type. Let's check if we can use it // TODO: See comment above about memHeaps[heapIdx].size - const size_t heapIdx = memTypes[memTypes[i].heapIndex].heapIndex; + const size_t heapIdx = memTypes[i].heapIndex; if( mUsedHeapMemory[heapIdx] + poolSize < memHeaps[heapIdx].size ) { // Found one! size_t defaultPoolSize = - std::min( mDefaultPoolSize[vboFlag], - memHeaps[memTypes[heapIdx].heapIndex].size - - mUsedHeapMemory[heapIdx] ); + std::min( (VkDeviceSize)mDefaultPoolSize[vboFlag], + memHeaps[heapIdx].size - mUsedHeapMemory[heapIdx] ); chosenMemoryTypeIdx = static_cast( i ); poolSize = std::max( defaultPoolSize, sizeBytes ); break; From 62acc724ae034e16372ceb28fbeaede24c7e0b77 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 12 Oct 2023 20:08:34 -0300 Subject: [PATCH 076/124] [D3D11] Fix rare error on old Drivers / GPUs Checking for FL >= 11.1 is not enough to use NO_OVERWRITE on SRV buffers. We must also check D3D11_FEATURE_D3D11_OPTIONS::MapNoOverwriteOnDynamicBufferSRV --- .../include/Vao/OgreD3D11VaoManager.h | 2 ++ .../src/Vao/OgreD3D11VaoManager.cpp | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/RenderSystems/Direct3D11/include/Vao/OgreD3D11VaoManager.h b/RenderSystems/Direct3D11/include/Vao/OgreD3D11VaoManager.h index 43296ced7c1..ac39d4f4dee 100644 --- a/RenderSystems/Direct3D11/include/Vao/OgreD3D11VaoManager.h +++ b/RenderSystems/Direct3D11/include/Vao/OgreD3D11VaoManager.h @@ -140,6 +140,8 @@ namespace Ogre VaoVec mVaos; uint32 mVaoNames; + bool mMapNoOverwriteOnDynamicBufferSRV; + D3D11Device &mDevice; D3D11SyncVec mFrameSyncVec; diff --git a/RenderSystems/Direct3D11/src/Vao/OgreD3D11VaoManager.cpp b/RenderSystems/Direct3D11/src/Vao/OgreD3D11VaoManager.cpp index a016141cd1d..39683faa533 100644 --- a/RenderSystems/Direct3D11/src/Vao/OgreD3D11VaoManager.cpp +++ b/RenderSystems/Direct3D11/src/Vao/OgreD3D11VaoManager.cpp @@ -81,6 +81,7 @@ namespace Ogre const NameValuePairList *params ) : VaoManager( params ), mVaoNames( 1 ), + mMapNoOverwriteOnDynamicBufferSRV( false ), mDevice( device ), mDrawId( 0 ), mD3D11RenderSystem( renderSystem ) @@ -132,12 +133,23 @@ namespace Ogre mTexBufferMaxSize = 128 * 1024 * 1024; mUavBufferMaxSize = mTexBufferMaxSize; - mReadOnlyIsTexBuffer = mD3D11RenderSystem->_getFeatureLevel() < D3D_FEATURE_LEVEL_11_0; + const D3D_FEATURE_LEVEL featureLevel = mD3D11RenderSystem->_getFeatureLevel(); + + mReadOnlyIsTexBuffer = featureLevel < D3D_FEATURE_LEVEL_11_0; mReadOnlyBufferMaxSize = mReadOnlyIsTexBuffer ? mTexBufferMaxSize : mUavBufferMaxSize; mSupportsPersistentMapping = false; mSupportsIndirectBuffers = _supportsIndirectBuffers; + if( featureLevel >= D3D_FEATURE_LEVEL_11_1 ) + { + D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {}; + HRESULT hr = + mDevice->CheckFeatureSupport( D3D11_FEATURE_D3D11_OPTIONS, &opts, sizeof( opts ) ); + if( SUCCEEDED( hr ) ) + mMapNoOverwriteOnDynamicBufferSRV = opts.MapNoOverwriteOnDynamicBufferSRV; + } + _createD3DResources(); } //----------------------------------------------------------------------------------- @@ -369,7 +381,7 @@ namespace Ogre { const BufferPackedTypes bufferPackedType = buffer->getBufferPackedType(); if( ( mSupportsIndirectBuffers || bufferPackedType != BP_TYPE_INDIRECT ) && - ( mD3D11RenderSystem->_getFeatureLevel() > D3D_FEATURE_LEVEL_11_0 || + ( mMapNoOverwriteOnDynamicBufferSRV || ( bufferPackedType != BP_TYPE_TEX && bufferPackedType != BP_TYPE_READONLY ) ) && bufferPackedType != BP_TYPE_CONST && bufferPackedType != BP_TYPE_UAV ) { @@ -1188,7 +1200,7 @@ namespace Ogre sizeBytes = alignToNextMultiple( sizeBytes, Math::lcm( alignment, bytesPerElement ) ); } - if( mD3D11RenderSystem->_getFeatureLevel() > D3D_FEATURE_LEVEL_11_0 ) + if( mMapNoOverwriteOnDynamicBufferSRV ) { // D3D11.1 supports NO_OVERWRITE on shader buffers, use the common pool size_t vboIdx = 0; @@ -1224,7 +1236,7 @@ namespace Ogre uint32( ( sizeBytes - requestedSize ) / bytesPerElement ), bufferType, initialData, keepAsShadow, this, bufferInterface, pixelFormat, false, mDevice ); - if( mD3D11RenderSystem->_getFeatureLevel() > D3D_FEATURE_LEVEL_11_0 ) + if( mMapNoOverwriteOnDynamicBufferSRV ) { if( initialData ) static_cast( bufferInterface )->_firstUpload( initialData ); @@ -1238,7 +1250,7 @@ namespace Ogre //----------------------------------------------------------------------------------- void D3D11VaoManager::destroyTexBufferImpl( TexBufferPacked *texBuffer ) { - if( mD3D11RenderSystem->_getFeatureLevel() > D3D_FEATURE_LEVEL_11_0 ) + if( mMapNoOverwriteOnDynamicBufferSRV ) { D3D11BufferInterface *bufferInterface = static_cast( texBuffer->getBufferInterface() ); @@ -1346,7 +1358,7 @@ namespace Ogre "D3D11VaoManager::createShaderBufferInterface" ); } - if( mD3D11RenderSystem->_getFeatureLevel() > D3D_FEATURE_LEVEL_11_0 ) + if( mMapNoOverwriteOnDynamicBufferSRV ) { D3D11DynamicBuffer *dynamicBuffer = 0; if( bufferType >= BT_DYNAMIC_DEFAULT ) @@ -1377,7 +1389,7 @@ namespace Ogre //----------------------------------------------------------------------------------- void D3D11VaoManager::destroyReadOnlyBufferImpl( ReadOnlyBufferPacked *readOnlyBuffer ) { - if( !mReadOnlyIsTexBuffer && mD3D11RenderSystem->_getFeatureLevel() > D3D_FEATURE_LEVEL_11_0 ) + if( !mReadOnlyIsTexBuffer && mMapNoOverwriteOnDynamicBufferSRV ) { OGRE_ASSERT_HIGH( dynamic_cast( readOnlyBuffer->getBufferInterface() ) ); From 6085437a355e7f4f292fc780d1f6ab2f2c899de9 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 12 Oct 2023 20:08:55 -0300 Subject: [PATCH 077/124] Fix cmd line parameter warning on older MSVC --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index efb7d9930b6..e7bb50c6dae 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 /Zc:cplusplus") + 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 651759e389fd55f8d0f1e4602aa3c776e67237ea Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 19 Oct 2023 12:09:21 -0300 Subject: [PATCH 078/124] [VK]Fix crash when RenderWindow is exclusively in the resolve texture Advanced users can use explicit MSAA and resolve directly into the RenderWindow. This is allowed, but would cause a crash on Vulkan if the swapchain is recreated. --- .../Vulkan/src/OgreVulkanRenderPassDescriptor.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp index 680edf32318..8f2222a9764 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderPassDescriptor.cpp @@ -690,8 +690,11 @@ namespace Ogre //----------------------------------------------------------------------------------- void VulkanRenderPassDescriptor::notifySwapchainCreated( VulkanWindow *window ) { - if( mNumColourEntries > 0 && mColour[0].texture->isRenderWindowSpecific() && - mColour[0].texture == window->getTexture() ) + if( mNumColourEntries > 0 && + ( ( mColour[0].texture && mColour[0].texture->isRenderWindowSpecific() && + mColour[0].texture == window->getTexture() ) || + ( mColour[0].resolveTexture && mColour[0].resolveTexture->isRenderWindowSpecific() && + mColour[0].resolveTexture == window->getTexture() ) ) ) { entriesModified( RenderPassDescriptor::All ); } @@ -699,8 +702,11 @@ namespace Ogre //----------------------------------------------------------------------------------- void VulkanRenderPassDescriptor::notifySwapchainDestroyed( VulkanWindow *window ) { - if( mNumColourEntries > 0 && mColour[0].texture->isRenderWindowSpecific() && - mColour[0].texture == window->getTexture() ) + if( mNumColourEntries > 0 && + ( ( mColour[0].texture && mColour[0].texture->isRenderWindowSpecific() && + mColour[0].texture == window->getTexture() ) || + ( mColour[0].resolveTexture && mColour[0].resolveTexture->isRenderWindowSpecific() && + mColour[0].resolveTexture == window->getTexture() ) ) ) { releaseFbo(); } From 491d37df15c048cd4757cd57d3091cec7c255fc5 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Wed, 1 Nov 2023 20:37:26 -0300 Subject: [PATCH 079/124] FindOgre missing functionality OGRE-Next pkg-config (#346) Fixes #346 --- CMake/Packages/FindOGRE.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMake/Packages/FindOGRE.cmake b/CMake/Packages/FindOGRE.cmake index 62f62aba65f..9e512371cbb 100644 --- a/CMake/Packages/FindOGRE.cmake +++ b/CMake/Packages/FindOGRE.cmake @@ -173,8 +173,9 @@ set(OGRE_PREFIX_WATCH ${OGRE_PREFIX_PATH} ${OGRE_PREFIX_SOURCE} ${OGRE_PREFIX_BU clear_if_changed(OGRE_PREFIX_WATCH ${OGRE_RESET_VARS}) if(NOT OGRE_STATIC) - # try to locate Ogre via pkg-config - use_pkgconfig(OGRE_PKGC "OGRE${OGRE_LIB_SUFFIX}") + # try to locate Ogre via pkg-config + use_pkgconfig(OGRE_PKGC "OGRE-Next${OGRE_LIB_SUFFIX}") + use_pkgconfig(OGRE_PKGC "OGRE${OGRE_LIB_SUFFIX}") # Set the framework search path for OS X set(OGRE_FRAMEWORK_SEARCH_PATH @@ -396,7 +397,7 @@ set(OGRE_COMPONENT_SEARCH_PATH_DBG macro(ogre_find_component COMPONENT HEADER PATH_HINTS) set(OGRE_${COMPONENT}_FIND_QUIETLY ${OGRE_FIND_QUIETLY}) findpkg_begin(OGRE_${COMPONENT}) - find_path(OGRE_${COMPONENT}_INCLUDE_DIR NAMES ${HEADER} HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${PATH_HINTS} ${COMPONENT} OGRE/${COMPONENT} ) + find_path(OGRE_${COMPONENT}_INCLUDE_DIR NAMES ${HEADER} HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${PATH_HINTS} ${COMPONENT} OGRE-Next/${COMPONENT} OGRE/${COMPONENT} ) set(OGRE_${COMPONENT}_LIBRARY_NAMES "OgreNext${COMPONENT}${OGRE_LIB_SUFFIX}" "Ogre${COMPONENT}${OGRE_LIB_SUFFIX}") get_debug_names(OGRE_${COMPONENT}_LIBRARY_NAMES) find_library(OGRE_${COMPONENT}_LIBRARY_REL NAMES ${OGRE_${COMPONENT}_LIBRARY_NAMES} HINTS ${OGRE_LIBRARY_DIR_REL} ${OGRE_FRAMEWORK_PATH} PATH_SUFFIXES "" "Release" "RelWithDebInfo" "MinSizeRel") From 6b12945905fbaae35a71569f04c22a55337cfab2 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 5 Nov 2023 13:14:07 -0300 Subject: [PATCH 080/124] Bump patch number --- OgreMain/include/OgrePrerequisites.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OgreMain/include/OgrePrerequisites.h b/OgreMain/include/OgrePrerequisites.h index 424506d1ed8..aa1f9b21575 100644 --- a/OgreMain/include/OgrePrerequisites.h +++ b/OgreMain/include/OgrePrerequisites.h @@ -65,7 +65,7 @@ namespace Ogre { // Define ogre version #define OGRE_VERSION_MAJOR 2 #define OGRE_VERSION_MINOR 3 - #define OGRE_VERSION_PATCH 2 + #define OGRE_VERSION_PATCH 3 #define OGRE_VERSION_SUFFIX "" #define OGRE_VERSION_NAME "Daedalus" From 97b877a791feae4ac9a2622b3a9b8edf56101ed9 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 5 Nov 2023 13:15:40 -0300 Subject: [PATCH 081/124] Fix Static build & D3D11 ignoring OGRE_USE_NEW_PROJECT_NAME (#420) Fixes #420 --- CMake/Templates/OGREStatic.pc.in | 8 ++++---- RenderSystems/Direct3D11/CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMake/Templates/OGREStatic.pc.in b/CMake/Templates/OGREStatic.pc.in index 39a748eede5..ee2d5cf51a8 100644 --- a/CMake/Templates/OGREStatic.pc.in +++ b/CMake/Templates/OGREStatic.pc.in @@ -2,12 +2,12 @@ prefix=@OGRE_PREFIX_PATH@ exec_prefix=${prefix} libdir=${prefix}/@OGRE_LIB_DIRECTORY@ includedir=${prefix}/include -plugindir=${libdir}/OGRE +plugindir=${libdir}/@OGRE_NEXT_PREFIX@ -Name: OGRE (static lib) +Name: @OGRE_NEXT_PREFIX@ (static lib) Description: Object-Oriented Graphics Rendering Engine Version: @OGRE_VERSION@ URL: http://www.ogre3d.org Requires: freetype2, zziplib, x11, xt, xaw7, gl -Libs: -L${libdir} -L${plugindir} -lOgreMain@OGRE_LIB_SUFFIX@ @OGRE_ADDITIONAL_LIBS@ -Cflags: -I${includedir} -I${includedir}/OGRE @OGRE_CFLAGS@ +Libs: -L${libdir} -L${plugindir} -l@OGRE_NEXT@Main@OGRE_LIB_SUFFIX@ @OGRE_ADDITIONAL_LIBS@ +Cflags: -I${includedir} -I${includedir}/@OGRE_NEXT_PREFIX@ @OGRE_CFLAGS@ diff --git a/RenderSystems/Direct3D11/CMakeLists.txt b/RenderSystems/Direct3D11/CMakeLists.txt index 8621d263182..8d7a468f656 100644 --- a/RenderSystems/Direct3D11/CMakeLists.txt +++ b/RenderSystems/Direct3D11/CMakeLists.txt @@ -65,4 +65,4 @@ if( OGRE_CONFIG_AMD_AGS ) endif() ogre_config_plugin(RenderSystem_Direct3D11) -install(FILES ${HEADER_FILES} DESTINATION include/OGRE/RenderSystems/Direct3D11) +install(FILES ${HEADER_FILES} DESTINATION include/${OGRE_NEXT_PREFIX}/RenderSystems/Direct3D11) From 8de8c1011ab3305b8d5deb9e37f9b5d3ed370a66 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 5 Nov 2023 18:20:58 -0300 Subject: [PATCH 082/124] CMake: rename FeatureSummary.cmake to avoid name clashes (#406) Fixes #406 --- CMake/{FeatureSummary.cmake => OgreFeatureSummary.cmake} | 0 CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename CMake/{FeatureSummary.cmake => OgreFeatureSummary.cmake} (100%) diff --git a/CMake/FeatureSummary.cmake b/CMake/OgreFeatureSummary.cmake similarity index 100% rename from CMake/FeatureSummary.cmake rename to CMake/OgreFeatureSummary.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index e7bb50c6dae..a79e2f9400d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -733,5 +733,5 @@ include(Packaging) # Show feature summary -include(FeatureSummary) +include(OgreFeatureSummary) From b607c127e1424eb7b1aac4615e1b9760753c5f03 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 5 Nov 2023 18:29:40 -0300 Subject: [PATCH 083/124] Fix build error on Static build --- Samples/2.0/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/2.0/CMakeLists.txt b/Samples/2.0/CMakeLists.txt index 81ba8d30583..aee58b48ade 100644 --- a/Samples/2.0/CMakeLists.txt +++ b/Samples/2.0/CMakeLists.txt @@ -206,7 +206,7 @@ if( OGRE_BUILD_SAMPLES2 AND NOT OGRE_BUILD_SAMPLES2_SKIP ) add_subdirectory(Tutorials/Tutorial_TextureBaking) add_subdirectory(Tutorials/TutorialUav01_Setup) add_subdirectory(Tutorials/TutorialUav02_Setup) - if( OGRE_BUILD_RENDERSYSTEM_VULKAN AND NOT ANDROID ) + if( OGRE_BUILD_RENDERSYSTEM_VULKAN AND NOT ANDROID AND NOT OGRE_STATIC ) add_subdirectory(Tutorials/Tutorial_VulkanExternal) endif() endif() From 8d4daeaf46d7d8f85f1833f17daedd7dac05daec Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 5 Nov 2023 18:38:38 -0300 Subject: [PATCH 084/124] Fix build error in static builds on Linux --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58317f2452b..2786e35884e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,6 +272,10 @@ set(OGRE_Paging_LIBRARIES ${OGRE_NEXT}Paging) set(OGRE_Terrain_LIBRARIES ${OGRE_NEXT}Terrain) set(OGRE_Volume_LIBRARIES ${OGRE_NEXT}Volume) +if( OGRE_STATIC AND UNIX AND NOT OGRE_CONFIG_UNIX_NO_X11 ) + set( OGRE_LIBRARIES ${OGRE_LIBRARIES} xcb xcb-randr ) +endif() + # Specify build paths set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OGRE_BINARY_DIR}/lib") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OGRE_BINARY_DIR}/lib") From 152b79d8cce9673dd2bde2e813112029dd00eb8c Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 6 Nov 2023 23:07:26 -0300 Subject: [PATCH 085/124] Update OgreNext logo for Windows --- OgreMain/src/WIN32/OgreWin32Resources.rc | 45 ++++++++++++----------- OgreMain/src/WIN32/ogre.ico | Bin 22798 -> 12014 bytes OgreMain/src/WIN32/ogrelogo.bmp | Bin 312966 -> 314662 bytes 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/OgreMain/src/WIN32/OgreWin32Resources.rc b/OgreMain/src/WIN32/OgreWin32Resources.rc index a20dfcff570..2f4b0bd5ab1 100644 --- a/OgreMain/src/WIN32/OgreWin32Resources.rc +++ b/OgreMain/src/WIN32/OgreWin32Resources.rc @@ -21,10 +21,8 @@ // Neutral resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1252) -#endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // @@ -33,6 +31,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDB_SPLASH BITMAP "ogrelogo.bmp" + ///////////////////////////////////////////////////////////////////////////// // // Icon @@ -41,18 +40,17 @@ IDB_SPLASH BITMAP "ogrelogo.bmp" // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_OGREICON ICON "ogre.ico" + #endif // Neutral resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources +// English (United Kingdom) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK #pragma code_page(1252) -#endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -93,30 +91,24 @@ BEGIN DEFPUSHBUTTON "&OK",IDOK,205,253,60,14 PUSHBUTTON "&Cancel",IDCANCEL,267,253,60,14 LTEXT "Rendering Subsystem:",IDC_OGRE_ICON,21,136,73,12 - COMBOBOX IDC_CBO_RENDERSYSTEM,95,134,219,57,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_CBO_RENDERSYSTEM,95,134,219,57,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Rendering System Options",IDC_OPTFRAME,5,152,322,101 - LISTBOX IDC_LST_OPTIONS,13,163,310,68,LBS_NOINTEGRALHEIGHT | - WS_VSCROLL | WS_TABSTOP + LISTBOX IDC_LST_OPTIONS,13,163,310,68,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP RTEXT "[Click On An Option]:",IDC_LBL_OPTION,14,237,125,11 - COMBOBOX IDC_CBO_OPTION,143,235,180,94,CBS_DROPDOWNLIST | - WS_DISABLED | WS_VSCROLL | WS_TABSTOP - CONTROL 106,IDC_OGRE_ICON,"Static",SS_BITMAP,0,0,327,140 + COMBOBOX IDC_CBO_OPTION,143,235,180,94,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP + CONTROL IDB_SPLASH,IDC_OGRE_ICON,"Static",SS_BITMAP,0,0,327,140 END -IDD_DLG_ERROR DIALOG 0, 0, 243, 178 +IDD_DLG_ERROR DIALOG 0, 0, 243, 178 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION "Error" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "&Close",IDOK,81,157,80,14 - LTEXT "The Ogre engine has encountered an error from which it cannot recover. The last message was:", - IDC_OGRE_ICON,7,7,229,19 + LTEXT "The Ogre engine has encountered an error from which it cannot recover. The last message was:",IDC_OGRE_ICON,7,7,229,19 LTEXT "",IDC_ERRMSG,17,29,209,84,SS_SUNKEN - LTEXT "If you cannot resolve this issue yourself, please report it through the web site at http://www.ogre3d.org.", - IDC_OGRE_ICON,7,118,229,19 - LTEXT "If you report the error, please include details of your hardware setup, and attach a copy of the 'ogre.log' file which you will find in the local folder.", - IDC_OGRE_ICON,7,138,229,17 + LTEXT "If you cannot resolve this issue yourself, please report it through the web site at http://www.ogre3d.org.",IDC_OGRE_ICON,7,118,229,19 + LTEXT "If you report the error, please include details of your hardware setup, and attach a copy of the 'ogre.log' file which you will find in the local folder.",IDC_OGRE_ICON,7,138,229,17 END @@ -126,7 +118,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO +GUIDELINES DESIGNINFO BEGIN IDD_DLG_CONFIG, DIALOG BEGIN @@ -144,7 +136,18 @@ BEGIN END #endif // APSTUDIO_INVOKED -#endif // English (U.K.) resources + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IDD_DLG_CONFIG AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +#endif // English (United Kingdom) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/OgreMain/src/WIN32/ogre.ico b/OgreMain/src/WIN32/ogre.ico index f8afd3736799b3b78ad4853293dc91334135f95a..54cb5381883cfd536ecc34f2cafc478c8a1ae09e 100644 GIT binary patch literal 12014 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 literal 312966 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%0A?St1hgy&0G}`T5DF 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 Date: Mon, 6 Nov 2023 23:18:41 -0300 Subject: [PATCH 086/124] Update OgreNext logo for macOS --- OgreMain/include/OSX/ogrelogo.png | Bin 31621 -> 25365 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/OgreMain/include/OSX/ogrelogo.png b/OgreMain/include/OSX/ogrelogo.png index a8d71f41624ee63211acdffc93059199b8b556f1..0ed28d66a03be19391f0bb48dae1e051a6932328 100644 GIT binary patch literal 25365 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 literal 31621 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 From 1ffbd3a7e807074c2347a0c0eab36c9964987878 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 10 Nov 2023 12:27:15 -0300 Subject: [PATCH 087/124] Use a better doxygen CSS template Also fix various doxgygen errors These are backports from 4.0 docs --- CMake/Templates/html.cfg.in | 420 +------ Docs/CMakeLists.txt | 12 +- Docs/doxygen-awesome.css | 2137 +++++++++++++++++++++++++++++++++++ Docs/ogre-logo-wetfloor.gif | Bin 7729 -> 0 bytes Docs/ogre-logo.gif | Bin 7633 -> 0 bytes Docs/ogre-logo.png | Bin 0 -> 2869 bytes Docs/ogre_style.css | 373 +----- Docs/src/apimainpage.md | 14 +- 8 files changed, 2174 insertions(+), 782 deletions(-) create mode 100644 Docs/doxygen-awesome.css delete mode 100644 Docs/ogre-logo-wetfloor.gif delete mode 100644 Docs/ogre-logo.gif create mode 100644 Docs/ogre-logo.png diff --git a/CMake/Templates/html.cfg.in b/CMake/Templates/html.cfg.in index 919f6a78f72..7002eb1fc15 100644 --- a/CMake/Templates/html.cfg.in +++ b/CMake/Templates/html.cfg.in @@ -45,7 +45,7 @@ PROJECT_BRIEF = "Object-Oriented Graphics Rendering Engine" # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. -PROJECT_LOGO = "${OGRE_SOURCE_DIR}/Docs/ogre-logo-wetfloor.gif" +PROJECT_LOGO = "${OGRE_SOURCE_DIR}/Docs/ogre-logo.png" # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -123,7 +123,7 @@ ALWAYS_DETAILED_SEC = YES # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. -INLINE_INHERITED_MEMB = YES +INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set @@ -251,7 +251,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = material=C++ compositor=C++ particle=C++ txt=Python glsl=C++ # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable @@ -419,7 +419,7 @@ HIDE_UNDOC_CLASSES = NO # If set to NO (the default) these declarations will be included in the # documentation. -HIDE_FRIEND_COMPOUNDS = NO +HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. @@ -721,13 +721,13 @@ EXCLUDE_PATTERNS = *UTF* \ # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = Ogre::AllocatedObject Ogre::ParamCommand # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = "${PROJECT_SOURCE_DIR}" # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp @@ -891,6 +891,8 @@ IGNORE_PREFIX = GENERATE_HTML = YES +GENERATE_LATEX = NO + # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. @@ -939,7 +941,7 @@ HTML_STYLESHEET = # robust against future updates. Doxygen will copy the style sheet file to # the output directory. -HTML_EXTRA_STYLESHEET = "${OGRE_SOURCE_DIR}/Docs/ogre_style.css" +HTML_EXTRA_STYLESHEET = "${OGRE_SOURCE_DIR}/Docs/doxygen-awesome.css" "${OGRE_SOURCE_DIR}/Docs/ogre_style.css" # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -998,157 +1000,6 @@ HTML_DYNAMIC_SECTIONS = YES HTML_INDEX_NUM_ENTRIES = 100 -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "OGRE-Next API Reference" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.ogre3d.documentation.api_1_9 - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.ogre3d.documentation.api_1_9 - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = org.ogre3d - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = OgreAPIReference_1.9.chm - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = api/ - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = YES - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = OgreAPIReference_1.9.qhc - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.ogre3d.documentation.api_1_9 - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = api/ - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.ogre3d.documentation.api_1_9 - # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the @@ -1229,7 +1080,7 @@ MATHJAX_FORMAT = HTML-CSS # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0 # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. @@ -1291,257 +1142,6 @@ SEARCHDATA_FILE = searchdata.xml EXTRA_SEARCH_MAPPINGS = -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- diff --git a/Docs/CMakeLists.txt b/Docs/CMakeLists.txt index 9c59f0da229..98e067fcaac 100644 --- a/Docs/CMakeLists.txt +++ b/Docs/CMakeLists.txt @@ -34,11 +34,15 @@ if(DOXYGEN_FOUND) ${OGRE_SOURCE_DIR}/Docs/src/SettingUpOgre/*.md ${OGRE_SOURCE_DIR}/Docs/src/UsingOgre/*.md ) - + + file(GLOB COMPONENTS ${OGRE_SOURCE_DIR}/Components/*/include) + file(GLOB PLUGINS ${OGRE_SOURCE_DIR}/PlugIns/*/include) + set(CMAKE_DOXYGEN_INPUT_LIST - \"${OGRE_SOURCE_DIR}/OgreMain - ${OGRE_SOURCE_DIR}/Components - ${OGRE_SOURCE_DIR}/Plugins + \"${OGRE_SOURCE_DIR}/OgreMain/include + ${COMPONENTS} + ${PLUGINS} + ${OGRE_SOURCE_DIR}/PlugIns ${OGRE_SOURCE_DIR}/RenderSystems ${OGRE_SOURCE_DIR}/Docs/src/apimainpage.md ${MANUAL}\") diff --git a/Docs/doxygen-awesome.css b/Docs/doxygen-awesome.css new file mode 100644 index 00000000000..6c1097cdd0b --- /dev/null +++ b/Docs/doxygen-awesome.css @@ -0,0 +1,2137 @@ +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 - 2022 jothepro + +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. + +*/ + +html { + /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ + --primary-color: #1779c4; + --primary-dark-color: #335c80; + --primary-light-color: #70b1e9; + + /* page base colors */ + --page-background-color: white; + --page-foreground-color: #2f4153; + --page-secondary-foreground-color: #637485; + + /* color for all separators on the website: hr, borders, ... */ + --separator-color: #dedede; + + /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ + --border-radius-large: 8px; + --border-radius-small: 4px; + --border-radius-medium: 6px; + + /* default spacings. Most compontest reference these values for spacing, to provide uniform spacing on the page. */ + --spacing-small: 5px; + --spacing-medium: 10px; + --spacing-large: 16px; + + /* default box shadow used for raising an element above the normal content. Used in dropdowns, Searchresult, ... */ + --box-shadow: 0 2px 8px 0 rgba(0,0,0,.075); + + --odd-color: rgba(0,0,0,.028); + + /* font-families. will affect all text on the website + * font-family: the normal font for text, headlines, menus + * font-family-monospace: used for preformatted text in memtitle, code, fragments + */ + --font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif; + --font-family-monospace: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + + /* font sizes */ + --page-font-size: 15.6px; + --navigation-font-size: 14.4px; + --code-font-size: 14px; /* affects code, fragment */ + --title-font-size: 22px; + + /* content text properties. These only affect the page content, not the navigation or any other ui elements */ + --content-line-height: 27px; + /* The content is centered and constraint in it's width. To make the content fill the whole page, set the variable to auto.*/ + --content-maxwidth: 1000px; + + /* colors for various content boxes: @warning, @note, @deprecated @bug */ + --warning-color: #f8d1cc; + --warning-color-dark: #b61825; + --warning-color-darker: #75070f; + --note-color: #faf3d8; + --note-color-dark: #f3a600; + --note-color-darker: #5f4204; + --todo-color: #e4f3ff; + --todo-color-dark: #1879C4; + --todo-color-darker: #274a5c; + --deprecated-color: #ecf0f3; + --deprecated-color-dark: #5b6269; + --deprecated-color-darker: #43454a; + --bug-color: #e4dafd; + --bug-color-dark: #5b2bdd; + --bug-color-darker: #2a0d72; + --invariant-color: #d8f1e3; + --invariant-color-dark: #44b86f; + --invariant-color-darker: #265532; + + /* blockquote colors */ + --blockquote-background: #f8f9fa; + --blockquote-foreground: #636568; + + /* table colors */ + --tablehead-background: #f1f1f1; + --tablehead-foreground: var(--page-foreground-color); + + /* menu-display: block | none + * Visibility of the top navigation on screens >= 768px. On smaller screen the menu is always visible. + * `GENERATE_TREEVIEW` MUST be enabled! + */ + --menu-display: block; + + --menu-focus-foreground: var(--page-background-color); + --menu-focus-background: var(--primary-color); + --menu-selected-background: rgba(0,0,0,.05); + + + --header-background: var(--page-background-color); + --header-foreground: var(--page-foreground-color); + + /* searchbar colors */ + --searchbar-background: var(--side-nav-background); + --searchbar-foreground: var(--page-foreground-color); + + /* searchbar size + * (`searchbar-width` is only applied on screens >= 768px. + * on smaller screens the searchbar will always fill the entire screen width) */ + --searchbar-height: 33px; + --searchbar-width: 210px; + --searchbar-border-radius: var(--searchbar-height); + + /* code block colors */ + --code-background: #f5f5f5; + --code-foreground: var(--page-foreground-color); + + /* fragment colors */ + --fragment-background: #F8F9FA; + --fragment-foreground: #37474F; + --fragment-keyword: #bb6bb2; + --fragment-keywordtype: #8258b3; + --fragment-keywordflow: #d67c3b; + --fragment-token: #438a59; + --fragment-comment: #969696; + --fragment-link: #5383d6; + --fragment-preprocessor: #46aaa5; + --fragment-linenumber-color: #797979; + --fragment-linenumber-background: #f4f4f5; + --fragment-linenumber-border: #e3e5e7; + --fragment-lineheight: 20px; + + /* sidebar navigation (treeview) colors */ + --side-nav-background: #fbfbfb; + --side-nav-foreground: var(--page-foreground-color); + --side-nav-arrow-opacity: 0; + --side-nav-arrow-hover-opacity: 0.9; + + --toc-background: var(--side-nav-background); + --toc-foreground: var(--side-nav-foreground); + + /* height of an item in any tree / collapsable table */ + --tree-item-height: 30px; + + --memname-font-size: var(--code-font-size); + --memtitle-font-size: 18px; + + --webkit-scrollbar-size: 7px; + --webkit-scrollbar-padding: 4px; + --webkit-scrollbar-color: var(--separator-color); +} + +@media screen and (max-width: 767px) { + html { + --page-font-size: 16px; + --navigation-font-size: 16px; + --code-font-size: 15px; /* affects code, fragment */ + --title-font-size: 22px; + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) { + color-scheme: dark; + + --primary-color: #1982d2; + --primary-dark-color: #86a9c4; + --primary-light-color: #4779ac; + + --box-shadow: 0 2px 8px 0 rgba(0,0,0,.35); + + --odd-color: rgba(100,100,100,.06); + + --menu-selected-background: rgba(0,0,0,.4); + + --page-background-color: #1C1D1F; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #38393b; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #222325; + --blockquote-foreground: #7e8c92; + + --warning-color: #2e1917; + --warning-color-dark: #ad2617; + --warning-color-darker: #f5b1aa; + --note-color: #3b2e04; + --note-color-dark: #f1b602; + --note-color-darker: #ceb670; + --todo-color: #163750; + --todo-color-dark: #1982D2; + --todo-color-darker: #dcf0fa; + --deprecated-color: #2e323b; + --deprecated-color-dark: #738396; + --deprecated-color-darker: #abb0bd; + --bug-color: #2a2536; + --bug-color-dark: #7661b3; + --bug-color-darker: #ae9ed6; + --invariant-color: #303a35; + --invariant-color-dark: #76ce96; + --invariant-color-darker: #cceed5; + + --fragment-background: #282c34; + --fragment-foreground: #dbe4eb; + --fragment-keyword: #cc99cd; + --fragment-keywordtype: #ab99cd; + --fragment-keywordflow: #e08000; + --fragment-token: #7ec699; + --fragment-comment: #999999; + --fragment-link: #98c0e3; + --fragment-preprocessor: #65cabe; + --fragment-linenumber-color: #cccccc; + --fragment-linenumber-background: #35393c; + --fragment-linenumber-border: #1f1f1f; + } +} + +/* dark mode variables are defined twice, to support both the dark-mode without and with doxygen-awesome-darkmode-toggle.js */ +html.dark-mode { + color-scheme: dark; + + --primary-color: #1982d2; + --primary-dark-color: #86a9c4; + --primary-light-color: #4779ac; + + --box-shadow: 0 2px 8px 0 rgba(0,0,0,.30); + + --odd-color: rgba(100,100,100,.06); + + --menu-selected-background: rgba(0,0,0,.4); + + --page-background-color: #1C1D1F; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #38393b; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #222325; + --blockquote-foreground: #7e8c92; + + --warning-color: #2e1917; + --warning-color-dark: #ad2617; + --warning-color-darker: #f5b1aa; + --note-color: #3b2e04; + --note-color-dark: #f1b602; + --note-color-darker: #ceb670; + --todo-color: #163750; + --todo-color-dark: #1982D2; + --todo-color-darker: #dcf0fa; + --deprecated-color: #2e323b; + --deprecated-color-dark: #738396; + --deprecated-color-darker: #abb0bd; + --bug-color: #2a2536; + --bug-color-dark: #7661b3; + --bug-color-darker: #ae9ed6; + --invariant-color: #303a35; + --invariant-color-dark: #76ce96; + --invariant-color-darker: #cceed5; + + --fragment-background: #282c34; + --fragment-foreground: #dbe4eb; + --fragment-keyword: #cc99cd; + --fragment-keywordtype: #ab99cd; + --fragment-keywordflow: #e08000; + --fragment-token: #7ec699; + --fragment-comment: #999999; + --fragment-link: #98c0e3; + --fragment-preprocessor: #65cabe; + --fragment-linenumber-color: #cccccc; + --fragment-linenumber-background: #35393c; + --fragment-linenumber-border: #1f1f1f; +} + +body { + color: var(--page-foreground-color); + background-color: var(--page-background-color); + font-size: var(--page-font-size); +} + +body, table, div, p, dl, #nav-tree .label, .title, .sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname, .SelectItem, #MSearchField, .navpath li.navelem a, .navpath li.navelem a:hover { + font-family: var(--font-family); +} + +h1, h2, h3, h4, h5 { + margin-top: .9em; + font-weight: 600; + line-height: initial; +} + +p, div, table, dl { + font-size: var(--page-font-size); +} + +a:link, a:visited, a:hover, a:focus, a:active { + color: var(--primary-color) !important; + font-weight: 500; +} + +a.anchor { + scroll-margin-top: var(--spacing-large); +} + +/* + Title and top navigation + */ + +#top { + background: var(--header-background); + border-bottom: 1px solid var(--separator-color); +} + +@media screen and (min-width: 768px) { + #top { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + } +} + +#main-nav { + flex-grow: 5; + padding: var(--spacing-small) var(--spacing-medium); +} + +#titlearea { + width: auto; + padding: var(--spacing-medium) var(--spacing-large); + background: none; + color: var(--header-foreground); + border-bottom: none; +} + +@media screen and (max-width: 767px) { + #titlearea { + padding-bottom: var(--spacing-small); + } +} + +#titlearea table tbody tr { + height: auto !important; +} + +#projectname { + font-size: var(--title-font-size); + font-weight: 600; +} + +#projectnumber { + font-family: inherit; + font-size: 60%; +} + +#projectbrief { + font-family: inherit; + font-size: 80%; +} + +#projectlogo { + vertical-align: middle; +} + +#projectlogo img { + max-height: calc(var(--title-font-size) * 2); + margin-right: var(--spacing-small); +} + +.sm-dox, .tabs, .tabs2, .tabs3 { + background: none; + padding: 0; +} + +.tabs, .tabs2, .tabs3 { + border-bottom: 1px solid var(--separator-color); + margin-bottom: -1px; +} + +@media screen and (max-width: 767px) { + .sm-dox a span.sub-arrow { + background: var(--code-background); + } + + #main-menu a.has-submenu span.sub-arrow { + color: var(--page-secondary-foreground-color); + border-radius: var(--border-radius-medium); + } + + #main-menu a.has-submenu:hover span.sub-arrow { + color: var(--page-foreground-color); + } +} + +@media screen and (min-width: 768px) { + .sm-dox li, .tablist li { + display: var(--menu-display); + } + + .sm-dox a span.sub-arrow { + border-color: var(--header-foreground) transparent transparent transparent; + } + + .sm-dox a:hover span.sub-arrow { + border-color: var(--menu-focus-foreground) transparent transparent transparent; + } + + .sm-dox ul a span.sub-arrow { + border-color: transparent transparent transparent var(--page-foreground-color); + } + + .sm-dox ul a:hover span.sub-arrow { + border-color: transparent transparent transparent var(--menu-focus-foreground); + } +} + +.sm-dox ul { + background: var(--page-background-color); + box-shadow: var(--box-shadow); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium) !important; + padding: var(--spacing-small); + animation: ease-out 150ms slideInMenu; +} + +@keyframes slideInMenu { + from { + opacity: 0; + transform: translate(0px, -2px); + } + + to { + opacity: 1; + transform: translate(0px, 0px); + } +} + +.sm-dox ul a { + color: var(--page-foreground-color) !important; + background: var(--page-background-color); + font-size: var(--navigation-font-size); +} + +.sm-dox>li>ul:after { + border-bottom-color: var(--page-background-color) !important; +} + +.sm-dox>li>ul:before { + border-bottom-color: var(--separator-color) !important; +} + +.sm-dox ul a:hover, .sm-dox ul a:active, .sm-dox ul a:focus { + font-size: var(--navigation-font-size) !important; + color: var(--menu-focus-foreground) !important; + text-shadow: none; + background-color: var(--menu-focus-background); + border-radius: var(--border-radius-small) !important; +} + +.sm-dox a, .sm-dox a:focus, .tablist li, .tablist li a, .tablist li.current a { + text-shadow: none; + background: transparent; + background-image: none !important; + color: var(--header-foreground) !important; + font-weight: normal; + font-size: var(--navigation-font-size); + border-radius: var(--border-radius-small) !important; +} + +.sm-dox a:focus { + outline: auto; +} + +.sm-dox a:hover, .sm-dox a:active, .tablist li a:hover { + text-shadow: none; + font-weight: normal; + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; + border-radius: var(--border-radius-small) !important; + font-size: var(--navigation-font-size); +} + +.tablist li.current { + border-radius: var(--border-radius-small); + background: var(--menu-selected-background); +} + +.tablist li { + margin: var(--spacing-small) 0 var(--spacing-small) var(--spacing-small); +} + +.tablist a { + padding: 0 var(--spacing-large); +} + + +/* + Search box + */ + +#MSearchBox { + height: var(--searchbar-height); + background: var(--searchbar-background); + border-radius: var(--searchbar-border-radius); + border: 1px solid var(--separator-color); + overflow: hidden; + width: var(--searchbar-width); + position: relative; + box-shadow: none; + display: block; + margin-top: 0; +} + +.left #MSearchSelect { + left: 0; + user-select: none; + padding-left: 8px; +} + +.left #MSearchSelect[src$=".png"] { + padding-left: 0 +} + +.SelectionMark { + user-select: none; +} + +.tabs .left #MSearchSelect { + padding-left: 0; +} + +.tabs #MSearchBox { + position: absolute; + right: var(--spacing-medium); +} + +@media screen and (max-width: 767px) { + .tabs #MSearchBox { + position: relative; + right: 0; + margin-left: var(--spacing-medium); + margin-top: 0; + } +} + +#MSearchSelectWindow, #MSearchResultsWindow { + z-index: 9999; +} + +#MSearchBox.MSearchBoxActive { + border-color: var(--primary-color); + box-shadow: inset 0 0 0 1px var(--primary-color); +} + +#main-menu > li:last-child { + margin-right: 0; +} + +@media screen and (max-width: 767px) { + #main-menu > li:last-child { + height: 50px; + } +} + +#MSearchField { + font-size: var(--navigation-font-size); + height: calc(var(--searchbar-height) - 2px); + background: transparent; + width: calc(var(--searchbar-width) - 64px); +} + +.MSearchBoxActive #MSearchField { + color: var(--searchbar-foreground); +} + +#MSearchSelect { + top: calc(calc(var(--searchbar-height) / 2) - 11px); +} + +#MSearchBox span.left, #MSearchBox span.right { + background: none; + background-image: none; +} + +#MSearchBox span.right { + padding-top: calc(calc(var(--searchbar-height) / 2) - 12px); + position: absolute; + right: var(--spacing-small); +} + +.tabs #MSearchBox span.right { + top: calc(calc(var(--searchbar-height) / 2) - 12px); +} + +@keyframes slideInSearchResults { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } +} + +#MSearchResultsWindow { + left: auto !important; + right: var(--spacing-medium); + border-radius: var(--border-radius-large); + border: 1px solid var(--separator-color); + transform: translate(0, 20px); + box-shadow: var(--box-shadow); + animation: ease-out 280ms slideInSearchResults; + background: var(--page-background-color); +} + +iframe#MSearchResults { + margin: 4px; +} + +iframe { + color-scheme: normal; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) iframe#MSearchResults { + filter: invert() hue-rotate(180deg); + } +} + +html.dark-mode iframe#MSearchResults { + filter: invert() hue-rotate(180deg); +} + +#MSearchSelectWindow { + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + background: var(--page-background-color); + padding-top: var(--spacing-small); + padding-bottom: var(--spacing-small); +} + +#MSearchSelectWindow a.SelectItem { + font-size: var(--navigation-font-size); + line-height: var(--content-line-height); + margin: 0 var(--spacing-small); + border-radius: var(--border-radius-small); + color: var(--page-foreground-color) !important; + font-weight: normal; +} + +#MSearchSelectWindow a.SelectItem:hover { + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; +} + +@media screen and (max-width: 767px) { + #MSearchBox { + margin-top: var(--spacing-medium); + margin-bottom: var(--spacing-medium); + width: calc(100vw - 30px); + } + + #main-menu > li:last-child { + float: none !important; + } + + #MSearchField { + width: calc(100vw - 110px); + } + + @keyframes slideInSearchResultsMobile { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } + } + + #MSearchResultsWindow { + left: var(--spacing-medium) !important; + right: var(--spacing-medium); + overflow: auto; + transform: translate(0, 20px); + animation: ease-out 280ms slideInSearchResultsMobile; + } + + /* + * Overwrites for fixing the searchbox on mobile in doxygen 1.9.2 + */ + label.main-menu-btn ~ #searchBoxPos1 { + top: 3px !important; + right: 6px !important; + left: 45px; + display: flex; + } + + label.main-menu-btn ~ #searchBoxPos1 > #MSearchBox { + margin-top: 0; + margin-bottom: 0; + flex-grow: 2; + float: left; + } +} + +/* + Tree view + */ + +#side-nav { + padding: 0 !important; + background: var(--side-nav-background); +} + +@media screen and (max-width: 767px) { + #side-nav { + display: none; + } + + #doc-content { + margin-left: 0 !important; + } +} + +#nav-tree { + background: transparent; +} + +#nav-tree .label { + font-size: var(--navigation-font-size); +} + +#nav-tree .item { + height: var(--tree-item-height); + line-height: var(--tree-item-height); +} + +#nav-sync { + bottom: 12px; + right: 12px; + top: auto !important; + user-select: none; +} + +#nav-tree .selected { + text-shadow: none; + background-image: none; + background-color: transparent; + position: relative; +} + +#nav-tree .selected::after { + content: ""; + position: absolute; + top: 1px; + bottom: 1px; + left: 0; + width: 4px; + border-radius: 0 var(--border-radius-small) var(--border-radius-small) 0; + background: var(--primary-color); +} + + +#nav-tree a { + color: var(--side-nav-foreground) !important; + font-weight: normal; +} + +#nav-tree a:focus { + outline-style: auto; +} + +#nav-tree .arrow { + opacity: var(--side-nav-arrow-opacity); +} + +.arrow { + color: inherit; + cursor: pointer; + font-size: 45%; + vertical-align: middle; + margin-right: 2px; + font-family: serif; + height: auto; + text-align: right; +} + +#nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow { + opacity: var(--side-nav-arrow-hover-opacity); +} + +#nav-tree .selected a { + color: var(--primary-color) !important; + font-weight: bolder; + font-weight: 600; +} + +.ui-resizable-e { + background: var(--separator-color); + width: 1px; +} + +/* + Contents + */ + +div.header { + border-bottom: 1px solid var(--separator-color); + background-color: var(--page-background-color); + background-image: none; +} + +div.contents, div.header .title, div.header .summary { + max-width: var(--content-maxwidth); +} + +div.contents, div.header .title { + line-height: initial; + margin: calc(var(--spacing-medium) + .2em) auto var(--spacing-medium) auto; +} + +div.header .summary { + margin: var(--spacing-medium) auto 0 auto; +} + +div.headertitle { + padding: 0; +} + +div.header .title { + font-weight: 600; + font-size: 210%; + padding: var(--spacing-medium) var(--spacing-large); + word-break: break-word; +} + +div.header .summary { + width: auto; + display: block; + float: none; + padding: 0 var(--spacing-large); +} + +td.memSeparator { + border-color: var(--separator-color); +} + +span.mlabel { + background: var(--primary-color); + border: none; + padding: 4px 9px; + border-radius: 12px; + margin-right: var(--spacing-medium); +} + +span.mlabel:last-of-type { + margin-right: 2px; +} + +div.contents { + padding: 0 var(--spacing-large); +} + +div.contents p, div.contents li { + line-height: var(--content-line-height); +} + +div.contents div.dyncontent { + margin: var(--spacing-medium) 0; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) div.contents div.dyncontent img, + html:not(.light-mode) div.contents center img, + html:not(.light-mode) div.contents table img, + html:not(.light-mode) div.contents div.dyncontent iframe, + html:not(.light-mode) div.contents center iframe, + html:not(.light-mode) div.contents table iframe { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode div.contents div.dyncontent img, +html.dark-mode div.contents center img, +html.dark-mode div.contents table img, +html.dark-mode div.contents div.dyncontent iframe, +html.dark-mode div.contents center iframe, +html.dark-mode div.contents table iframe { + filter: hue-rotate(180deg) invert(); +} + +h2.groupheader { + border-bottom: 0px; + color: var(--page-foreground-color); + box-shadow: + 100px 0 var(--page-background-color), + -100px 0 var(--page-background-color), + 100px 0.75px var(--separator-color), + -100px 0.75px var(--separator-color), + 500px 0 var(--page-background-color), + -500px 0 var(--page-background-color), + 500px 0.75px var(--separator-color), + -500px 0.75px var(--separator-color), + 1500px 0 var(--page-background-color), + -1500px 0 var(--page-background-color), + 1500px 0.75px var(--separator-color), + -1500px 0.75px var(--separator-color), + 2000px 0 var(--page-background-color), + -2000px 0 var(--page-background-color), + 2000px 0.75px var(--separator-color), + -2000px 0.75px var(--separator-color); +} + +blockquote { + margin: 0 var(--spacing-medium) 0 var(--spacing-medium); + padding: var(--spacing-small) var(--spacing-large); + background: var(--blockquote-background); + color: var(--blockquote-foreground); + border-left: 0; + overflow: visible; + border-radius: var(--border-radius-medium); + overflow: visible; + position: relative; +} + +blockquote::before, blockquote::after { + font-weight: bold; + font-family: serif; + font-size: 360%; + opacity: .15; + position: absolute; +} + +blockquote::before { + content: "“"; + left: -10px; + top: 4px; +} + +blockquote::after { + content: "”"; + right: -8px; + bottom: -25px; +} + +blockquote p { + margin: var(--spacing-small) 0 var(--spacing-medium) 0; +} +.paramname { + font-weight: 600; + color: var(--primary-dark-color); +} + +.paramname > code { + border: 0; +} + +table.params .paramname { + font-weight: 600; + font-family: var(--font-family-monospace); + font-size: var(--code-font-size); + padding-right: var(--spacing-small); +} + +.glow { + text-shadow: 0 0 15px var(--primary-light-color) !important; +} + +.alphachar a { + color: var(--page-foreground-color); +} + +/* + Table of Contents + */ + +div.toc { + z-index: 10; + position: relative; + background-color: var(--toc-background); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + padding: 0 var(--spacing-large); + margin: 0 0 var(--spacing-medium) var(--spacing-medium); +} + +div.toc h3 { + color: var(--toc-foreground); + font-size: var(--navigation-font-size); + margin: var(--spacing-large) 0; +} + +div.toc li { + font-size: var(--navigation-font-size); + padding: 0; + background: none; +} + +div.toc li:before { + content: '↓'; + font-weight: 800; + font-family: var(--font-family); + margin-right: var(--spacing-small); + color: var(--toc-foreground); + opacity: .4; +} + +div.toc ul li.level1 { + margin: 0; +} + +div.toc ul li.level2, div.toc ul li.level3 { + margin-top: 0; +} + + +@media screen and (max-width: 767px) { + div.toc { + float: none; + width: auto; + margin: 0 0 var(--spacing-medium) 0; + } +} + +/* + Code & Fragments + */ + +code, div.fragment, pre.fragment { + border-radius: var(--border-radius-small); + border: 1px solid var(--separator-color); + overflow: hidden; +} + +code { + display: inline; + background: var(--code-background); + color: var(--code-foreground); + padding: 2px 6px; + word-break: break-word; +} + +div.fragment, pre.fragment { + margin: var(--spacing-medium) 0; + padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large); + background: var(--fragment-background); + color: var(--fragment-foreground); + overflow-x: auto; +} + +@media screen and (max-width: 767px) { + div.fragment, pre.fragment { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right: 0; + } + + .contents > div.fragment, + .textblock > div.fragment, + .textblock > pre.fragment, + .contents > .doxygen-awesome-fragment-wrapper > div.fragment, + .textblock > .doxygen-awesome-fragment-wrapper > div.fragment, + .textblock > .doxygen-awesome-fragment-wrapper > pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + border-radius: 0; + border-left: 0; + } + + .textblock li > .fragment, + .textblock li > .doxygen-awesome-fragment-wrapper > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + } + + .memdoc li > .fragment, + .memdoc li > .doxygen-awesome-fragment-wrapper > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + } + + .textblock ul, .memdoc ul { + overflow: initial; + } + + .memdoc > div.fragment, + .memdoc > pre.fragment, + dl dd > div.fragment, + dl dd pre.fragment, + .memdoc > .doxygen-awesome-fragment-wrapper > div.fragment, + .memdoc > .doxygen-awesome-fragment-wrapper > pre.fragment, + dl dd > .doxygen-awesome-fragment-wrapper > div.fragment, + dl dd .doxygen-awesome-fragment-wrapper > pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + border-radius: 0; + border-left: 0; + } +} + +code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span { + font-family: var(--font-family-monospace); + font-size: var(--code-font-size) !important; +} + +div.line:after { + margin-right: var(--spacing-medium); +} + +div.fragment .line, pre.fragment { + white-space: pre; + word-wrap: initial; + line-height: var(--fragment-lineheight); +} + +div.fragment span.keyword { + color: var(--fragment-keyword); +} + +div.fragment span.keywordtype { + color: var(--fragment-keywordtype); +} + +div.fragment span.keywordflow { + color: var(--fragment-keywordflow); +} + +div.fragment span.stringliteral { + color: var(--fragment-token) +} + +div.fragment span.comment { + color: var(--fragment-comment); +} + +div.fragment a.code { + color: var(--fragment-link) !important; +} + +div.fragment span.preprocessor { + color: var(--fragment-preprocessor); +} + +div.fragment span.lineno { + display: inline-block; + width: 27px; + border-right: none; + background: var(--fragment-linenumber-background); + color: var(--fragment-linenumber-color); +} + +div.fragment span.lineno a { + background: none; + color: var(--fragment-link) !important; +} + +div.fragment .line:first-child .lineno { + box-shadow: -999999px 0px 0 999999px var(--fragment-linenumber-background), -999998px 0px 0 999999px var(--fragment-linenumber-border); +} + +/* + dl warning, attention, note, deprecated, bug, ... + */ + +dl.bug dt a, dl.deprecated dt a, dl.todo dt a { + font-weight: bold !important; +} + +dl.warning, dl.attention, dl.note, dl.deprecated, dl.bug, dl.invariant, dl.pre, dl.todo, dl.remark { + padding: var(--spacing-medium); + margin: var(--spacing-medium) 0; + color: var(--page-background-color); + overflow: hidden; + margin-left: 0; + border-radius: var(--border-radius-small); +} + +dl.section dd { + margin-bottom: 2px; +} + +dl.warning, dl.attention { + background: var(--warning-color); + border-left: 8px solid var(--warning-color-dark); + color: var(--warning-color-darker); +} + +dl.warning dt, dl.attention dt { + color: var(--warning-color-dark); +} + +dl.note, dl.remark { + background: var(--note-color); + border-left: 8px solid var(--note-color-dark); + color: var(--note-color-darker); +} + +dl.note dt, dl.remark dt { + color: var(--note-color-dark); +} + +dl.todo { + background: var(--todo-color); + border-left: 8px solid var(--todo-color-dark); + color: var(--todo-color-darker); +} + +dl.todo dt { + color: var(--todo-color-dark); +} + +dl.bug dt a { + color: var(--todo-color-dark) !important; +} + +dl.bug { + background: var(--bug-color); + border-left: 8px solid var(--bug-color-dark); + color: var(--bug-color-darker); +} + +dl.bug dt a { + color: var(--bug-color-dark) !important; +} + +dl.deprecated { + background: var(--deprecated-color); + border-left: 8px solid var(--deprecated-color-dark); + color: var(--deprecated-color-darker); +} + +dl.deprecated dt a { + color: var(--deprecated-color-dark) !important; +} + +dl.section dd, dl.bug dd, dl.deprecated dd, dl.todo dd { + margin-inline-start: 0px; +} + +dl.invariant, dl.pre { + background: var(--invariant-color); + border-left: 8px solid var(--invariant-color-dark); + color: var(--invariant-color-darker); +} + +dl.invariant dt, dl.pre dt { + color: var(--invariant-color-dark); +} + +/* + memitem + */ + +div.memdoc, div.memproto, h2.memtitle { + box-shadow: none; + background-image: none; + border: none; +} + +div.memdoc { + padding: 0 var(--spacing-medium); + background: var(--page-background-color); +} + +h2.memtitle, div.memitem { + border: 1px solid var(--separator-color); + box-shadow: var(--box-shadow); +} + +h2.memtitle { + box-shadow: 0px var(--spacing-medium) 0 -1px var(--fragment-background), var(--box-shadow); +} + +div.memitem { + transition: none; +} + +div.memproto, h2.memtitle { + background: var(--fragment-background); + text-shadow: none; +} + +h2.memtitle { + font-weight: 500; + font-size: var(--memtitle-font-size); + font-family: var(--font-family-monospace); + border-bottom: none; + border-top-left-radius: var(--border-radius-medium); + border-top-right-radius: var(--border-radius-medium); + word-break: break-all; + position: relative; +} + +h2.memtitle:after { + content: ""; + display: block; + background: var(--fragment-background); + height: var(--spacing-medium); + bottom: calc(0px - var(--spacing-medium)); + left: 0; + right: -14px; + position: absolute; + border-top-right-radius: var(--border-radius-medium); +} + +h2.memtitle > span.permalink { + font-size: inherit; +} + +h2.memtitle > span.permalink > a { + text-decoration: none; + padding-left: 3px; + margin-right: -4px; + user-select: none; + display: inline-block; + margin-top: -6px; +} + +h2.memtitle > span.permalink > a:hover { + color: var(--primary-dark-color) !important; +} + +a:target + h2.memtitle, a:target + h2.memtitle + div.memitem { + border-color: var(--primary-light-color); +} + +div.memitem { + border-top-right-radius: var(--border-radius-medium); + border-bottom-right-radius: var(--border-radius-medium); + border-bottom-left-radius: var(--border-radius-medium); + overflow: hidden; + display: block !important; +} + +div.memdoc { + border-radius: 0; +} + +div.memproto { + border-radius: 0 var(--border-radius-small) 0 0; + overflow: auto; + border-bottom: 1px solid var(--separator-color); + padding: var(--spacing-medium); + margin-bottom: -1px; +} + +div.memtitle { + border-top-right-radius: var(--border-radius-medium); + border-top-left-radius: var(--border-radius-medium); +} + +div.memproto table.memname { + font-family: var(--font-family-monospace); + color: var(--page-foreground-color); + font-size: var(--memname-font-size); +} + +div.memproto div.memtemplate { + font-family: var(--font-family-monospace); + color: var(--primary-dark-color); + font-size: var(--memname-font-size); + margin-left: 2px; +} + +table.mlabels, table.mlabels > tbody { + display: block; +} + +td.mlabels-left { + width: auto; +} + +td.mlabels-right { + margin-top: 3px; + position: sticky; + left: 0; +} + +table.mlabels > tbody > tr:first-child { + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.memname, .memitem span.mlabels { + margin: 0 +} + +/* + reflist + */ + +dl.reflist { + box-shadow: var(--box-shadow); + border-radius: var(--border-radius-medium); + border: 1px solid var(--separator-color); + overflow: hidden; + padding: 0; +} + + +dl.reflist dt, dl.reflist dd { + box-shadow: none; + text-shadow: none; + background-image: none; + border: none; + padding: 12px; +} + + +dl.reflist dt { + font-weight: 500; + border-radius: 0; + background: var(--code-background); + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color) +} + + +dl.reflist dd { + background: none; +} + +/* + Table + */ + +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) { + display: inline-block; + max-width: 100%; + } + +.contents > table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname):not(.classindex) { + margin-left: calc(0px - var(--spacing-large)); + margin-right: calc(0px - var(--spacing-large)); + max-width: calc(100% + 2 * var(--spacing-large)); +} + +table.markdownTable, table.fieldtable { + border: none; + margin: var(--spacing-medium) 0; + box-shadow: 0 0 0 1px var(--separator-color); + border-radius: var(--border-radius-small); +} + +table.fieldtable { + width: 100%; +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background: var(--tablehead-background); + color: var(--tablehead-foreground); + font-weight: 600; + font-size: var(--page-font-size); +} + +th.markdownTableHeadLeft:first-child, th.markdownTableHeadRight:first-child, th.markdownTableHeadCenter:first-child, th.markdownTableHeadNone:first-child { + border-top-left-radius: var(--border-radius-small); +} + +th.markdownTableHeadLeft:last-child, th.markdownTableHeadRight:last-child, th.markdownTableHeadCenter:last-child, th.markdownTableHeadNone:last-child { + border-top-right-radius: var(--border-radius-small); +} + +table.markdownTable td, table.markdownTable th, table.fieldtable dt { + border: none; + border-right: 1px solid var(--separator-color); + padding: var(--spacing-small) var(--spacing-medium); +} + +table.markdownTable td:last-child, table.markdownTable th:last-child, table.fieldtable dt:last-child { + border: none; +} + +table.markdownTable tr, table.markdownTable tr { + border-bottom: 1px solid var(--separator-color); +} + +table.markdownTable tr:last-child, table.markdownTable tr:last-child { + border-bottom: none; +} + +table.fieldtable th { + font-size: var(--page-font-size); + font-weight: 600; + background-image: none; + background-color: var(--tablehead-background); + color: var(--tablehead-foreground); + border-bottom: 1px solid var(--separator-color); +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + border-bottom: 1px solid var(--separator-color); + border-right: 1px solid var(--separator-color); +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--separator-color); +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: var(--primary-light-color); + box-shadow: 0 0 15px var(--primary-light-color); +} + +table.memberdecls { + display: block; +} + +table.memberdecls tr[class^='memitem'] { + font-family: var(--font-family-monospace); + font-size: var(--code-font-size); +} + +table.memberdecls tr[class^='memitem'] .memTemplParams { + font-family: var(--font-family-monospace); + font-size: var(--code-font-size); + color: var(--primary-dark-color); +} + +table.memberdecls .memItemLeft, +table.memberdecls .memItemRight, +table.memberdecls .memTemplItemLeft, +table.memberdecls .memTemplItemRight, +table.memberdecls .memTemplParams { + transition: none; + padding-top: var(--spacing-small); + padding-bottom: var(--spacing-small); + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + background-color: var(--fragment-background); +} + +table.memberdecls .memTemplItemLeft, +table.memberdecls .memTemplItemRight { + padding-top: 2px; +} + +table.memberdecls .memTemplParams { + border-bottom: 0; + border-left: 1px solid var(--separator-color); + border-right: 1px solid var(--separator-color); + border-radius: var(--border-radius-small) var(--border-radius-small) 0 0; + padding-bottom: 0; +} + +table.memberdecls .memTemplItemLeft { + border-radius: 0 0 0 var(--border-radius-small); + border-left: 1px solid var(--separator-color); + border-top: 0; +} + +table.memberdecls .memTemplItemRight { + border-radius: 0 0 var(--border-radius-small) 0; + border-right: 1px solid var(--separator-color); + border-top: 0; +} + +table.memberdecls .memItemLeft { + border-radius: var(--border-radius-small) 0 0 var(--border-radius-small); + border-left: 1px solid var(--separator-color); + padding-left: var(--spacing-medium); + padding-right: 0; +} + +table.memberdecls .memItemRight { + border-radius: 0 var(--border-radius-small) var(--border-radius-small) 0; + border-right: 1px solid var(--separator-color); + padding-right: var(--spacing-medium); + padding-left: 0; + +} + +table.memberdecls .mdescLeft, table.memberdecls .mdescRight { + background: none; + color: var(--page-foreground-color); + padding: var(--spacing-small) 0; +} + +table.memberdecls .memSeparator { + background: var(--page-background-color); + height: var(--spacing-large); + border: 0; + transition: none; +} + +table.memberdecls .groupheader { + margin-bottom: var(--spacing-large); +} + +table.memberdecls .inherit_header td { + padding: 0 0 var(--spacing-medium) 0; + text-indent: -12px; + line-height: 1.5em; + color: var(--page-secondary-foreground-color); +} + +@media screen and (max-width: 767px) { + + table.memberdecls .memItemLeft, + table.memberdecls .memItemRight, + table.memberdecls .mdescLeft, + table.memberdecls .mdescRight, + table.memberdecls .memTemplItemLeft, + table.memberdecls .memTemplItemRight, + table.memberdecls .memTemplParams { + display: block; + text-align: left; + padding-left: var(--spacing-large); + margin: 0 calc(0px - var(--spacing-large)) 0 calc(0px - var(--spacing-large)); + border-right: none; + border-left: none; + border-radius: 0; + } + + table.memberdecls .memItemLeft, + table.memberdecls .mdescLeft, + table.memberdecls .memTemplItemLeft { + border-bottom: 0; + padding-bottom: 0; + } + + table.memberdecls .memTemplItemLeft { + padding-top: 0; + } + + table.memberdecls .mdescLeft { + margin-top: calc(0px - var(--page-font-size)); + } + + table.memberdecls .memItemRight, + table.memberdecls .mdescRight, + table.memberdecls .memTemplItemRight { + border-top: 0; + padding-top: 0; + padding-right: var(--spacing-large); + overflow-x: auto; + } + + table.memberdecls tr[class^='memitem']:not(.inherit) { + display: block; + width: calc(100vw - 2 * var(--spacing-large)); + } + + table.memberdecls .mdescRight { + color: var(--page-foreground-color); + } + + table.memberdecls tr.inherit { + visibility: hidden; + } + + table.memberdecls tr[style="display: table-row;"] { + display: block !important; + visibility: visible; + width: calc(100vw - 2 * var(--spacing-large)); + animation: fade .5s; + } + + @keyframes fade { + 0% { + opacity: 0; + max-height: 0; + } + + 100% { + opacity: 1; + max-height: 200px; + } + } +} + + +/* + Horizontal Rule + */ + +hr { + margin-top: var(--spacing-large); + margin-bottom: var(--spacing-large); + height: 1px; + background-color: var(--separator-color); + border: 0; +} + +.contents hr { + box-shadow: 100px 0 0 var(--separator-color), + -100px 0 0 var(--separator-color), + 500px 0 0 var(--separator-color), + -500px 0 0 var(--separator-color), + 1500px 0 0 var(--separator-color), + -1500px 0 0 var(--separator-color), + 2000px 0 0 var(--separator-color), + -2000px 0 0 var(--separator-color); +} + +.contents img, .contents .center, .contents center, .contents div.image object { + max-width: 100%; + overflow: auto; +} + +@media screen and (max-width: 767px) { + .contents .dyncontent > .center, .contents > center { + margin-left: calc(0px - var(--spacing-large)); + margin-right: calc(0px - var(--spacing-large)); + max-width: calc(100% + 2 * var(--spacing-large)); + } +} + +/* + Directories + */ +div.directory { + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + width: auto; +} + +table.directory { + font-family: var(--font-family); + font-size: var(--page-font-size); + font-weight: normal; + width: 100%; +} + +table.directory td.entry { + padding: var(--spacing-small); +} + +table.directory td.desc { + min-width: 250px; +} + +table.directory tr.even { + background-color: var(--odd-color); +} + +.icona { + width: auto; + height: auto; + margin: 0 var(--spacing-small); +} + +.icon { + background: var(--primary-color); + width: 18px; + height: 18px; + line-height: 18px; +} + +.iconfopen, .icondoc, .iconfclosed { + background-position: center; + margin-bottom: 0; +} + +.icondoc { + filter: saturate(0.2); +} + +@media screen and (max-width: 767px) { + div.directory { + margin-left: calc(0px - var(--spacing-large)); + margin-right: calc(0px - var(--spacing-large)); + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) .iconfopen, html:not(.light-mode) .iconfclosed { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode .iconfopen, html.dark-mode .iconfclosed { + filter: hue-rotate(180deg) invert(); +} + +/* + Class list + */ + +.classindex dl.odd { + background: var(--odd-color); + border-radius: var(--border-radius-small); +} + +/* + Class Index Doxygen 1.8 +*/ + +table.classindex { + margin-left: 0; + margin-right: 0; + width: 100%; +} + +table.classindex table div.ah { + background-image: none; + background-color: initial; + border-color: var(--separator-color); + color: var(--page-foreground-color); + box-shadow: var(--box-shadow); + border-radius: var(--border-radius-large); + padding: var(--spacing-small); +} + +div.qindex { + background-color: var(--odd-color); + border-radius: var(--border-radius-small); + border: 1px solid var(--separator-color); + padding: var(--spacing-small) 0; +} + +/* + Footer and nav-path + */ + +#nav-path { + width: 100%; +} + +#nav-path ul { + background-image: none; + background: var(--page-background-color); + border: none; + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + border-bottom: 0; + box-shadow: 0 0.75px 0 var(--separator-color); + font-size: var(--navigation-font-size); +} + +img.footer { + width: 60px; +} + +.navpath li.footer { + color: var(--page-secondary-foreground-color); +} + +address.footer { + color: var(--page-secondary-foreground-color); + margin-bottom: var(--spacing-large); +} + +#nav-path li.navelem { + background-image: none; + display: flex; + align-items: center; +} + +.navpath li.navelem a { + text-shadow: none; + display: inline-block; + color: var(--primary-color) !important; +} + +.navpath li.navelem b { + color: var(--primary-dark-color); + font-weight: 500; +} + +li.navelem { + padding: 0; + margin-left: -8px; +} + +li.navelem:first-child { + margin-left: var(--spacing-large); +} + +li.navelem:first-child:before { + display: none; +} + +#nav-path li.navelem:after { + content: ''; + border: 5px solid var(--page-background-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: translateY(-1px) scaleY(4.2); + z-index: 10; + margin-left: 6px; +} + +#nav-path li.navelem:before { + content: ''; + border: 5px solid var(--separator-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: translateY(-1px) scaleY(3.2); + margin-right: var(--spacing-small); +} + +.navpath li.navelem a:hover { + color: var(--primary-color); +} + +/* + Scrollbars for Webkit +*/ + +#nav-tree::-webkit-scrollbar, +div.fragment::-webkit-scrollbar, +pre.fragment::-webkit-scrollbar, +div.memproto::-webkit-scrollbar, +.contents center::-webkit-scrollbar, +.contents .center::-webkit-scrollbar, +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname)::-webkit-scrollbar { + width: calc(var(--webkit-scrollbar-size) + var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding)); + height: calc(var(--webkit-scrollbar-size) + var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding)); +} + +#nav-tree::-webkit-scrollbar-thumb, +div.fragment::-webkit-scrollbar-thumb, +pre.fragment::-webkit-scrollbar-thumb, +div.memproto::-webkit-scrollbar-thumb, +.contents center::-webkit-scrollbar-thumb, +.contents .center::-webkit-scrollbar-thumb, +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname)::-webkit-scrollbar-thumb { + background-color: transparent; + border: var(--webkit-scrollbar-padding) solid transparent; + border-radius: calc(var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding)); + background-clip: padding-box; +} + +#nav-tree:hover::-webkit-scrollbar-thumb, +div.fragment:hover::-webkit-scrollbar-thumb, +pre.fragment:hover::-webkit-scrollbar-thumb, +div.memproto:hover::-webkit-scrollbar-thumb, +.contents center:hover::-webkit-scrollbar-thumb, +.contents .center:hover::-webkit-scrollbar-thumb, +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname):hover::-webkit-scrollbar-thumb { + background-color: var(--webkit-scrollbar-color); +} + +#nav-tree::-webkit-scrollbar-track, +div.fragment::-webkit-scrollbar-track, +pre.fragment::-webkit-scrollbar-track, +div.memproto::-webkit-scrollbar-track, +.contents center::-webkit-scrollbar-track, +.contents .center::-webkit-scrollbar-track, +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname)::-webkit-scrollbar-track { + background: transparent; +} + +#nav-tree::-webkit-scrollbar-corner { + background-color: var(--side-nav-background); +} + +#nav-tree, +div.fragment, +pre.fragment, +div.memproto, +.contents center, +.contents .center, +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) { + overflow-x: auto; + overflow-x: overlay; +} + +#nav-tree { + overflow-x: auto; + overflow-y: auto; + overflow-y: overlay; +} + +/* + Scrollbars for Firefox +*/ + +#nav-tree, +div.fragment, +pre.fragment, +div.memproto, +.contents center, +.contents .center, +.contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) { + scrollbar-width: thin; +} + +/* + Optional Dark mode toggle button +*/ + +doxygen-awesome-dark-mode-toggle { + display: inline-block; + margin: 0 0 0 var(--spacing-small); + padding: 0; + width: var(--searchbar-height); + height: var(--searchbar-height); + background: none; + border: none; + border-radius: var(--searchbar-height); + vertical-align: middle; + text-align: center; + line-height: var(--searchbar-height); + font-size: 22px; + display: flex; + align-items: center; + justify-content: center; + user-select: none; + cursor: pointer; +} + +doxygen-awesome-dark-mode-toggle > svg { + transition: transform .1s ease-in-out; +} + +doxygen-awesome-dark-mode-toggle:active > svg { + transform: scale(.5); +} + +doxygen-awesome-dark-mode-toggle:hover { + background-color: rgba(0,0,0,.03); +} + +html.dark-mode doxygen-awesome-dark-mode-toggle:hover { + background-color: rgba(0,0,0,.18); +} + +/* + Optional fragment copy button +*/ +.doxygen-awesome-fragment-wrapper { + position: relative; +} + +doxygen-awesome-fragment-copy-button { + opacity: 0; + background: var(--fragment-background); + width: 28px; + height: 28px; + position: absolute; + right: calc(var(--spacing-large) - (var(--spacing-large) / 2.5)); + top: calc(var(--spacing-large) - (var(--spacing-large) / 2.5)); + border: 1px solid var(--fragment-foreground); + cursor: pointer; + border-radius: var(--border-radius-small); + display: flex; + justify-content: center; + align-items: center; +} + +.doxygen-awesome-fragment-wrapper:hover doxygen-awesome-fragment-copy-button, doxygen-awesome-fragment-copy-button.success { + opacity: .28; +} + +doxygen-awesome-fragment-copy-button:hover, doxygen-awesome-fragment-copy-button.success { + opacity: 1 !important; +} + +doxygen-awesome-fragment-copy-button:active:not([class~=success]) svg { + transform: scale(.91); +} + +doxygen-awesome-fragment-copy-button svg { + fill: var(--fragment-foreground); + width: 18px; + height: 18px; +} + +doxygen-awesome-fragment-copy-button.success svg { + fill: rgb(14, 168, 14); +} + +doxygen-awesome-fragment-copy-button.success { + border-color: rgb(14, 168, 14); +} + +@media screen and (max-width: 767px) { + .textblock > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, + .textblock li > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, + .memdoc li > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, + .memdoc > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, + dl dd > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button { + right: 0; + } +} + +/* + Optional paragraph link button +*/ + +a.anchorlink { + font-size: 90%; + margin-left: var(--spacing-small); + color: var(--page-foreground-color) !important; + text-decoration: none; + opacity: .15; + display: none; + transition: opacity .1s ease-in-out, color .1s ease-in-out; +} + +a.anchorlink svg { + fill: var(--page-foreground-color); +} + +h3 a.anchorlink svg, h4 a.anchorlink svg { + margin-bottom: -3px; + margin-top: -4px; +} + +a.anchorlink:hover { + opacity: .45; +} + +h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.anchorlink { + display: inline-block; +} diff --git a/Docs/ogre-logo-wetfloor.gif b/Docs/ogre-logo-wetfloor.gif deleted file mode 100644 index f478019f0a73e4c871e5f6f1af488e78be5f1a44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7729 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 T{KAS200000NkvXXu0mjfR%dtL literal 0 HcmV?d00001 diff --git a/Docs/ogre_style.css b/Docs/ogre_style.css index 9fe77113837..83d5137dc7e 100644 --- a/Docs/ogre_style.css +++ b/Docs/ogre_style.css @@ -1,361 +1,12 @@ -/* - * GitHub Markdown style CSS for doxygen 1.8.14 - * Source: https://github.com/sindresorhus/github-markdown-css - * License: MIT © Sindre Sorhus - */ - -* { - box-sizing: border-box; -} - -body, table, div, p, dl { - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; - line-height: 1.5; - color: #24292e; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 1.5; - word-wrap: break-word; -} - -b { - font-weight: 600; -} - -/* @group Heading Levels */ - -h1, h2, h3, h4, h5, h6, .headertitle { - font-weight: 600; - line-height: 1.25; - margin-top: 24px; - margin-bottom: 16px; -} - -.headertitle { - margin-top: 0px; -} - -h1 { - font-size: 2em; - padding-bottom: 0.3em; -} - -h2 { - padding-bottom: 0.3em; - font-size: 1.5em; -} - -h3 { - font-size: 1.25em; -} - -h4 { - font-size: 1em; -} - -h5 { - font-size: 0.875em; -} - -h6 { - font-size: 0.85em; - color: #6a737d; -} - -a { - background-color: transparent; - color: #628768; - text-decoration: none; - font-weight: normal; -} - -.contents a:visited { - color: #628768; -} - -a:active, a:hover { - outline-width: 0; -} - -a:hover { - text-decoration: underline; -} - -a:not([href]) { - color: inherit; - text-decoration: none; -} - -a.el { - font-weight: normal; -} - -.image { - text-align: left; -} - -.tip { - background-image: url(tip.png); - background-position: left center; - background-repeat: no-repeat; - padding-left: 30px; - margin-top: 1em; - margin-bottom: 1em; - min-height: 31px; - display: block; - font-style:italic; -} - -.warn { - background-image: url(warn.png); - background-position: left center; - background-repeat: no-repeat; - padding-left: 48px; - margin-top: 1em; - margin-bottom: 1em; - min-height: 31px; - display: block; - font-style:italic; -} - -#projectname -{ - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 2em; - font-weight: bold; -} - -#projectbrief -{ - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 0.8em; -} - -#projectnumber -{ - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 1em; -} - -div.contents { - width: 980px; - padding: 0px; - margin-top: -1px; - margin-bottom: 10px; -} - -div.toc { - border: 0px none; - border-radius: 7px 7px 7px 7px; -} - -div.header -{ - width: 980px; - padding: 00px; - margin-top: 10px; - background-image: none; - background-repeat: none; - background-color: transparent; - border: medium none; -} - -.PageDoc div.header .title { - font-size: 2em; -} - -.PageDoc code { - padding: .2em .4em; - margin: 0; - font-size: 85%; - background-color: rgba(27,31,35,.05); - border-radius: 3px; - font-family: inherit; -} - -.PageDoc blockquote.doxtable { - padding: 0 1em; - color: #6a737d; - border-left: .25em solid #dfe2e5; - background-color: white; -} - -.PageDoc blockquote.doxtable p { - color: #6a737d; - background-color: white; -} - -table.markdownTable tr { - background-color: #fff; - border-top: 1px solid #c6cbd1; -} - -table.markdownTable td, -table.markdownTable tr { - padding: 6px 13px; - border: 1px solid #dfe2e5; -} - -table.markdownTable tr:nth-child(2n) { - background-color: #f6f8fa; -} - -.title ol { - margin: 0px; -} - -.title ol li { - list-style-type: none; -} - -.ui-resizable .ui-resizable-handle { -} - -.ui-resizable-e { - background: none; - background-color: #E6E6E6; -} - -.ui-resizable-handle { -} - -div.fragment { - padding: 16px; - background-color: #f3f3f3; - border: 0px solid; -} - -div.line, -.PageDoc code { - font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 85%; - line-height: 1.45; - -webkit-transition-duration: 0; - -moz-transition-duration: 0; - -ms-transition-duration: 0; - -o-transition-duration: 0; - transition-duration: 0; -} - -div.line.glow { - background-color: auto; - box-shadow: none; -} - -pre.fragment { - border: 0px solid #C4CFE5; - padding: 16px; - background-color: #f3f3f3; - font-size: 85%; - line-height: 1.45; - font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 85%; -} - -/* @group Code Colorization */ -span.keyword { - color: #808000 -} - -span.keywordtype { - color: #808000 -} - -span.keywordflow { - color: #808000 -} - -span.comment { - color: #008000 -} - -span.preprocessor { - color: #800000 -} - -span.stringliteral { - color: #000080 -} - -span.charliteral { - color: #000080 -} - -blockquote { - background-color: #EEEEEE; - border-left: 2px solid #606060; - margin: 0 24px 0 4px; - padding: 0 12px 0 16px; -} - -/* @end */ - -.arrow { - box-sizing: content-box; - display: inline-block; -} - -img { - max-width: 100%; - max-height: 100%; -} - -#nav-tree { - background-image: none; -} - -#nav-tree .label { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 14px; -} - -#side-nav { - width: 25%; - max-width: 50%; -} - -.memtitle { - background-image: none; -} - -.memproto { - text-shadow: none; - /* opera specific markup */ - box-shadow: none; - /* firefox specific markup */ - -moz-box-shadow: none; - -moz-border-radius-topright: 4px; - /* webkit specific markup */ - -webkit-box-shadow: none; - -webkit-border-top-right-radius: 4px; -} - -.memdoc { - background-image:none; - background-repeat:repeat-x; - background-color: #FFFFFF; - /* opera specific markup */ - box-shadow: none; - /* firefox specific markup */ - -moz-box-shadow: none; - /* webkit specific markup */ - -webkit-box-shadow: none; -} - -#projectlogo { - display: none; -} - -#projectalign { - padding: 4px 0; -} - -.sm-dox, -.sm-dox a { - background-image: none; -} - -#nav-tree { - background-color: #fff; -} +html { + --primary-color: #628768; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) { + --primary-color: #628768; + } + img.inline { + background-color: #d2dbde; + } +} \ No newline at end of file diff --git a/Docs/src/apimainpage.md b/Docs/src/apimainpage.md index 25f7b485c8f..4a35967aece 100644 --- a/Docs/src/apimainpage.md +++ b/Docs/src/apimainpage.md @@ -3,10 +3,10 @@ # Introduction ## What is this? -This is the complete API reference for OGRE (Object-Oriented Graphics Rendering Engine) version **2.3**. Contained within are the +This is the complete API reference for OGRE-Next (Object-Oriented Graphics Rendering Engine) version **3.0**. Contained within are the specifications for each namespace/module/class and the methods from those which you can refer to when writing code which uses OGRE. -The API references for some of the previous OGRE versions can be found under the following link: www.ogre3d.org/docs/api/X.Y (replace X.Y with the version number, for example 1.7, 1.8, etc.). +The API references for some of the previous OGRE versions can be found under the following link: https://ogrecave.github.io/ogre-next/api/X.Y (replace X.Y with the version number, for example 2.3, 3.0, etc.). ## It's so BIG! @@ -23,16 +23,16 @@ general introduction to the OGRE principles and core components, and a reference to various important parts of the OGRE system, especially the script syntax for materials, particle systems, and overlays. You should find a local copy of this in your distribution. -* The OGRE 2.1 FAQ: This page contains a list of frequently asked questions (FAQ) around Ogre 2.1, pertaining to its general state, the supported rendering components as well as more specific building / compiling / coding questions. This list will be extended as new central questions arise. +* The OGRE-Next 2.1+ FAQ: This page contains a list of frequently asked questions (FAQ) around OGRE-Next 2.1 and later, pertaining to its general state, the supported rendering components as well as more specific building / compiling / coding questions. This list will be extended as new central questions arise. We make an effort to document our classes fully so we hope you can find what you need here. However, if you can't find it, or you're not sure where to -start looking, visit the main OGRE website and dip into the community areas -like the wiki and the forums to get some assistance. +start looking, visit the main OGRE website and dip into the community areas +like the wiki and the forums to get some assistance. ## License -The OGRE rendering engine itself is licensed under the MIT License. More details can be found here.
-This documentation work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
+The OGRE rendering engine itself is licensed under the MIT License. More details can be found here.
+This documentation work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
*Copyright © 2015 Torus Knot Software Ltd*
Creative Commons License From 03fbfb62ca792295dcd84033a609eb37dc4452d8 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 10 Nov 2023 19:11:25 -0300 Subject: [PATCH 088/124] New CI for Doxygen Let's hope it works alright. --- .github/workflows/linux.build.yml | 2 +- .github/workflows/main.yml | 43 +++++-------------- .../BuildScripts/build_ci_doxygen_step0.sh | 36 ++++++++++++++++ .../BuildScripts/build_ci_doxygen_step1.sh | 26 +++++++++++ 4 files changed, 74 insertions(+), 33 deletions(-) create mode 100755 Scripts/BuildScripts/build_ci_doxygen_step0.sh create mode 100755 Scripts/BuildScripts/build_ci_doxygen_step1.sh diff --git a/.github/workflows/linux.build.yml b/.github/workflows/linux.build.yml index 045e2a87047..5e55591e9a9 100644 --- a/.github/workflows/linux.build.yml +++ b/.github/workflows/linux.build.yml @@ -1,4 +1,4 @@ -name: CI +name: Linux CI # Controls when the action will run. on: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3dce0ae315a..af8fc6f89f6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,21 +1,12 @@ -name: CI +name: Doxygen # Controls when the action will run. on: push: branches: 'master' - # Run for all pull requests - pull_request: - branches: '*' - types: [opened] - env: - CMAKE_DOXYGEN_INPUT_LIST: "Components Docs/src OgreMain PlugIns RenderSystems" - OGRE_SOURCE_DIR: "./" - OGRE_BINARY_DIR: "./" OGRE_VERSION: "latest" - DOXYGEN_HTML_OUTPUT_DIR: "./latest" # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -24,27 +15,15 @@ jobs: # The type of runner that the job will run on runs-on: ubuntu-latest - # Steps represent a sequence of tasks that will be executed as part of the job steps: - - uses: actions/checkout@v3 - - - name: Generate Doxyfile - # Replace CMake's ${ENV_VAR} to Doxygen's $(ENV_VAR) syntax - run: cat CMake/Templates/html.cfg.in | sed 's/\${\(.*\)}/$(\1)/' > Doxyfile - - - name: Generate docs with doxygen - uses: mattnotmitt/doxygen-action@v1 - with: - doxyfile-path: './Doxyfile' - - - name: Remove files - working-directory: .github/workflows/ - run: python3 doxygen_remove_files.py - - - name: Publish # Only on master branch - if: github.ref == 'refs/heads/master' - uses: peaceiris/actions-gh-pages@v3 + - uses: actions/checkout@v4 + - name: Build Doxygen + working-directory: ./ + run: ./Scripts/BuildScripts/build_ci_doxygen_step0.sh + - uses: actions/checkout@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./ - keep_files: true + ref: gh-pages + path: gh-pages + - name: Publish Doxygen + working-directory: ./ + run: ./Scripts/BuildScripts/build_ci_doxygen_step1.sh diff --git a/Scripts/BuildScripts/build_ci_doxygen_step0.sh b/Scripts/BuildScripts/build_ci_doxygen_step0.sh new file mode 100755 index 00000000000..e5992bad88f --- /dev/null +++ b/Scripts/BuildScripts/build_ci_doxygen_step0.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +if [ -z "$OGRE_VERSION" ]; then + echo "OGRE_VERSION is not set. Aborting!" + exit 1; +fi + +echo "--- Installing System Dependencies ---" +sudo apt-get update +sudo apt-get install -y ninja-build libxrandr-dev libxaw7-dev libxcb-randr0-dev libx11-xcb-dev libsdl2-dev doxygen graphviz + +echo "--- Fetching prebuilt Dependencies ---" +wget https://github.com/OGRECave/ogre-next-deps/releases/download/bin-releases/Dependencies_Release_Ubuntu.20.04.LTS.Clang-12_a3f61e782f3effbd58a15727885cbd85cd1b342b.7z + +echo "--- Extracting prebuilt Dependencies ---" +7z x Dependencies_Release_Ubuntu.20.04.LTS.Clang-12_a3f61e782f3effbd58a15727885cbd85cd1b342b.7z + +mkdir -p build/Doxygen +cd build/Doxygen +echo "--- Building Ogre (Debug) ---" +cmake \ +-DOGRE_CONFIG_THREAD_PROVIDER=0 \ +-DOGRE_CONFIG_THREADS=0 \ +-DOGRE_BUILD_COMPONENT_SCENE_FORMAT=1 \ +-DOGRE_BUILD_SAMPLES2=0 \ +-DOGRE_BUILD_TESTS=0 \ +-DOGRE_BUILD_COMPONENT_PLANAR_REFLECTIONS=1 \ +-DCMAKE_BUILD_TYPE="Debug" \ +-DCMAKE_CXX_STANDARD=11 \ +-G Ninja ../.. || exit $? +ninja OgreDoc || exit $? +cd ../.. || exit $? +# echo "--- Checking out gh-pages branch ---" +# git checkout gh-pages || exit $? + +echo "Done Step 0!" diff --git a/Scripts/BuildScripts/build_ci_doxygen_step1.sh b/Scripts/BuildScripts/build_ci_doxygen_step1.sh new file mode 100755 index 00000000000..ae0b590d352 --- /dev/null +++ b/Scripts/BuildScripts/build_ci_doxygen_step1.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +if [ -z "$OGRE_VERSION" ]; then + echo "OGRE_VERSION is not set. Aborting!" + exit 1; +fi + +# echo "--- Checking out gh-pages branch ---" +# git checkout gh-pages || exit $? +cd gh-pages || exit $? +cd api || exit $? +echo "--- Removing old ${OGRE_VERSION} ---" +git rm -rf ${OGRE_VERSION} || exit $? +rm -rf ${OGRE_VERSION} || exit $? +echo "--- Copying new ${OGRE_VERSION} ---" +mv ../../build/Doxygen/api/html ${OGRE_VERSION} || exit $? +git config user.email "github-actions" +git config user.name "github-actions@github.com" +echo "--- Adding to ${OGRE_VERSION} to git ---" +git add ${OGRE_VERSION} || exit $? +echo "--- Committing ---" +git commit -m "Deploy GH" || exit $? +echo "--- Pushing repo... ---" +git push || exit $? + +echo "Done Step 1!" From 81f5383e9882e129a9bbe76d9db0d77ab13d9403 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 10 Nov 2023 20:04:45 -0300 Subject: [PATCH 089/124] Improve Doxygen CI --- .github/workflows/main.yml | 15 +++++++---- ...i_doxygen_step0.sh => build_ci_doxygen.sh} | 13 +++++++--- .../BuildScripts/build_ci_doxygen_step1.sh | 26 ------------------- 3 files changed, 19 insertions(+), 35 deletions(-) rename Scripts/BuildScripts/{build_ci_doxygen_step0.sh => build_ci_doxygen.sh} (78%) delete mode 100755 Scripts/BuildScripts/build_ci_doxygen_step1.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index af8fc6f89f6..ec02171f924 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,13 +17,18 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Build Doxygen - working-directory: ./ - run: ./Scripts/BuildScripts/build_ci_doxygen_step0.sh - uses: actions/checkout@v4 with: ref: gh-pages path: gh-pages - - name: Publish Doxygen + + - name: Build Doxygen working-directory: ./ - run: ./Scripts/BuildScripts/build_ci_doxygen_step1.sh + run: ./Scripts/BuildScripts/build_ci_doxygen.sh + + - name: Publish # Only on master branch + if: github.ref == 'refs/heads/master' + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./gh-pages diff --git a/Scripts/BuildScripts/build_ci_doxygen_step0.sh b/Scripts/BuildScripts/build_ci_doxygen.sh similarity index 78% rename from Scripts/BuildScripts/build_ci_doxygen_step0.sh rename to Scripts/BuildScripts/build_ci_doxygen.sh index e5992bad88f..39a7b5bb220 100755 --- a/Scripts/BuildScripts/build_ci_doxygen_step0.sh +++ b/Scripts/BuildScripts/build_ci_doxygen.sh @@ -29,8 +29,13 @@ cmake \ -DCMAKE_CXX_STANDARD=11 \ -G Ninja ../.. || exit $? ninja OgreDoc || exit $? -cd ../.. || exit $? -# echo "--- Checking out gh-pages branch ---" -# git checkout gh-pages || exit $? -echo "Done Step 0!" +echo "--- Going to gh-pages repo ---" +cd ../../gh-pages || exit $? +cd api || exit $? +echo "--- Removing old ${OGRE_VERSION} ---" +rm -rf ${OGRE_VERSION} || exit $? +echo "--- Copying new ${OGRE_VERSION} ---" +mv ../../build/Doxygen/api/html ${OGRE_VERSION} || exit $? + +echo "Done!" diff --git a/Scripts/BuildScripts/build_ci_doxygen_step1.sh b/Scripts/BuildScripts/build_ci_doxygen_step1.sh deleted file mode 100755 index ae0b590d352..00000000000 --- a/Scripts/BuildScripts/build_ci_doxygen_step1.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -if [ -z "$OGRE_VERSION" ]; then - echo "OGRE_VERSION is not set. Aborting!" - exit 1; -fi - -# echo "--- Checking out gh-pages branch ---" -# git checkout gh-pages || exit $? -cd gh-pages || exit $? -cd api || exit $? -echo "--- Removing old ${OGRE_VERSION} ---" -git rm -rf ${OGRE_VERSION} || exit $? -rm -rf ${OGRE_VERSION} || exit $? -echo "--- Copying new ${OGRE_VERSION} ---" -mv ../../build/Doxygen/api/html ${OGRE_VERSION} || exit $? -git config user.email "github-actions" -git config user.name "github-actions@github.com" -echo "--- Adding to ${OGRE_VERSION} to git ---" -git add ${OGRE_VERSION} || exit $? -echo "--- Committing ---" -git commit -m "Deploy GH" || exit $? -echo "--- Pushing repo... ---" -git push || exit $? - -echo "Done Step 1!" From 317eaca9d5a961132eeabbb662bbabf9d0bde839 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 10 Nov 2023 20:17:19 -0300 Subject: [PATCH 090/124] Use the old push method peaceiris/actions-gh-pages@v3 was ridiculously slow --- .github/workflows/main.yml | 7 ------- Scripts/BuildScripts/build_ci_doxygen.sh | 11 +++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec02171f924..2e38b8971e6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,10 +25,3 @@ jobs: - name: Build Doxygen working-directory: ./ run: ./Scripts/BuildScripts/build_ci_doxygen.sh - - - name: Publish # Only on master branch - if: github.ref == 'refs/heads/master' - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./gh-pages diff --git a/Scripts/BuildScripts/build_ci_doxygen.sh b/Scripts/BuildScripts/build_ci_doxygen.sh index 39a7b5bb220..855006cd082 100755 --- a/Scripts/BuildScripts/build_ci_doxygen.sh +++ b/Scripts/BuildScripts/build_ci_doxygen.sh @@ -34,8 +34,19 @@ echo "--- Going to gh-pages repo ---" cd ../../gh-pages || exit $? cd api || exit $? echo "--- Removing old ${OGRE_VERSION} ---" +git rm -rf ${OGRE_VERSION} || exit $? rm -rf ${OGRE_VERSION} || exit $? echo "--- Copying new ${OGRE_VERSION} ---" mv ../../build/Doxygen/api/html ${OGRE_VERSION} || exit $? +git config user.email "darksylinc" +git config user.name "darksylinc@users.noreply.github.com" + +echo "--- Adding to ${OGRE_VERSION} to git ---" +git add ${OGRE_VERSION} || exit $? +echo "--- Committing ---" +git commit -m "Deploy GH" || exit $? +echo "--- Pushing repo... ---" +git push || exit $? + echo "Done!" From 6d06db93e1aca8e530efa04191f26290330d54a1 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 10 Nov 2023 20:29:07 -0300 Subject: [PATCH 091/124] Don't error if there are no doxygen changes --- Scripts/BuildScripts/build_ci_doxygen.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Scripts/BuildScripts/build_ci_doxygen.sh b/Scripts/BuildScripts/build_ci_doxygen.sh index 855006cd082..63f12f9cd0f 100755 --- a/Scripts/BuildScripts/build_ci_doxygen.sh +++ b/Scripts/BuildScripts/build_ci_doxygen.sh @@ -44,9 +44,13 @@ git config user.name "darksylinc@users.noreply.github.com" echo "--- Adding to ${OGRE_VERSION} to git ---" git add ${OGRE_VERSION} || exit $? -echo "--- Committing ---" -git commit -m "Deploy GH" || exit $? -echo "--- Pushing repo... ---" -git push || exit $? +if [ $(git status --porcelain | wc -l) -eq "0" ]; then + echo "--- Nothing has changed. Nothing to commit or push. ---" +else + echo "--- Committing ---" + git commit -m "Deploy GH" || exit $? + echo "--- Pushing repo... ---" + git push || exit $? +fi echo "Done!" From bb07baeb2994d37f994df90b469be9b9a8d6e5bf Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Wed, 15 Nov 2023 21:20:39 -0300 Subject: [PATCH 092/124] [Vk/GL] Declare textures as mediump when appropriate We were doing this for Metal, but not for GLSL. --- .../GLSL/CrossPlatformSettings_piece_all.glsl | 6 ++++++ .../Media/Hlms/Pbs/Any/AreaLights_piece_ps.any | 2 +- .../Pbs/Any/Main/200.Textures_piece_ps.any | 4 ++-- .../Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl | 6 +++--- .../Media/Hlms/Pbs/GLSL/PixelShader_ps.glsl | 18 +++++++++--------- .../Media/Hlms/Terra/GLSL/PixelShader_ps.glsl | 16 ++++++++-------- .../Media/Hlms/Unlit/GLSL/PixelShader_ps.glsl | 8 ++++---- 7 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl b/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl index f3930a6a98f..a6702974136 100644 --- a/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl +++ b/Samples/Media/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl @@ -125,6 +125,8 @@ #define midf3x3_c mat3 #define midf4x4_c mat4 + #define midf_tex + #define toMidf3x3( x ) mat3( x ) #define buildMidf3x3( row0, row1, row2 ) mat3( row0, row1, row2 ) @@ -152,6 +154,8 @@ #define midf3x3_c f16mat3x3 #define midf4x4_c f16mat4x4 + #define midf_tex mediump + #define toMidf3x3( x ) f16mat3x3( x ) #define buildMidf3x3( row0, row1, row2 ) f16mat3x3( row0, row1, row2 ) @@ -190,6 +194,8 @@ #define midf3x3_c mat3 #define midf4x4_c mat4 + #define midf_tex mediump + #define toMidf3x3( x ) mat3( x ) #define buildMidf3x3( row0, row1, row2 ) mat3( row0, row1, row2 ) diff --git a/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any index 791075e1ed5..794cebbcaca 100644 --- a/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/AreaLights_piece_ps.any @@ -8,7 +8,7 @@ uniform sampler2DArray areaLightMasks; @end @property( syntax == glslvk ) - layout( ogre_t@value(areaLightMasks) ) uniform texture2DArray areaLightMasks; + layout( ogre_t@value(areaLightMasks) ) midf_tex uniform texture2DArray areaLightMasks; layout( ogre_s@value(areaLightMasks) ) uniform sampler areaLightMasksSampler; @end @property( syntax == hlsl ) diff --git a/Samples/Media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any index 29bdc8f5840..0ffb347360a 100644 --- a/Samples/Media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any @@ -7,8 +7,8 @@ uniform sampler2DArray ltcMatrix; @end @property( syntax == glslvk ) - layout( ogre_t@value(ltcMatrix) ) uniform texture2DArray ltcMatrix; - layout( ogre_s@value(ltcMatrix) ) uniform sampler ltcSampler; + layout( ogre_t@value(ltcMatrix) ) midf_tex uniform texture2DArray ltcMatrix; + layout( ogre_s@value(ltcMatrix) ) midf_tex uniform sampler ltcSampler; @end @property( syntax == hlsl ) Texture2DArray ltcMatrix : register(t@value(ltcMatrix)); diff --git a/Samples/Media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl b/Samples/Media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl index 27d4a0563bf..aae9c0cde7b 100644 --- a/Samples/Media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl +++ b/Samples/Media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl @@ -5,13 +5,13 @@ @property( syntax == glslvk ) layout( ogre_s@value(decalsSampler) ) uniform sampler decalsSampler; @end - @property( hlms_decals_diffuse )vulkan_layout( ogre_t@value(decalsDiffuseTex) ) uniform texture2DArray decalsDiffuseTex;@end - @property( hlms_decals_normals )vulkan_layout( ogre_t@value(decalsNormalsTex) ) uniform texture2DArray decalsNormalsTex;@end + @property( hlms_decals_diffuse )vulkan_layout( ogre_t@value(decalsDiffuseTex) ) midf_tex uniform texture2DArray decalsDiffuseTex;@end + @property( hlms_decals_normals )vulkan_layout( ogre_t@value(decalsNormalsTex) ) midf_tex uniform texture2DArray decalsNormalsTex;@end @property( hlms_decals_diffuse == hlms_decals_emissive ) #define decalsEmissiveTex decalsDiffuseTex @end @property( hlms_decals_emissive && hlms_decals_diffuse != hlms_decals_emissive ) - vulkan_layout( ogre_t@value(decalsEmissiveTex) ) uniform texture2DArray decalsEmissiveTex; + vulkan_layout( ogre_t@value(decalsEmissiveTex) ) midf_tex uniform texture2DArray decalsEmissiveTex; @end @end @end diff --git a/Samples/Media/Hlms/Pbs/GLSL/PixelShader_ps.glsl b/Samples/Media/Hlms/Pbs/GLSL/PixelShader_ps.glsl index 296a2290f6f..b2c3e75199e 100644 --- a/Samples/Media/Hlms/Pbs/GLSL/PixelShader_ps.glsl +++ b/Samples/Media/Hlms/Pbs/GLSL/PixelShader_ps.glsl @@ -49,8 +49,8 @@ layout(std140) uniform; vulkan_layout( ogre_t@value(depthTextureNoMsaa) ) uniform texture2D depthTextureNoMsaa; @end @end - vulkan_layout( ogre_t@value(refractionMap) ) uniform texture2D refractionMap; - vulkan( layout( ogre_s@value(refractionMap) ) uniform sampler refractionMapSampler ); + vulkan_layout( ogre_t@value(refractionMap) ) midf_tex uniform texture2D refractionMap; + vulkan( layout( ogre_s@value(refractionMap) ) uniform sampler refractionMapSampler ); @end @insertpiece( DeclPlanarReflTextures ) @@ -82,21 +82,21 @@ vulkan_layout( location = 0 ) in block ReadOnlyBufferF( @value(f3dLightList), float4, f3dLightList ); @end @property( irradiance_volumes ) - vulkan_layout( ogre_t@value(irradianceVolume) ) uniform texture3D irradianceVolume; - vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); + vulkan_layout( ogre_t@value(irradianceVolume) ) midf_tex uniform texture3D irradianceVolume; + vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); @end @foreach( num_textures, n ) - vulkan_layout( ogre_t@value(textureMaps@n) ) uniform texture2DArray textureMaps@n;@end + vulkan_layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2DArray textureMaps@n;@end @property( use_envprobe_map ) @property( !hlms_enable_cubemaps_auto ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCube texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCube texEnvProbeMap; @else @property( !hlms_cubemaps_use_dpm ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCubeArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCubeArray texEnvProbeMap; @else - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform texture2DArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform texture2DArray texEnvProbeMap; @insertpiece( DeclDualParaboloidFunc ) @end @end @@ -140,7 +140,7 @@ void main() @property( alpha_test ) @foreach( num_textures, n ) - vulkan_layout( ogre_t@value(textureMaps@n) ) uniform texture2DArray textureMaps@n;@end + vulkan_layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2DArray textureMaps@n;@end @property( syntax == glslvk ) @foreach( num_samplers, n ) diff --git a/Samples/Media/Hlms/Terra/GLSL/PixelShader_ps.glsl b/Samples/Media/Hlms/Terra/GLSL/PixelShader_ps.glsl index a6d26cdd2e8..7df903db081 100644 --- a/Samples/Media/Hlms/Terra/GLSL/PixelShader_ps.glsl +++ b/Samples/Media/Hlms/Terra/GLSL/PixelShader_ps.glsl @@ -67,8 +67,8 @@ in block in vec4 gl_FragCoord; @end -vulkan_layout( ogre_t@value(terrainNormals) ) uniform texture2D terrainNormals; -vulkan_layout( ogre_t@value(terrainShadows) ) uniform texture2D terrainShadows; +vulkan_layout( ogre_t@value(terrainNormals) ) midf_tex uniform texture2D terrainNormals; +vulkan_layout( ogre_t@value(terrainShadows) ) midf_tex uniform texture2D terrainShadows; vulkan( layout( ogre_s@value(terrainNormals) ) uniform sampler samplerStateTerra ); @property( hlms_forwardplus ) @@ -76,21 +76,21 @@ vulkan( layout( ogre_s@value(terrainNormals) ) uniform sampler samplerStateTerra ReadOnlyBufferF( @value(f3dLightList), float4, f3dLightList ); @end @property( irradiance_volumes ) - vulkan_layout( ogre_t@value(irradianceVolume) ) uniform texture3D irradianceVolume; - vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); + vulkan_layout( ogre_t@value(irradianceVolume) ) midf_tex uniform texture3D irradianceVolume; + vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); @end @foreach( num_textures, n ) - vulkan_layout( ogre_t@value(textureMaps@n) ) uniform texture2DArray textureMaps@n;@end + vulkan_layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2DArray textureMaps@n;@end @property( use_envprobe_map ) @property( !hlms_enable_cubemaps_auto ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCube texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCube texEnvProbeMap; @else @property( !hlms_cubemaps_use_dpm ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCubeArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCubeArray texEnvProbeMap; @else - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform texture2DArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform texture2DArray texEnvProbeMap; @insertpiece( DeclDualParaboloidFunc ) @end @end diff --git a/Samples/Media/Hlms/Unlit/GLSL/PixelShader_ps.glsl b/Samples/Media/Hlms/Unlit/GLSL/PixelShader_ps.glsl index 281731137ee..38f47c9525d 100644 --- a/Samples/Media/Hlms/Unlit/GLSL/PixelShader_ps.glsl +++ b/Samples/Media/Hlms/Unlit/GLSL/PixelShader_ps.glsl @@ -28,17 +28,17 @@ layout(location = FRAG_COLOR, index = 0) out midf outColour; @property( syntax != glslvk ) @foreach( num_textures, n ) @property( is_texture@n_array ) - uniform sampler2DArray textureMapsArray@n; + midf_tex uniform sampler2DArray textureMapsArray@n; @else - uniform sampler2D textureMaps@n; + midf_tex uniform sampler2D textureMaps@n; @end @end @else @foreach( num_textures, n ) @property( is_texture@n_array ) - layout( ogre_t@value(textureMapsArray@n) ) uniform texture2DArray textureMapsArray@n; + layout( ogre_t@value(textureMapsArray@n) ) midf_tex uniform texture2DArray textureMapsArray@n; @else - layout( ogre_t@value(textureMaps@n) ) uniform texture2D textureMaps@n; + layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2D textureMaps@n; @end @end @end From e1de9b4edfcd073a3c9fd131c26466adaf6101f7 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 23 Nov 2023 16:23:42 -0300 Subject: [PATCH 093/124] Deprecate SceneManager::setFog Update documentation. --- Docs/src/manual/Ogre3.0.Changes.md | 35 ++++++++++++++++++- .../manual/ResolvingMergeConflictsIn3.0.md | 14 ++++---- OgreMain/include/OgreMaterial.h | 1 + OgreMain/include/OgrePass.h | 13 +++---- OgreMain/include/OgreSceneManager.h | 13 ++++--- OgreMain/include/OgreTechnique.h | 1 + OgreMain/src/OgreHlmsLowLevel.cpp | 11 ++++++ OgreMain/src/OgreMaterialSerializer.cpp | 11 ++++++ OgreMain/src/OgreSceneManager.cpp | 12 +++++++ OgreMain/src/OgreScriptTranslator.cpp | 13 ++++++- 10 files changed, 105 insertions(+), 19 deletions(-) diff --git a/Docs/src/manual/Ogre3.0.Changes.md b/Docs/src/manual/Ogre3.0.Changes.md index d764cfacad8..34175240d21 100644 --- a/Docs/src/manual/Ogre3.0.Changes.md +++ b/Docs/src/manual/Ogre3.0.Changes.md @@ -46,4 +46,37 @@ 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.3 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. + +## Move to C++11 and general cleanup + +Lots of dead \& long-deprecated code was removed. +See [Resolving Merge Conflicts in Ogre-Next 3.0](@ref ResolvingMergeConflicts30) for more help with C++11 changes. + + - Remove D3D9 + - Remove Terrain + - Remove RTShaderSystem + - Remove NaCL + - Remove dead SceneManagers + - Remove `( void )` from empty functions + - Remove StaticGeometry + - Remove files under `Deprecated/` folders + - Move to C++11 + - Remove code under `__cplusplus` that uses `< 201103L` `>= 201103L` or numbers below 201103L + - Math::Log2 should use log2 + - All virtuals must have `overload` keyword + - Remove `HardwareUniformBuffer`, `HardwareCounterBuffer` + - Fix many warnings. + - Clean up Media folder and remove unused stuff from Ogre samples. + - Add ASAN CMake option. + - Use OGRE_DEPRECATED. + - Add cmake option to embed debug level into OgreBuildSettings. + - Bakes OGRE_DEBUG_MODE into OgreBuildSettings.h; which is on by default on Ninja/GNU Make generators and disabled for the rest. + - Pass cookie to Ogre Root initialization to catch obvious ABI errors. Each library could call checkAbiCookie on initialization to avoid problems + - Default to clang's ld linker on Linux, i.e. `set( CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld" )` + - Remove `OgreShadowVolumeExtrudeProgram.cpp` + - Deprecate `SceneManager::setFog` + - Remove `getShadowCasterVertex` + - Remove memory allocator stuff (see Ogre 1.x) + - Remove nedmalloc + - Typedef SharedPtr to std::shared_ptr (see Ogre 1.x) diff --git a/Docs/src/manual/ResolvingMergeConflictsIn3.0.md b/Docs/src/manual/ResolvingMergeConflictsIn3.0.md index a4ddc032e04..047f2e6d0f2 100644 --- a/Docs/src/manual/ResolvingMergeConflictsIn3.0.md +++ b/Docs/src/manual/ResolvingMergeConflictsIn3.0.md @@ -7,9 +7,9 @@ In Ogre-Next 3.0 we performed multiple changes that affected nearly the entire c - Lots of warnings were fixed - Clang format 13 was applied to the entire codebase -Users who run a customized version of Ogre-Next may found rebasing to the latest version a near impossible job due to the sheer amount of minor merge conflicts. +Users who run a forked/customized version of Ogre-Next may found rebasing to the latest version a near impossible job due to the sheer amount of *minor* merge conflicts. -To perform this task with more easily, we recommend the following: +To perform this task more easily, we recommend the following: 1. Merge your changes with `master` branch (or 3.0 when it appears) 2. Resolve all conflicts with `your code` @@ -69,7 +69,7 @@ void moreFunctions() } ``` -After applying Clang format, everything that follows will indent (and likely the code will not compile): +After applying Clang format, everything that follows will indent (and likely the code will not compile) which make much easier to spot where the problem went wrong: ```cpp void myFuntion( int a ) @@ -90,12 +90,12 @@ void myFuntion( int a ) } ``` -If you find after merging and applying clang format that there is massive added or removed indentation; start from the top and find the first occurrence of this change and start looking for the missing brace. +If you find after merging and applying clang format that there is massive indentation being added (or removed); start from the top and find the first occurrence of this change and start looking for the missing brace. # Batch Script -The following bash script will run clang-format on all files with the right extensions in the current folder and recursively in its subdirectories +The following bash script will run clang-format on all files with the right extensions in the current folder and recursively in its sub-directories. ```bash FILES=$(find . -name "*.mm" -o -name "*.h" -o -name "*.cpp") @@ -105,4 +105,6 @@ do echo "Formatting \"$file\"" clang-format-13 -i "$file" done -``` \ No newline at end of file +``` + +You can also look at our python script in [.github/workflows/run_clang_format.py](https://github.com/OGRECave/ogre-next/blob/879a86fd4d1e7274af67b37628f29d6ad06a7d79/.github/workflows/run_clang_format.py) if you prefer Python instead. \ No newline at end of file diff --git a/OgreMain/include/OgreMaterial.h b/OgreMain/include/OgreMaterial.h index 8f9ae048ae8..55e62bb1de7 100644 --- a/OgreMain/include/OgreMaterial.h +++ b/OgreMain/include/OgreMaterial.h @@ -459,6 +459,7 @@ namespace Ogre property there. @see Pass::setFog */ + OGRE_DEPRECATED_VER( 3 ) void setFog( bool overrideScene, FogMode mode = FOG_NONE, const ColourValue &colour = ColourValue::White, Real expDensity = Real( 0.001 ), Real linearStart = 0.0, Real linearEnd = 1.0 ); diff --git a/OgreMain/include/OgrePass.h b/OgreMain/include/OgrePass.h index f95141b93fe..a1e533845ff 100644 --- a/OgreMain/include/OgrePass.h +++ b/OgreMain/include/OgrePass.h @@ -608,41 +608,42 @@ namespace Ogre linearEnd Distance in world units at which linear fog becomes completely opaque. Only applicable if mode is FOG_LINEAR. */ + OGRE_DEPRECATED_VER( 3 ) void setFog( bool overrideScene, FogMode mode = FOG_NONE, const ColourValue &colour = ColourValue::White, Real expDensity = Real( 0.001 ), Real linearStart = 0.0, Real linearEnd = 1.0 ); /** Returns true if this pass is to override the scene fog settings. */ - bool getFogOverride() const; + OGRE_DEPRECATED_VER( 3 ) bool getFogOverride() const; /** Returns the fog mode for this pass. @note Only valid if getFogOverride is true. */ - FogMode getFogMode() const; + OGRE_DEPRECATED_VER( 3 ) FogMode getFogMode() const; /** Returns the fog colour for the scene. */ - const ColourValue &getFogColour() const; + OGRE_DEPRECATED_VER( 3 ) const ColourValue &getFogColour() const; /** Returns the fog start distance for this pass. @note Only valid if getFogOverride is true. */ - Real getFogStart() const; + OGRE_DEPRECATED_VER( 3 ) Real getFogStart() const; /** Returns the fog end distance for this pass. @note Only valid if getFogOverride is true. */ - Real getFogEnd() const; + OGRE_DEPRECATED_VER( 3 ) Real getFogEnd() const; /** Returns the fog density for this pass. @note Only valid if getFogOverride is true. */ - Real getFogDensity() const; + OGRE_DEPRECATED_VER( 3 ) Real getFogDensity() const; /// Gets the internal datablock that acts as proxy for us HlmsDatablock *_getDatablock() const; diff --git a/OgreMain/include/OgreSceneManager.h b/OgreMain/include/OgreSceneManager.h index 68127c42e89..b9e5b5a7c97 100644 --- a/OgreMain/include/OgreSceneManager.h +++ b/OgreMain/include/OgreSceneManager.h @@ -1943,6 +1943,8 @@ namespace Ogre virtual void _restoreManualHardwareResources(); /** Sets the fogging mode applied to the scene. + Deprecated in favour of Atmosphere component. See AtmosphereNpr::setSky. + @remarks This method sets up the scene-wide fogging effect. These settings apply to all geometry rendered, UNLESS the material with which it @@ -1966,29 +1968,30 @@ namespace Ogre opaque. Only applicable if mode is FOG_LINEAR. */ + OGRE_DEPRECATED_VER( 3 ) void setFog( FogMode mode = FOG_NONE, const ColourValue &colour = ColourValue::White, Real expDensity = Real( 0.001 ), Real linearStart = Real( 0.0 ), Real linearEnd = Real( 1.0 ) ); /** Returns the fog mode for the scene. */ - virtual FogMode getFogMode() const; + OGRE_DEPRECATED_VER( 3 ) virtual FogMode getFogMode() const; /** Returns the fog colour for the scene. */ - virtual const ColourValue &getFogColour() const; + OGRE_DEPRECATED_VER( 3 ) virtual const ColourValue &getFogColour() const; /** Returns the fog start distance for the scene. */ - virtual Real getFogStart() const; + OGRE_DEPRECATED_VER( 3 ) virtual Real getFogStart() const; /** Returns the fog end distance for the scene. */ - virtual Real getFogEnd() const; + OGRE_DEPRECATED_VER( 3 ) virtual Real getFogEnd() const; /** Returns the fog density for the scene. */ - virtual Real getFogDensity() const; + OGRE_DEPRECATED_VER( 3 ) virtual Real getFogDensity() const; /** Creates a new BillboardSet for use with this scene manager. @remarks diff --git a/OgreMain/include/OgreTechnique.h b/OgreMain/include/OgreTechnique.h index cd71fe4ae58..ea1b70c45a1 100644 --- a/OgreMain/include/OgreTechnique.h +++ b/OgreMain/include/OgreTechnique.h @@ -341,6 +341,7 @@ namespace Ogre property there. @see Pass::setFog */ + OGRE_DEPRECATED_VER( 3 ) void setFog( bool overrideScene, FogMode mode = FOG_NONE, const ColourValue &colour = ColourValue::White, Real expDensity = Real( 0.001 ), Real linearStart = 0.0, Real linearEnd = 1.0 ); diff --git a/OgreMain/src/OgreHlmsLowLevel.cpp b/OgreMain/src/OgreHlmsLowLevel.cpp index 463f8ea894f..739d8b97a9b 100644 --- a/OgreMain/src/OgreHlmsLowLevel.cpp +++ b/OgreMain/src/OgreHlmsLowLevel.cpp @@ -283,6 +283,12 @@ namespace Ogre mAutoParamDataSource->setCurrentPass( pass ); mAutoParamDataSource->setCurrentLightList( &renderable->getLights() ); +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( push, 0 ) +#else +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif if( pass->getFogOverride() ) { mAutoParamDataSource->setFog( pass->getFogMode(), pass->getFogColour(), @@ -296,6 +302,11 @@ namespace Ogre mCurrentSceneManager->getFogDensity(), mCurrentSceneManager->getFogStart(), mCurrentSceneManager->getFogEnd() ); } +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( pop ) +#else +# pragma GCC diagnostic pop +#endif Pass::ConstTextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); size_t unit = 0; diff --git a/OgreMain/src/OgreMaterialSerializer.cpp b/OgreMain/src/OgreMaterialSerializer.cpp index e0f04f6d32d..dcc42ec0ecc 100644 --- a/OgreMain/src/OgreMaterialSerializer.cpp +++ b/OgreMain/src/OgreMaterialSerializer.cpp @@ -627,6 +627,12 @@ namespace Ogre writeValue( pPass->getPolygonModeOverrideable() ? "on" : "off" ); } +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( push, 0 ) +#else +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // fog override if( mDefaults || pPass->getFogOverride() != false ) { @@ -659,6 +665,11 @@ namespace Ogre } } } +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( pop ) +#else +# pragma GCC diagnostic pop +#endif // GPU Vertex and Fragment program references and parameters if( pPass->hasVertexProgram() ) diff --git a/OgreMain/src/OgreSceneManager.cpp b/OgreMain/src/OgreSceneManager.cpp index 48626395b71..db54259429c 100644 --- a/OgreMain/src/OgreSceneManager.cpp +++ b/OgreMain/src/OgreSceneManager.cpp @@ -229,8 +229,20 @@ namespace Ogre mShadowCasterPlainBlackPass->setDiffuse( ColourValue::Black ); mShadowCasterPlainBlackPass->setSelfIllumination( ColourValue::Black ); mShadowCasterPlainBlackPass->setSpecular( ColourValue::Black ); + +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( push, 0 ) +#else +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // Override fog mShadowCasterPlainBlackPass->setFog( true, FOG_NONE ); +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( pop ) +#else +# pragma GCC diagnostic pop +#endif // no textures or anything else, we will bind vertex programs // every so often though } diff --git a/OgreMain/src/OgreScriptTranslator.cpp b/OgreMain/src/OgreScriptTranslator.cpp index fa756f954e4..62a51371cec 100644 --- a/OgreMain/src/OgreScriptTranslator.cpp +++ b/OgreMain/src/OgreScriptTranslator.cpp @@ -2489,7 +2489,18 @@ namespace Ogre{ ++i2; } - mPass->setFog(val, mode, clr, dens, start, end); +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( push, 0 ) +#else +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + mPass->setFog( val, mode, clr, dens, start, end ); +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +# pragma warning( pop ) +#else +# pragma GCC diagnostic pop +#endif } else compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, From 3a48d1a533da950135d6d4aac7d8868b6742bc6b Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 23 Nov 2023 19:55:49 -0300 Subject: [PATCH 094/124] Use OgreNext name --- 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 34175240d21..0ecc6229ea0 100644 --- a/Docs/src/manual/Ogre3.0.Changes.md +++ b/Docs/src/manual/Ogre3.0.Changes.md @@ -1,4 +1,4 @@ -# What's new in Ogre 3.0 {#Ogre30Changes} +# What's new in Ogre-Next 3.0 {#Ogre30Changes} @tableofcontents From d7caf256a041d3796da95639b31c4dc3572e716c Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 4 Dec 2023 11:42:56 -0300 Subject: [PATCH 095/124] Bump patch version --- OgreMain/include/OgrePrerequisites.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OgreMain/include/OgrePrerequisites.h b/OgreMain/include/OgrePrerequisites.h index aa1f9b21575..4d641d62d76 100644 --- a/OgreMain/include/OgrePrerequisites.h +++ b/OgreMain/include/OgrePrerequisites.h @@ -65,7 +65,7 @@ namespace Ogre { // Define ogre version #define OGRE_VERSION_MAJOR 2 #define OGRE_VERSION_MINOR 3 - #define OGRE_VERSION_PATCH 3 + #define OGRE_VERSION_PATCH 4 #define OGRE_VERSION_SUFFIX "" #define OGRE_VERSION_NAME "Daedalus" From 62fa784b5b7fcd2449b81e90ee67d666cf94e985 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 4 Dec 2023 11:44:00 -0300 Subject: [PATCH 096/124] [Vk]Non-coherent memory pools were being ignored This fails in latest Android Studio Simulator API_LEVEL 34 --- RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 7af8c7d8bef..d64cd98560a 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -781,7 +781,7 @@ namespace Ogre ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) ) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ) { - // addMemoryType( CPU_WRITE_PERSISTENT, memProperties, i ); + addMemoryType( CPU_WRITE_PERSISTENT, memProperties, i ); } // Find coherent memory (many desktop GPUs don't provide this) From 19c1ce7320a4cc7f45430efe04e5cbd738c365ee Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 4 Dec 2023 12:12:41 -0300 Subject: [PATCH 097/124] Change OgreNext 3.0 name to Eris Winner of https://forums.ogre3d.org/viewtopic.php?t=97169 --- OgreMain/include/OgrePrerequisites.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OgreMain/include/OgrePrerequisites.h b/OgreMain/include/OgrePrerequisites.h index 7c2e53ada7e..d633da343ce 100644 --- a/OgreMain/include/OgrePrerequisites.h +++ b/OgreMain/include/OgrePrerequisites.h @@ -73,7 +73,7 @@ namespace Ogre #define OGRE_VERSION_MAJOR 3 #define OGRE_VERSION_MINOR 0 #define OGRE_VERSION_PATCH 0 -#define OGRE_VERSION_SUFFIX "unstable" +#define OGRE_VERSION_SUFFIX "Eris" #define OGRE_VERSION_NAME "E" #define OGRE_MAKE_VERSION( maj, min, patch ) ( ( maj << 16 ) | ( min << 8 ) | patch ) From 872a8c5f0bb465d592f2ccf844f1b0416175bfbe Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 5 Dec 2023 12:02:06 -0300 Subject: [PATCH 098/124] [Vk] ALways prefer coherent memory when it's superior Fix misleading argument name in VulkanDynamicBuffer constructor. --- .../include/Vao/OgreVulkanDynamicBuffer.h | 2 +- .../Vulkan/include/Vao/OgreVulkanVaoManager.h | 7 +-- .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 50 ++++++++++++++++--- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/RenderSystems/Vulkan/include/Vao/OgreVulkanDynamicBuffer.h b/RenderSystems/Vulkan/include/Vao/OgreVulkanDynamicBuffer.h index cabb5f62b6f..c6f8680e2f4 100644 --- a/RenderSystems/Vulkan/include/Vao/OgreVulkanDynamicBuffer.h +++ b/RenderSystems/Vulkan/include/Vao/OgreVulkanDynamicBuffer.h @@ -75,7 +75,7 @@ namespace Ogre size_t addMappedRange( size_t start, size_t count ); public: - VulkanDynamicBuffer( VkDeviceMemory deviceMemory, size_t vboSize, const bool isNonCoherent, + VulkanDynamicBuffer( VkDeviceMemory deviceMemory, size_t vboSize, const bool isCoherent, const bool hasReadAccess, VulkanDevice *device ); ~VulkanDynamicBuffer(); diff --git a/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h b/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h index b6caf638950..d1c4c5eebd9 100644 --- a/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h +++ b/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h @@ -267,9 +267,10 @@ namespace Ogre FastArray mDelayedFuncs; bool mFenceFlushed; - bool mSupportsCoherentMemory; - bool mSupportsNonCoherentMemory; - bool mReadMemoryIsCoherent; + bool mSupportsCoherentMemory : 1; + bool mSupportsNonCoherentMemory : 1; + bool mPreferCoherentMemory : 1; + bool mReadMemoryIsCoherent : 1; static const uint32 VERTEX_ATTRIBUTE_INDEX[VES_COUNT]; diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 7992039b1ff..fea58bafd7b 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -824,10 +824,47 @@ namespace Ogre mSupportsNonCoherentMemory = !mBestVkMemoryTypeIndex[CPU_WRITE_PERSISTENT].empty(); mSupportsCoherentMemory = !mBestVkMemoryTypeIndex[CPU_WRITE_PERSISTENT_COHERENT].empty(); + mPreferCoherentMemory = false; + if( !mBestVkMemoryTypeIndex[CPU_WRITE_PERSISTENT_COHERENT].empty() ) + { + // When it comes to writing (and at least in theory), the following order should be + // preferred: + // + // 1 Uncached, coherent + // 2 Cached, non-coherent + // 3 Cached, coherent + // 4 Anything else (uncached, non-coherent? that doesn't make sense) + // + // "Uncached, coherent" means CPU caches are bypassed. Hence GPU doesn't have to worry about + // them and can automatically synchronize its internal caches (since there's nothing to + // synchronize). + // + // "Cached" means CPU caches are important. If it's coherent, HW (likely) needs to do heavy + // work to keep both CPU & GPU caches in sync. Hence non-coherent makes sense to be superior + // here since we just invalidate the GPU caches by hand. + // + // Now there are a few gotchas: + // + // - Whether 1 is faster than 2 mostly depends on whether the code makes correct use of + // write-combining (or else perf goes down fast). + // - Whether 2 is faster than 3 or viceversa may be HW specific. For example Intel only + // exposes Cached + Coherent and nothing else. It seems they have no performance problems + // at all. + const uint32 idx = mBestVkMemoryTypeIndex[CPU_WRITE_PERSISTENT_COHERENT].back(); + // Prefer coherent memory if it's uncached, or if we have no choice. + if( !mSupportsNonCoherentMemory || + memProperties.memoryTypes[idx].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT ) + { + mPreferCoherentMemory = true; + } + } + logManager.logMessage( "VkDevice will use coherent memory buffers: " + StringConverter::toString( mSupportsCoherentMemory ) ); logManager.logMessage( "VkDevice will use non-coherent memory buffers: " + StringConverter::toString( mSupportsNonCoherentMemory ) ); + logManager.logMessage( "VkDevice will prefer coherent memory buffers: " + + StringConverter::toString( mPreferCoherentMemory ) ); if( mBestVkMemoryTypeIndex[CPU_READ_WRITE].empty() ) { @@ -1259,8 +1296,8 @@ namespace Ogre VulkanRawBuffer VulkanVaoManager::allocateRawBuffer( VboFlag vboFlag, size_t sizeBytes, size_t alignment ) { - // Change flag if unavailable - if( vboFlag == CPU_WRITE_PERSISTENT && !mSupportsNonCoherentMemory ) + // Override what user prefers (or change if unavailable). + if( vboFlag == CPU_WRITE_PERSISTENT && mPreferCoherentMemory ) vboFlag = CPU_WRITE_PERSISTENT_COHERENT; else if( vboFlag == CPU_WRITE_PERSISTENT_COHERENT && !mSupportsCoherentMemory ) vboFlag = CPU_WRITE_PERSISTENT; @@ -2057,10 +2094,7 @@ namespace Ogre mDynamicBufferCurrentFrame = ( mDynamicBufferCurrentFrame + 1 ) % mDynamicBufferMultiplier; } //----------------------------------------------------------------------------------- - void VulkanVaoManager::_notifyNewCommandBuffer() - { - mFenceFlushed = true; - } + void VulkanVaoManager::_notifyNewCommandBuffer() { mFenceFlushed = true; } //----------------------------------------------------------------------------------- void VulkanVaoManager::getAvailableSempaphores( VkSemaphoreArray &semaphoreArray, size_t numSemaphores ) @@ -2297,8 +2331,8 @@ namespace Ogre break; } - // Change flag if unavailable - if( vboFlag == CPU_WRITE_PERSISTENT && !mSupportsNonCoherentMemory ) + // Override what user prefers (or change if unavailable). + if( vboFlag == CPU_WRITE_PERSISTENT && mPreferCoherentMemory ) vboFlag = CPU_WRITE_PERSISTENT_COHERENT; else if( vboFlag == CPU_WRITE_PERSISTENT_COHERENT && !mSupportsCoherentMemory ) vboFlag = CPU_WRITE_PERSISTENT; From 36a26183760a9bedd813acb475c79eba59599a5d Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 5 Dec 2023 12:07:06 -0300 Subject: [PATCH 099/124] Update comment --- RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index fea58bafd7b..45ab1c2829d 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -850,6 +850,8 @@ namespace Ogre // - Whether 2 is faster than 3 or viceversa may be HW specific. For example Intel only // exposes Cached + Coherent and nothing else. It seems they have no performance problems // at all. + // + // This assumes CPU write-combining is fast. If it's not, then this is wrong. const uint32 idx = mBestVkMemoryTypeIndex[CPU_WRITE_PERSISTENT_COHERENT].back(); // Prefer coherent memory if it's uncached, or if we have no choice. if( !mSupportsNonCoherentMemory || From 1f52a03d4633f0bae56ea7f4aa939af0b749ed9a Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 5 Dec 2023 14:09:23 -0300 Subject: [PATCH 100/124] [Vk] Fix flip error in conditional logic --- RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 45ab1c2829d..cc9cd3467f8 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -855,7 +855,7 @@ namespace Ogre const uint32 idx = mBestVkMemoryTypeIndex[CPU_WRITE_PERSISTENT_COHERENT].back(); // Prefer coherent memory if it's uncached, or if we have no choice. if( !mSupportsNonCoherentMemory || - memProperties.memoryTypes[idx].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT ) + !( memProperties.memoryTypes[idx].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT ) ) { mPreferCoherentMemory = true; } From 696ec720fd5a0a3fccee41d7efed4cc65292d911 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 5 Dec 2023 20:42:18 -0300 Subject: [PATCH 101/124] [Vk] Fix memory leak when using Low Level Materials with uniform params The param buffer was never flushed, never unmapped, never destroyed, and it kept growing slowly leaking RAM over time. Additionally fix validation errors of vkInvalidateMappedMemoryRanges due to incorrect handling of nonCoherentAtomSize. --- .../Vulkan/include/OgreVulkanRenderSystem.h | 36 +++++++- .../Vulkan/include/OgreVulkanUtils.h | 10 ++- RenderSystems/Vulkan/src/OgreVulkanQueue.cpp | 2 + .../Vulkan/src/OgreVulkanRenderSystem.cpp | 89 ++++++++++++++++++- .../src/Vao/OgreVulkanDynamicBuffer.cpp | 9 +- 5 files changed, 137 insertions(+), 9 deletions(-) diff --git a/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h b/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h index 6a3fbdffe0b..d0f0a460309 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h +++ b/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h @@ -78,10 +78,10 @@ namespace Ogre // TODO: AutoParamsBuffer probably belongs to MetalDevice (because it's per device?) typedef vector::type ConstBufferPackedVec; ConstBufferPackedVec mAutoParamsBuffer; + size_t mFirstUnflushedAutoParamsBuffer; size_t mAutoParamsBufferIdx; uint8 *mCurrentAutoParamsBufferPtr; size_t mCurrentAutoParamsBufferSpaceLeft; - size_t mHistoricalAutoParamsSize[60]; // For v1 rendering. v1::IndexData *mCurrentIndexBuffer; @@ -272,6 +272,40 @@ namespace Ogre uint16 variabilityMask ) override; void bindGpuProgramPassIterationParameters( GpuProgramType gptype ) override; + protected: + /** Low Level Materials use a params buffer to pass all uniforms. We emulate this using a large + const buffer to which we write to and bind the regions we need. + This is done in bindGpuProgramParameters(). + + When it runs out of space, we create another one (see mAutoParamsBuffer). + + However: + - In all cases we must flush buffers before command submission or else the cmds we're + about to execute may not see the const buffer data up to date. We don't flush in + bindGpuProgramParameters() because we could end up with lots of 4-byte flushes + which is seriously inefficient. Flushing the whole thing once at the end is better. + - We musn't grow indefinitely. On submissionType >= NewFrameIdx, we + are certain we can set mAutoParamsBufferIdx = 0 and start over. + @remarks + bindGpuProgramParameters() tries to use BT_DYNAMIC_PERSISTENT_COHERENT which doesn't need + flushing (thus we'd only care about submissionType >= NewFrameIdx to reuse memory). + + However VaoManager cannot guarantee BT_DYNAMIC_PERSISTENT_COHERENT will actually be + coherent thus we must call unmap( UO_KEEP_PERSISTENT ) anyway. + @param submissionType + See SubmissionType::SubmissionType. + */ + void flushBoundGpuProgramParameters( const SubmissionType::SubmissionType submissionType ); + + public: + /** All pending or queued buffer flushes (i.e. calls to vkFlushMappedMemoryRanges) must be done + now because we're about to submit commands for execution; and they need to see those + regions flushed. + @param submissionType + See SubmissionType::SubmissionType. + */ + void flushPendingNonCoherentFlushes( const SubmissionType::SubmissionType submissionType ); + void clearFrameBuffer( RenderPassDescriptor *renderPassDesc, TextureGpu *anyTarget, uint8 mipLevel ) override; diff --git a/RenderSystems/Vulkan/include/OgreVulkanUtils.h b/RenderSystems/Vulkan/include/OgreVulkanUtils.h index dcf285391d4..bbf3d1ad95d 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanUtils.h +++ b/RenderSystems/Vulkan/include/OgreVulkanUtils.h @@ -61,11 +61,19 @@ namespace Ogre uint32_t findMemoryType( VkPhysicalDeviceMemoryProperties &memProperties, uint32_t typeFilter, VkMemoryPropertyFlags properties ); - inline VkDeviceSize alignMemory( size_t offset, const VkDeviceSize &alignment ) + inline VkDeviceSize alignMemory( size_t offset, const VkDeviceSize alignment ) { return ( ( offset + alignment - 1 ) / alignment ) * alignment; } + inline void setAlignMemoryCoherentAtom( VkMappedMemoryRange &outMemRange, const size_t offset, + const size_t sizeBytes, const VkDeviceSize alignment ) + { + const VkDeviceSize endOffset = alignMemory( offset + sizeBytes, alignment ); + outMemRange.offset = ( offset / alignment ) * alignment; + outMemRange.size = endOffset - outMemRange.offset; + } + String getSpirvReflectError( SpvReflectResult spirvReflectResult ); VkSampleCountFlagBits getMaxUsableSampleCount( VkPhysicalDeviceProperties &physicalDeviceProperties, diff --git a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp index 782bcf7bded..327bc13047c 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp @@ -1187,6 +1187,8 @@ namespace Ogre { endCommandBuffer(); + mRenderSystem->flushPendingNonCoherentFlushes( submissionType ); + // We must reset all bindings or else after 3 (mDynamicBufferCurrentFrame) frames // there could be dangling API handles left hanging around indefinitely that // may be collected by RootLayouts that use more slots than they need diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index e4f274483ed..e82c2d5000c 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -161,6 +161,7 @@ namespace Ogre mVulkanProgramFactory2( 0 ), mVulkanProgramFactory3( 0 ), mVkInstance( 0 ), + mFirstUnflushedAutoParamsBuffer( 0 ), mAutoParamsBufferIdx( 0 ), mCurrentAutoParamsBufferPtr( 0 ), mCurrentAutoParamsBufferSpaceLeft( 0 ), @@ -288,6 +289,18 @@ namespace Ogre if( !mDevice ) return; + for( ConstBufferPacked *constBuffer : mAutoParamsBuffer ) + { + if( constBuffer->getMappingState() != MS_UNMAPPED ) + constBuffer->unmap( UO_UNMAP_ALL ); + mVaoManager->destroyConstBuffer( constBuffer ); + } + mAutoParamsBuffer.clear(); + mFirstUnflushedAutoParamsBuffer = 0u; + mAutoParamsBufferIdx = 0u; + mCurrentAutoParamsBufferPtr = 0; + mCurrentAutoParamsBufferSpaceLeft = 0; + mDevice->stall(); { @@ -2316,13 +2329,21 @@ namespace Ogre { if( mAutoParamsBufferIdx >= mAutoParamsBuffer.size() ) { + // Ask for a coherent buffer to avoid excessive flushing. Note: VaoManager may ignore + // this request if the GPU can't provide coherent memory and we must flush anyway. ConstBufferPacked *constBuffer = mVaoManager->createConstBuffer( std::max( 512u * 1024u, bytesToWrite ), - BT_DYNAMIC_PERSISTENT, 0, false ); + BT_DYNAMIC_PERSISTENT_COHERENT, 0, false ); mAutoParamsBuffer.push_back( constBuffer ); } ConstBufferPacked *constBuffer = mAutoParamsBuffer[mAutoParamsBufferIdx]; + + // This should be near-impossible to trigger because most Const Buffers are <= 64kb + // and we reserver 512kb per const buffer. A Low Level Material using a Params buffer + // with > 64kb is an edge case we don't care handling. + OGRE_ASSERT_LOW( bytesToWrite <= constBuffer->getTotalSizeBytes() ); + mCurrentAutoParamsBufferPtr = reinterpret_cast( constBuffer->map( 0, constBuffer->getNumElements() ) ); mCurrentAutoParamsBufferSpaceLeft = constBuffer->getTotalSizeBytes(); @@ -2332,7 +2353,7 @@ namespace Ogre shader->updateBuffers( params, mCurrentAutoParamsBufferPtr ); - assert( dynamic_cast( + OGRE_ASSERT_HIGH( dynamic_cast( mAutoParamsBuffer[mAutoParamsBufferIdx - 1u] ) ); VulkanConstBufferPacked *constBuffer = @@ -2357,6 +2378,70 @@ namespace Ogre } } //------------------------------------------------------------------------- + void VulkanRenderSystem::flushBoundGpuProgramParameters( + const SubmissionType::SubmissionType submissionType ) + { + bool bWillReuseLastBuffer = false; + + const size_t maxBufferToFlush = mAutoParamsBufferIdx; + for( size_t i = mFirstUnflushedAutoParamsBuffer; i < maxBufferToFlush; ++i ) + { + ConstBufferPacked *constBuffer = mAutoParamsBuffer[i]; + if( i + 1u != maxBufferToFlush ) + { + // Flush whole buffer. + constBuffer->unmap( UO_KEEP_PERSISTENT ); + } + else + { + // Last buffer. Partial flush. + const size_t bytesToFlush = + constBuffer->getTotalSizeBytes() - mCurrentAutoParamsBufferSpaceLeft; + + constBuffer->unmap( UO_KEEP_PERSISTENT, 0u, bytesToFlush ); + if( submissionType <= SubmissionType::FlushOnly && + mCurrentAutoParamsBufferSpaceLeft >= 4u ) + { + // Map again so we can continue from where we left off. + + // If the assert triggers then getNumElements is not in bytes and our math is wrong. + OGRE_ASSERT_LOW( constBuffer->getBytesPerElement() == 1u ); + constBuffer->regressFrame(); + mCurrentAutoParamsBufferPtr = reinterpret_cast( + constBuffer->map( bytesToFlush, constBuffer->getNumElements() - bytesToFlush ) ); + mCurrentAutoParamsBufferSpaceLeft = constBuffer->getNumElements() - bytesToFlush; + bWillReuseLastBuffer = true; + } + else + { + mCurrentAutoParamsBufferSpaceLeft = 0u; + mCurrentAutoParamsBufferPtr = 0; + } + } + } + + if( submissionType >= SubmissionType::NewFrameIdx ) + { + mAutoParamsBufferIdx = 0u; + mFirstUnflushedAutoParamsBuffer = 0u; + } + else + { + // If maxBufferToFlush == 0 then bindGpuProgramParameters() was never called this round + // and bWillReuseLastBuffer can't be true. + if( bWillReuseLastBuffer ) + mFirstUnflushedAutoParamsBuffer = maxBufferToFlush - 1u; + else + mFirstUnflushedAutoParamsBuffer = maxBufferToFlush; + } + } + //------------------------------------------------------------------------- + void VulkanRenderSystem::flushPendingNonCoherentFlushes( + const SubmissionType::SubmissionType submissionType ) + { + flushBoundGpuProgramParameters( submissionType ); + } + //------------------------------------------------------------------------- void VulkanRenderSystem::bindGpuProgramPassIterationParameters( GpuProgramType gptype ) {} //------------------------------------------------------------------------- void VulkanRenderSystem::clearFrameBuffer( RenderPassDescriptor *renderPassDesc, diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanDynamicBuffer.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanDynamicBuffer.cpp index 9003aacf2e7..e3b04d59f0d 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanDynamicBuffer.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanDynamicBuffer.cpp @@ -88,8 +88,8 @@ namespace Ogre VkMappedMemoryRange memRange; makeVkStruct( memRange, VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ); memRange.memory = mDeviceMemory; - memRange.offset = start; - memRange.size = alignMemory( count, mDevice->mDeviceProperties.limits.nonCoherentAtomSize ); + setAlignMemoryCoherentAtom( memRange, start, count, + mDevice->mDeviceProperties.limits.nonCoherentAtomSize ); VkResult result = vkInvalidateMappedMemoryRanges( mDevice->mDevice, 1u, &memRange ); checkVkResult( result, "vkInvalidateMappedMemoryRanges" ); } @@ -107,9 +107,8 @@ namespace Ogre mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; mappedRange.pNext = 0; mappedRange.memory = mDeviceMemory; - mappedRange.offset = mMappedRanges[ticket].start + start; - mappedRange.size = - alignMemory( count, mDevice->mDeviceProperties.limits.nonCoherentAtomSize ); + setAlignMemoryCoherentAtom( mappedRange, mMappedRanges[ticket].start + start, count, + mDevice->mDeviceProperties.limits.nonCoherentAtomSize ); VkResult result = vkFlushMappedMemoryRanges( mDevice->mDevice, 1u, &mappedRange ); checkVkResult( result, "vkFlushMappedMemoryRanges" ); } From ab6cc9f2c55e77c9bc7561176933825161c5a19e Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 5 Dec 2023 20:45:11 -0300 Subject: [PATCH 102/124] Fix wrong OGRE_VERSION_NAME --- OgreMain/include/OgrePrerequisites.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OgreMain/include/OgrePrerequisites.h b/OgreMain/include/OgrePrerequisites.h index d633da343ce..cb713e1c895 100644 --- a/OgreMain/include/OgrePrerequisites.h +++ b/OgreMain/include/OgrePrerequisites.h @@ -73,8 +73,8 @@ namespace Ogre #define OGRE_VERSION_MAJOR 3 #define OGRE_VERSION_MINOR 0 #define OGRE_VERSION_PATCH 0 -#define OGRE_VERSION_SUFFIX "Eris" -#define OGRE_VERSION_NAME "E" +#define OGRE_VERSION_SUFFIX "unstable" +#define OGRE_VERSION_NAME "Eris" #define OGRE_MAKE_VERSION( maj, min, patch ) ( ( maj << 16 ) | ( min << 8 ) | patch ) #define OGRE_VERSION ( ( OGRE_VERSION_MAJOR << 16 ) | ( OGRE_VERSION_MINOR << 8 ) | OGRE_VERSION_PATCH ) From dd50b3d7bbd7601b7101114f9d13856936b0bc7f Mon Sep 17 00:00:00 2001 From: cryham Date: Sun, 10 Dec 2023 00:02:48 +0100 Subject: [PATCH 103/124] add Stunt Rally 3 screen --- Docs/frontpage/StuntRally3.jpg | Bin 0 -> 320028 bytes README.md | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 Docs/frontpage/StuntRally3.jpg diff --git a/Docs/frontpage/StuntRally3.jpg b/Docs/frontpage/StuntRally3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d4499e8089ccb0dc9c15e04eb8049a6d515f95dc GIT binary patch literal 320028 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

x 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

KiRxAZkW_}(Uc;3JK= zJ^SMWuOl?aaviYmU-9L2+VMJBBhx(C3mXuD832?hzzR z8Az`-wHZ@-qoxv444ieOCp3<6OeV4@WTzFKImtD4X5y$zx#S5N?vc1v6wOYsMllSH1F0C*!2$KO2bR9EH@cbTi0$+FSJ-�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 literal 0 HcmV?d00001 diff --git a/README.md b/README.md index d6746f71a16..cfa92f219ae 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,10 @@ For a list of samples and their demonstrated features, refer to the [samples sec ![](./Docs/frontpage/SunsetRangers.jpg) +## [Stunt Rally 3](https://stuntrally.tuxfamily.org/) + +![](./Docs/frontpage/StuntRally3.jpg) + # Features From 49bf397d15fdc2b0578f5f2baa488fd76ec15646 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 2 Jan 2024 15:41:46 -0300 Subject: [PATCH 104/124] Add SceneNode::getAttachments --- OgreMain/include/OgreSceneNode.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OgreMain/include/OgreSceneNode.h b/OgreMain/include/OgreSceneNode.h index 2000699a5b7..9af91c12bfa 100644 --- a/OgreMain/include/OgreSceneNode.h +++ b/OgreMain/include/OgreSceneNode.h @@ -152,6 +152,8 @@ namespace Ogre /// @copydoc Node::_callMemoryChangeListeners void _callMemoryChangeListeners() override; + const ObjectVec &getAttachments() { return mAttachments; } + /** Retrieves an iterator which can be used to efficiently step through the objects attached to this node. @remarks From 1164584f8206a74609db0ca67b930b023c47c07b Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 15 Jan 2024 11:35:15 -0300 Subject: [PATCH 105/124] [Android] Fix crash on some devices --- .../Template/app/src/main/jni/AndroidMain.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Samples/2.0/AndroidAppTemplate/Template/app/src/main/jni/AndroidMain.cpp b/Samples/2.0/AndroidAppTemplate/Template/app/src/main/jni/AndroidMain.cpp index bd2bb616a20..cf508cc311b 100644 --- a/Samples/2.0/AndroidAppTemplate/Template/app/src/main/jni/AndroidMain.cpp +++ b/Samples/2.0/AndroidAppTemplate/Template/app/src/main/jni/AndroidMain.cpp @@ -163,7 +163,10 @@ void handle_cmd( android_app *app, int32_t cmd ) case APP_CMD_CONTENT_RECT_CHANGED: case APP_CMD_WINDOW_RESIZED: __android_log_print( ANDROID_LOG_INFO, "OgreSamples", "windowMovedOrResized: %d", cmd ); - g_appController.mGraphicsSystem->getRenderWindow()->windowMovedOrResized(); + // We got crash reports from getting _RESIZED events w/ mGraphicsSystem being a nullptr. + // That's Android for you. + if( g_appController.mGraphicsSystem && g_appController.mGraphicsSystem->getRenderWindow() ) + g_appController.mGraphicsSystem->getRenderWindow()->windowMovedOrResized(); break; default: __android_log_print( ANDROID_LOG_INFO, "OgreSamples", "event not handled: %d", cmd ); From fbbea6c8e728ee5d945aa47bb140c1e98ef208e2 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 30 Jan 2024 15:17:52 -0300 Subject: [PATCH 106/124] [D3D11] Fix Unlit rendering bugs when using InstancedStereo --- .../Media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/Media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl b/Samples/Media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl index b0f14fa7638..ac2c4d87e07 100644 --- a/Samples/Media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl +++ b/Samples/Media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl @@ -47,7 +47,7 @@ #define inVs_stereoDrawId input.drawId @end -#define finalDrawId input.drawId +#define finalDrawId inVs_drawId @foreach( hlms_uv_count, n ) #define inVs_uv@n input.uv@n@end From a2326ceecee2b1a936f6b2358559a3b7d2a36ce8 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 4 Feb 2024 01:01:32 -0300 Subject: [PATCH 107/124] Port python script to 3.0 --- Scripts/BuildScripts/generate_build_scripts.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Scripts/BuildScripts/generate_build_scripts.py b/Scripts/BuildScripts/generate_build_scripts.py index 3ce12053fcc..e2702290292 100755 --- a/Scripts/BuildScripts/generate_build_scripts.py +++ b/Scripts/BuildScripts/generate_build_scripts.py @@ -20,6 +20,7 @@ def getMercurialBranchName(): exitCode = process.wait() if exitCode == 0: + output = output.decode() branchName = output.replace( '\n', '' ) return branchName else: @@ -32,6 +33,7 @@ def getGitBranchName(): exitCode = process.wait() if exitCode == 0: + output = output.decode() branchName = output.replace( '\n', '' ) return branchName else: From 488f0473145d4a6dd6f68e9bf34f854866f5c34f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 4 Feb 2024 01:01:53 -0300 Subject: [PATCH 108/124] Add VS2022 build scripts --- .../BuildScripts/generate_build_scripts.py | 1 + ...build_ogre_Visual_Studio_17_2022_Win32.bat | 71 +++++++++++++++++++ .../build_ogre_Visual_Studio_17_2022_x64.bat | 71 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_Win32.bat create mode 100644 Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_x64.bat diff --git a/Scripts/BuildScripts/generate_build_scripts.py b/Scripts/BuildScripts/generate_build_scripts.py index e2702290292..5971510d223 100755 --- a/Scripts/BuildScripts/generate_build_scripts.py +++ b/Scripts/BuildScripts/generate_build_scripts.py @@ -71,6 +71,7 @@ def getGitBranchName(): generators = \ [ + 'Visual Studio 17 2022', 'Visual Studio 16 2019', 'Visual Studio 15 2017', 'Visual Studio 14 2015', diff --git a/Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_Win32.bat b/Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_Win32.bat new file mode 100644 index 00000000000..2d8b1ae7afe --- /dev/null +++ b/Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_Win32.bat @@ -0,0 +1,71 @@ + +@echo off +SETLOCAL + +set OGRE_BRANCH_NAME=master +set GENERATOR="Visual Studio 17 2022" +set PLATFORM=Win32 + +set CMAKE_BIN_x86="C:\Program Files (x86)\CMake\bin\cmake.exe" +set CMAKE_BIN_x64="C:\Program Files\CMake\bin\cmake.exe" +IF EXIST %CMAKE_BIN_x64% ( + echo CMake 64-bit detected + set CMAKE_BIN=%CMAKE_BIN_x64% +) ELSE ( + IF EXIST %CMAKE_BIN_x86% ( + echo CMake 32-bit detected + set CMAKE_BIN=%CMAKE_BIN_x86% + ) ELSE ( + echo Cannot detect either %CMAKE_BIN_x86% or + echo %CMAKE_BIN_x64% make sure CMake is installed + EXIT /B 1 + ) +) +echo Using CMake at %CMAKE_BIN% + +mkdir Ogre +cd Ogre +IF NOT EXIST ogre-next-deps ( + mkdir ogre-next-deps + echo --- Cloning ogre-next-deps --- + git clone --recurse-submodules --shallow-submodules https://github.com/OGRECave/ogre-next-deps +) ELSE ( + echo --- ogre-next-deps repo detected. Cloning skipped --- +) +cd ogre-next-deps +mkdir build +cd build +echo --- Building ogre-next-deps --- +%CMAKE_BIN% -G %GENERATOR% -A %PLATFORM% .. +%CMAKE_BIN% --build . --config Debug +%CMAKE_BIN% --build . --target install --config Debug +%CMAKE_BIN% --build . --config Release +%CMAKE_BIN% --build . --target install --config Release + +cd ../../ +IF NOT EXIST ogre-next ( + echo --- Cloning Ogre master --- + git clone --branch %OGRE_BRANCH_NAME% https://github.com/OGRECave/ogre-next +) +cd ogre-next +IF NOT EXIST Dependencies ( + mklink /D Dependencies ..\ogre-next-deps\build\ogredeps + IF ERRORLEVEL 1 ( + echo Failed to create Dependency directory symlink. Run the script as Administrator. + EXIT /B 1 + ) +) +mkdir build +cd build +echo --- Running CMake configure --- +%CMAKE_BIN% -D OGRE_CONFIG_THREAD_PROVIDER=0 -D OGRE_CONFIG_THREADS=0 -D OGRE_BUILD_COMPONENT_SCENE_FORMAT=1 -D OGRE_BUILD_SAMPLES2=1 -D OGRE_BUILD_TESTS=1 -D OGRE_DEPENDENCIES_DIR=..\..\ogre-next-deps\build\ogredeps -G %GENERATOR% -A %PLATFORM% .. +echo --- Building Ogre (Debug) --- +%CMAKE_BIN% --build . --config Debug +%CMAKE_BIN% --build . --target install --config Debug +echo --- Building Ogre (Release) --- +%CMAKE_BIN% --build . --config Release +%CMAKE_BIN% --build . --target install --config Release + +echo Done! + +ENDLOCAL diff --git a/Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_x64.bat b/Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_x64.bat new file mode 100644 index 00000000000..02914738e1a --- /dev/null +++ b/Scripts/BuildScripts/output/build_ogre_Visual_Studio_17_2022_x64.bat @@ -0,0 +1,71 @@ + +@echo off +SETLOCAL + +set OGRE_BRANCH_NAME=master +set GENERATOR="Visual Studio 17 2022" +set PLATFORM=x64 + +set CMAKE_BIN_x86="C:\Program Files (x86)\CMake\bin\cmake.exe" +set CMAKE_BIN_x64="C:\Program Files\CMake\bin\cmake.exe" +IF EXIST %CMAKE_BIN_x64% ( + echo CMake 64-bit detected + set CMAKE_BIN=%CMAKE_BIN_x64% +) ELSE ( + IF EXIST %CMAKE_BIN_x86% ( + echo CMake 32-bit detected + set CMAKE_BIN=%CMAKE_BIN_x86% + ) ELSE ( + echo Cannot detect either %CMAKE_BIN_x86% or + echo %CMAKE_BIN_x64% make sure CMake is installed + EXIT /B 1 + ) +) +echo Using CMake at %CMAKE_BIN% + +mkdir Ogre +cd Ogre +IF NOT EXIST ogre-next-deps ( + mkdir ogre-next-deps + echo --- Cloning ogre-next-deps --- + git clone --recurse-submodules --shallow-submodules https://github.com/OGRECave/ogre-next-deps +) ELSE ( + echo --- ogre-next-deps repo detected. Cloning skipped --- +) +cd ogre-next-deps +mkdir build +cd build +echo --- Building ogre-next-deps --- +%CMAKE_BIN% -G %GENERATOR% -A %PLATFORM% .. +%CMAKE_BIN% --build . --config Debug +%CMAKE_BIN% --build . --target install --config Debug +%CMAKE_BIN% --build . --config Release +%CMAKE_BIN% --build . --target install --config Release + +cd ../../ +IF NOT EXIST ogre-next ( + echo --- Cloning Ogre master --- + git clone --branch %OGRE_BRANCH_NAME% https://github.com/OGRECave/ogre-next +) +cd ogre-next +IF NOT EXIST Dependencies ( + mklink /D Dependencies ..\ogre-next-deps\build\ogredeps + IF ERRORLEVEL 1 ( + echo Failed to create Dependency directory symlink. Run the script as Administrator. + EXIT /B 1 + ) +) +mkdir build +cd build +echo --- Running CMake configure --- +%CMAKE_BIN% -D OGRE_CONFIG_THREAD_PROVIDER=0 -D OGRE_CONFIG_THREADS=0 -D OGRE_BUILD_COMPONENT_SCENE_FORMAT=1 -D OGRE_BUILD_SAMPLES2=1 -D OGRE_BUILD_TESTS=1 -D OGRE_DEPENDENCIES_DIR=..\..\ogre-next-deps\build\ogredeps -G %GENERATOR% -A %PLATFORM% .. +echo --- Building Ogre (Debug) --- +%CMAKE_BIN% --build . --config Debug +%CMAKE_BIN% --build . --target install --config Debug +echo --- Building Ogre (Release) --- +%CMAKE_BIN% --build . --config Release +%CMAKE_BIN% --build . --target install --config Release + +echo Done! + +ENDLOCAL From 2b6d5b07c1a274d9aa5cf459e0aa02715c1c7693 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 18 Feb 2024 19:00:50 -0300 Subject: [PATCH 109/124] Fix potential crash when setting a datablock to have no textures As a precondition, the datablock must've had textures before, the datablock ended up fully loaded and baked with textures, and not be running on OpenGL. --- .../Hlms/Common/include/OgreHlmsTextureBaseClass.inl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Components/Hlms/Common/include/OgreHlmsTextureBaseClass.inl b/Components/Hlms/Common/include/OgreHlmsTextureBaseClass.inl index 47f56fb08d7..d10af2a3f88 100644 --- a/Components/Hlms/Common/include/OgreHlmsTextureBaseClass.inl +++ b/Components/Hlms/Common/include/OgreHlmsTextureBaseClass.inl @@ -288,9 +288,15 @@ namespace Ogre else if( !mSamplersDescSet || *mSamplersDescSet != baseSampler ) { if( mSamplersDescSet ) + { hlmsManager->destroyDescriptorSetSampler( mSamplersDescSet ); - mSamplersDescSet = hlmsManager->getDescriptorSetSampler( baseSampler ); - needsRecalculateHash = true; + mSamplersDescSet = 0; + } + if( !baseSampler.mSamplers.empty() ) + { + mSamplersDescSet = hlmsManager->getDescriptorSetSampler( baseSampler ); + needsRecalculateHash = true; + } } return needsRecalculateHash; From 5270e7d2fd747c640cc82d9483a967c1e8d9af6a Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Mon, 26 Feb 2024 19:21:48 -0300 Subject: [PATCH 110/124] [Vk] Fix assert in complex conditions VulkanRenderSystem::flushBoundGpuProgramParameters would assert inside constBuffer->regressFrame(); The steps to trigger are: 1. Use mAutoParamsBuffer (i.e. a low level material with parameters) so that mFirstUnflushedAutoParamsBuffer becomes non-zero. 2. Stall twice in a row without presenting to screen. In real world scenarios this could happen if a lot of texture memory is streaming and TextureGpuManager is forced to stall. --- .../Vulkan/include/OgreVulkanRenderSystem.h | 1 - RenderSystems/Vulkan/src/OgreVulkanDevice.cpp | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h b/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h index d0f0a460309..fbd30244256 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h +++ b/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h @@ -272,7 +272,6 @@ namespace Ogre uint16 variabilityMask ) override; void bindGpuProgramPassIterationParameters( GpuProgramType gptype ) override; - protected: /** Low Level Materials use a params buffer to pass all uniforms. We emulate this using a large const buffer to which we write to and bind the regions we need. This is done in bindGpuProgramParameters(). diff --git a/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp b/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp index 14081c6ab85..bcdc6299357 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp @@ -678,6 +678,20 @@ namespace Ogre //------------------------------------------------------------------------- void VulkanDevice::stall() { + // We must call flushBoundGpuProgramParameters() now because commitAndNextCommandBuffer() will + // call flushBoundGpuProgramParameters( SubmissionType::FlushOnly ). + // + // Unfortunately that's not enough because that assumes VaoManager::mFrameCount + // won't change (which normally wouldn't w/ FlushOnly). However our caller is + // about to do mFrameCount += mDynamicBufferMultiplier. + // + // The solution is to tell flushBoundGpuProgramParameters() we're changing frame idx. + // Calling it again becomes a no-op since mFirstUnflushedAutoParamsBuffer becomes 0. + // + // We also *want* mCurrentAutoParamsBufferPtr to become nullptr since it can be reused from + // scratch. Because we're stalling, it is safe to do so. + mRenderSystem->flushBoundGpuProgramParameters( SubmissionType::NewFrameIdx ); + // We must flush the cmd buffer and our bindings because we take the // moment to delete all delayed buffers and API handles after a stall. // From 4996577a4c1d66da3d922b7337505099462b97b9 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Wed, 28 Feb 2024 18:30:40 +0100 Subject: [PATCH 111/124] Fixed infinite loop in DeflateStream::read(buf, count), when called with too large buffer, as for example does DataStream::getAsString() --- 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 8bd4cfcff4c..b2389624053 100644 --- a/OgreMain/src/OgreDeflate.cpp +++ b/OgreMain/src/OgreDeflate.cpp @@ -239,7 +239,7 @@ namespace Ogre mZStream->next_in = mTmp; } - if( mZStream->avail_in ) + if( mZStream->avail_in || mZStream->avail_out ) { const uint32 availpre = mZStream->avail_out; const int status = inflate( mZStream, Z_SYNC_FLUSH ); From dff1598c9beca7b88ceb0df74b367d035bba34d0 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 29 Feb 2024 12:44:16 -0300 Subject: [PATCH 112/124] Do not link against xcb in Static Builds on Apple platforms --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c86f891afc..570e24b3017 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,7 +301,7 @@ set(OGRE_Paging_LIBRARIES ${OGRE_NEXT}Paging) set(OGRE_Terrain_LIBRARIES ${OGRE_NEXT}Terrain) set(OGRE_Volume_LIBRARIES ${OGRE_NEXT}Volume) -if( OGRE_STATIC AND UNIX AND NOT OGRE_CONFIG_UNIX_NO_X11 ) +if( OGRE_STATIC AND UNIX AND NOT APPLE AND NOT OGRE_CONFIG_UNIX_NO_X11 ) set( OGRE_LIBRARIES ${OGRE_LIBRARIES} xcb xcb-randr ) endif() From ef5f3e7ae395db1c91a968367922ef9ef6be08c3 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 29 Feb 2024 14:51:31 -0300 Subject: [PATCH 113/124] Fix Decals broken in Terra --- Docs/src/manual/Ogre3.0.Changes.md | 6 ++++++ .../src/Terra/Hlms/OgreHlmsTerra.cpp | 1 + .../Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any | 8 +++----- .../Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any | 13 +++++++++---- .../Hlms/Terra/Any/800.PixelShader_piece_ps.any | 2 ++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Docs/src/manual/Ogre3.0.Changes.md b/Docs/src/manual/Ogre3.0.Changes.md index 0ecc6229ea0..811f2d8a909 100644 --- a/Docs/src/manual/Ogre3.0.Changes.md +++ b/Docs/src/manual/Ogre3.0.Changes.md @@ -48,6 +48,12 @@ Default material BRDF settings have changed in 3.0; thus materials will look dif 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. +## Hlms Shader piece changes + +The piece block `LoadNormalData` got split into `LoadGeomNormalData` & `LoadNormalData` in order to support Decals in Terra. + +If you were overriding `LoadNormalData` in a custom piece, make sure to account for the new `LoadGeomNormalData`. + ## Move to C++11 and general cleanup Lots of dead \& long-deprecated code was removed. diff --git a/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/OgreHlmsTerra.cpp b/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/OgreHlmsTerra.cpp index d39ea869474..dbc82f6e17c 100644 --- a/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/OgreHlmsTerra.cpp +++ b/Samples/2.0/Tutorials/Tutorial_Terrain/src/Terra/Hlms/OgreHlmsTerra.cpp @@ -783,6 +783,7 @@ namespace Ogre outLibraryFoldersPaths.push_back( "Hlms/Pbs/Any/Atmosphere" ); #endif outLibraryFoldersPaths.push_back( "Hlms/Pbs/Any/Main" ); + outLibraryFoldersPaths.push_back( "Hlms/Pbs/" + shaderSyntax ); outLibraryFoldersPaths.push_back( "Hlms/Terra/Any" ); // Fill the data folder path diff --git a/Samples/Media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any b/Samples/Media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any index da650d5b98d..194503bda24 100644 --- a/Samples/Media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any +++ b/Samples/Media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any @@ -69,17 +69,15 @@ float3 absLocalPos = abs( localPos.xyz ); bool isOutsideDecal = absLocalPos.x > 0.5f || absLocalPos.y > 0.5f || absLocalPos.z > 0.5f; - //Mask away objects looking away from the decal. Please note that inPs.normal is not unit-length - //and is before any TBN for normal mapping. In other words it's the geometric normal - //geomNormal is not available because it gets decalred after decals run + //Mask away objects looking away from the decal. //We assume invWorldView is orthogonal, thus the transpose = inverse, hance invWorldView1.xyz //works as the decal's direction // //Use a smooth fade to avoid flickering due to floating point precision when the normal //and the decal are perpendicular to each other. (tolerance set to 0.0002) midf3 decalDir = normalize( midf3_c( invWorldView1.xyz ) ); - //isOutsideDecal = dot( decalDir.xyz, inPs.normal.xyz ) <= 0.0 ? true : isOutsideDecal; - midf normalAway = saturate( (dot( decalDir.xyz, inPs.normal.xyz ) + _h( 0.0002 ) ) / _h( 0.0002 ) ); + //isOutsideDecal = dot( decalDir.xyz, pixelData.geomNormal.xyz ) <= 0.0 ? true : isOutsideDecal; + midf normalAway = saturate( (dot( decalDir.xyz, pixelData.geomNormal.xyz ) + _h( 0.0002 ) ) / _h( 0.0002 ) ); normalAway = isOutsideDecal ? _h( 0.0f ) : normalAway; midf decalMask = normalAway; 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 99752eb78ca..82b650406bc 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 @@ -371,11 +371,12 @@ @piece( two_sided_flip_normal )* (gl_FrontFacing ? 1.0 : -1.0)@end @end @end +@piece( LoadGeomNormalData ) + // Geometric normal + pixelData.geomNormal = normalize( inPs.normal ) @insertpiece( two_sided_flip_normal ); +@end @piece( LoadNormalData ) - @property( !normal_map ) - // Geometric normal - pixelData.normal = normalize( inPs.normal ) @insertpiece( two_sided_flip_normal ); - @else + @property( normal_map ) //Normal mapping. pixelData.geomNormal = normalize( inPs.normal ) @insertpiece( two_sided_flip_normal ); midf3 vTangent = normalize( inPs.tangent ); @@ -791,6 +792,10 @@ pixelData.specular.xyz = float3( 0.0f, 0.0f, 0.0f ); @end + @property( !hlms_use_prepass ) + @insertpiece( LoadGeomNormalData ) + @end + @insertpiece( forwardPlusDoDecals ) @property( !hlms_use_prepass ) 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 fff0d10f965..ff5b8419ca1 100644 --- a/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any +++ b/Samples/Media/Hlms/Terra/Any/800.PixelShader_piece_ps.any @@ -182,6 +182,7 @@ @end @end +@undefpiece( LoadGeomNormalData ) @undefpiece( LoadNormalData ) @piece( LoadNormalData ) // Geometric normal @@ -227,6 +228,7 @@ @insertpiece( LoadDetailWeights ) @property( !hlms_use_prepass ) + @insertpiece( LoadGeomNormalData ) @insertpiece( LoadNormalData ) @insertpiece( SampleAndApplyDetailNormalMaps@property( detail_triplanar_normal )Triplanar@end ) @end From 663d5fdd481a8fb30e96030e545e9c35bddc4627 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sun, 25 Feb 2024 14:39:12 -0300 Subject: [PATCH 114/124] Fix build errors when building against FreeImageRe fork Prioritize "FreeImage" over "freeimage" spelling when finding libraries On Linux, we want CMake to pick up the library built by ogre-next-deps, not the one installed in the system. Add JPEG XR support --- CMake/Packages/FindFreeImage.cmake | 8 ++++---- OgreMain/src/OgreFreeImageCodec2.cpp | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CMake/Packages/FindFreeImage.cmake b/CMake/Packages/FindFreeImage.cmake index 2f907b718de..5e3691e1027 100644 --- a/CMake/Packages/FindFreeImage.cmake +++ b/CMake/Packages/FindFreeImage.cmake @@ -31,17 +31,17 @@ clear_if_changed(FreeImage_PREFIX_PATH FreeImage_INCLUDE_DIR ) -set(FreeImage_LIBRARY_NAMES freeimage freeimageLib FreeImage FreeImageLib) +set(FreeImage_LIBRARY_NAMES FreeImage freeimage freeimageLib FreeImageLib) get_debug_names(FreeImage_LIBRARY_NAMES) use_pkgconfig(FreeImage_PKGC freeimage) findpkg_framework(FreeImage) -find_path(FreeImage_INCLUDE_DIR NAMES FreeImage.h HINTS ${FreeImage_INC_SEARCH_PATH} ${FreeImage_PKGC_INCLUDE_DIRS}) +find_path(FreeImage_INCLUDE_DIR NAMES FreeImage.h HINTS${FreeImage_INC_SEARCH_PATH} ${FreeImage_PKGC_INCLUDE_DIRS}) -find_library(FreeImage_LIBRARY_REL NAMES ${FreeImage_LIBRARY_NAMES} HINTS ${FreeImage_LIB_SEARCH_PATH} ${FreeImage_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" Release RelWithDebInfo MinSizeRel) -find_library(FreeImage_LIBRARY_DBG NAMES ${FreeImage_LIBRARY_NAMES_DBG} HINTS ${FreeImage_LIB_SEARCH_PATH} ${FreeImage_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" Debug) +find_library(FreeImage_LIBRARY_REL NAMES ${FreeImage_LIBRARY_NAMES} HINTS ${OGRE_DEP_SEARCH_PATH} ${FreeImage_LIB_SEARCH_PATH} ${FreeImage_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" Release RelWithDebInfo MinSizeRel) +find_library(FreeImage_LIBRARY_DBG NAMES ${FreeImage_LIBRARY_NAMES_DBG} HINTS ${OGRE_DEP_SEARCH_PATH} ${FreeImage_LIB_SEARCH_PATH} ${FreeImage_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" Debug) make_library_set(FreeImage_LIBRARY) diff --git a/OgreMain/src/OgreFreeImageCodec2.cpp b/OgreMain/src/OgreFreeImageCodec2.cpp index dd3143d1598..3261cacf4a7 100644 --- a/OgreMain/src/OgreFreeImageCodec2.cpp +++ b/OgreMain/src/OgreFreeImageCodec2.cpp @@ -424,12 +424,12 @@ namespace Ogre // write data into memory FreeImage_SaveToMemory( (FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, mem ); // Grab data information - BYTE *data; - DWORD size; + uint8_t *data; + uint32_t size; FreeImage_AcquireMemory( mem, &data, &size ); // Copy data into our own buffer // Because we're asking MemoryDataStream to free this, must create in a compatible way - BYTE *ourData = OGRE_ALLOC_T( BYTE, size, MEMCATEGORY_GENERAL ); + uint8_t *ourData = OGRE_ALLOC_T( uint8_t, size, MEMCATEGORY_GENERAL ); memcpy( ourData, data, size ); // Wrap data in stream, tell it to free on close DataStreamPtr outstream( OGRE_NEW MemoryDataStream( ourData, size, true ) ); @@ -456,7 +456,7 @@ namespace Ogre MemoryDataStream memStream( input, true ); FIMEMORY *fiMem = - FreeImage_OpenMemory( memStream.getPtr(), static_cast( memStream.size() ) ); + FreeImage_OpenMemory( memStream.getPtr(), static_cast( memStream.size() ) ); FIBITMAP *fiBitmap = FreeImage_LoadFromMemory( (FREE_IMAGE_FORMAT)mFreeImageType, fiMem ); if( !fiBitmap ) { @@ -633,8 +633,8 @@ namespace Ogre //--------------------------------------------------------------------- String FreeImageCodec2::magicNumberToFileExt( const char *magicNumberPtr, size_t maxbytes ) const { - FIMEMORY *fiMem = FreeImage_OpenMemory( (BYTE *)const_cast( magicNumberPtr ), - static_cast( maxbytes ) ); + FIMEMORY *fiMem = FreeImage_OpenMemory( (uint8_t *)const_cast( magicNumberPtr ), + static_cast( maxbytes ) ); FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory( fiMem, (int)maxbytes ); FreeImage_CloseMemory( fiMem ); @@ -654,10 +654,10 @@ namespace Ogre FreeImageCodec2::ValidationStatus FreeImageCodec2::validateMagicNumber( const char *magicNumberPtr, size_t maxbytes ) const { - FIMEMORY *fiMem = FreeImage_OpenMemory( (BYTE *)const_cast( magicNumberPtr ), - static_cast( maxbytes ) ); + FIMEMORY *fiMem = FreeImage_OpenMemory( (uint8_t *)const_cast( magicNumberPtr ), + static_cast( maxbytes ) ); - const BOOL bValid = FreeImage_ValidateFromMemory( (FREE_IMAGE_FORMAT)mFreeImageType, fiMem ); + const FIBOOL bValid = FreeImage_ValidateFromMemory( (FREE_IMAGE_FORMAT)mFreeImageType, fiMem ); FreeImage_CloseMemory( fiMem ); if( bValid ) @@ -685,6 +685,7 @@ namespace Ogre case FIF_TIFF: case FIF_XPM: case FIF_WEBP: + case FIF_JXR: return CodecInvalid; } From 64ffd1ca8dda4a61a6fa7f3c279892fd244daf4b Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 29 Feb 2024 16:52:27 -0300 Subject: [PATCH 115/124] Update CI build scripts to use new ogre-next-deps build --- Scripts/BuildScripts/build_ci_linux.sh | 4 ++-- Scripts/BuildScripts/build_ci_windows.bat | 20 ++++++++++---------- appveyor.yml | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Scripts/BuildScripts/build_ci_linux.sh b/Scripts/BuildScripts/build_ci_linux.sh index 9dc6836a37e..834378dbb7c 100755 --- a/Scripts/BuildScripts/build_ci_linux.sh +++ b/Scripts/BuildScripts/build_ci_linux.sh @@ -9,10 +9,10 @@ sudo apt-get update sudo apt-get install -y ninja-build libxrandr-dev libxaw7-dev libxcb-randr0-dev libx11-xcb-dev libsdl2-dev echo "--- Fetching prebuilt Dependencies ---" -wget https://github.com/OGRECave/ogre-next-deps/releases/download/bin-releases/Dependencies_Release_Ubuntu.20.04.LTS.Clang-12_a3f61e782f3effbd58a15727885cbd85cd1b342b.7z +wget https://github.com/OGRECave/ogre-next-deps/releases/download/bin-releases/Dependencies_Release_Ubuntu.20.04.LTS.Clang-12_22ab475b517e724409cb6d585b3646ac6a7b23ea.7z echo "--- Extracting prebuilt Dependencies ---" -7z x Dependencies_Release_Ubuntu.20.04.LTS.Clang-12_a3f61e782f3effbd58a15727885cbd85cd1b342b.7z +7z x Dependencies_Release_Ubuntu.20.04.LTS.Clang-12_22ab475b517e724409cb6d585b3646ac6a7b23ea.7z mkdir -p build/Debug cd build/Debug diff --git a/Scripts/BuildScripts/build_ci_windows.bat b/Scripts/BuildScripts/build_ci_windows.bat index 7cc76fea629..3095a462118 100644 --- a/Scripts/BuildScripts/build_ci_windows.bat +++ b/Scripts/BuildScripts/build_ci_windows.bat @@ -30,17 +30,17 @@ echo %PATH% echo -- PYTHONPATH -- echo %PYTHONPATH% -IF NOT EXIST %BUILD_FOLDER%\..\ogredeps ( - mkdir %BUILD_FOLDER%\..\ogredeps - echo --- Cloning Ogredeps --- - git clone --recurse-submodules --shallow-submodules https://github.com/OGRECave/ogre-next-deps %BUILD_FOLDER%\..\ogredeps +IF NOT EXIST %BUILD_FOLDER%\..\ogre-next-deps ( + mkdir %BUILD_FOLDER%\..\ogre-next-deps + echo --- Cloning ogre-next-deps --- + git clone --recurse-submodules --shallow-submodules https://github.com/OGRECave/ogre-next-deps %BUILD_FOLDER%\..\ogre-next-deps ) ELSE ( - echo --- Ogredeps repo detected. Cloning skipped --- + echo --- ogre-next-deps repo detected. Cloning skipped --- ) -mkdir %BUILD_FOLDER%\..\ogredeps\build -cd %BUILD_FOLDER%\..\ogredeps\build -echo --- Building Ogredeps --- -%CMAKE_BIN% -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER%\..\ogredeps +mkdir %BUILD_FOLDER%\..\ogre-next-deps\build +cd %BUILD_FOLDER%\..\ogre-next-deps\build +echo --- Building ogre-next-deps --- +%CMAKE_BIN% -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER%\..\ogre-next-deps %CMAKE_BIN% --build . --config %CONFIGURATION% %CMAKE_BIN% --build . --target install --config %CONFIGURATION% @@ -48,7 +48,7 @@ cd %BUILD_FOLDER% mkdir %BUILD_FOLDER%\build cd %BUILD_FOLDER%\build echo --- Running CMake configure --- -%CMAKE_BIN% -D OGRE_UNITY_BUILD=1 -D OGRE_USE_BOOST=0 -D OGRE_CONFIG_THREAD_PROVIDER=0 -D OGRE_CONFIG_THREADS=0 -D OGRE_BUILD_COMPONENT_SCENE_FORMAT=1 -D OGRE_BUILD_SAMPLES2=1 -D OGRE_BUILD_TESTS=1 -D OGRE_DEPENDENCIES_DIR=%BUILD_FOLDER%\..\ogredeps\build\ogredeps -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER% +%CMAKE_BIN% -D OGRE_UNITY_BUILD=1 -D OGRE_USE_BOOST=0 -D OGRE_CONFIG_THREAD_PROVIDER=0 -D OGRE_CONFIG_THREADS=0 -D OGRE_BUILD_COMPONENT_SCENE_FORMAT=1 -D OGRE_BUILD_SAMPLES2=1 -D OGRE_BUILD_TESTS=1 -D OGRE_DEPENDENCIES_DIR=%BUILD_FOLDER%\..\ogre-next-deps\build\ogre-next-deps -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER% echo --- Building Ogre --- %CMAKE_BIN% --build . --config %CONFIGURATION% %CMAKE_BIN% --build . --target install --config %CONFIGURATION% diff --git a/appveyor.yml b/appveyor.yml index 9e01e0ffc83..7fb711f7978 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.3.{build} +version: 3.0.{build} environment: matrix: @@ -26,7 +26,7 @@ environment: BUILD_SCRIPT: build_ci_windows.bat cache: - - ..\ogredeps + - ..\ogre-next-deps build_script: - cmd: Scripts\BuildScripts\%BUILD_SCRIPT% From 31f493df285e6dbd00e0a4483bc495658d584420 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 29 Feb 2024 17:25:50 -0300 Subject: [PATCH 116/124] Update appveyor to fix CI build issues --- Scripts/BuildScripts/build_ci_windows.bat | 2 +- appveyor.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Scripts/BuildScripts/build_ci_windows.bat b/Scripts/BuildScripts/build_ci_windows.bat index 3095a462118..6cb6f2f4254 100644 --- a/Scripts/BuildScripts/build_ci_windows.bat +++ b/Scripts/BuildScripts/build_ci_windows.bat @@ -48,7 +48,7 @@ cd %BUILD_FOLDER% mkdir %BUILD_FOLDER%\build cd %BUILD_FOLDER%\build echo --- Running CMake configure --- -%CMAKE_BIN% -D OGRE_UNITY_BUILD=1 -D OGRE_USE_BOOST=0 -D OGRE_CONFIG_THREAD_PROVIDER=0 -D OGRE_CONFIG_THREADS=0 -D OGRE_BUILD_COMPONENT_SCENE_FORMAT=1 -D OGRE_BUILD_SAMPLES2=1 -D OGRE_BUILD_TESTS=1 -D OGRE_DEPENDENCIES_DIR=%BUILD_FOLDER%\..\ogre-next-deps\build\ogre-next-deps -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER% +%CMAKE_BIN% -D OGRE_UNITY_BUILD=1 -D OGRE_USE_BOOST=0 -D OGRE_CONFIG_THREAD_PROVIDER=0 -D OGRE_CONFIG_THREADS=0 -D OGRE_BUILD_COMPONENT_SCENE_FORMAT=1 -D OGRE_BUILD_SAMPLES2=1 -D OGRE_BUILD_TESTS=1 -D OGRE_DEPENDENCIES_DIR=%BUILD_FOLDER%\..\ogre-next-deps\build\ogredeps -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER% echo --- Building Ogre --- %CMAKE_BIN% --build . --config %CONFIGURATION% %CMAKE_BIN% --build . --target install --config %CONFIGURATION% diff --git a/appveyor.yml b/appveyor.yml index 7fb711f7978..c6d2179cdb6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,10 +19,10 @@ environment: # BUILD_SCRIPT: build_ogre_Visual_Studio_14_2015_x64.bat - PLATFORM: x64 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - PYTHON: "C:\\Python36-x64" - PYTHONHOME: "C:\\Python36-x64" - PYTHONPATH: "C:\\Python36-x64\\lib\\site-packages" - PATH: "C:\\Python36-x64;C:\\Python36\\Scripts;%PATH%" + PYTHON: "C:\\Python312" + PYTHONHOME: "C:\\Python312" + PYTHONPATH: "C:\\Python312\\lib\\site-packages" + PATH: "C:\\Python312;C:\\Python312\\Scripts;%PATH%" BUILD_SCRIPT: build_ci_windows.bat cache: From b8ae80e248e76a5b849c2bb2354c0046478f2ce0 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Thu, 29 Feb 2024 18:27:35 -0300 Subject: [PATCH 117/124] Windows CI: Don't rebuild cached ogre-next-deps --- Scripts/BuildScripts/build_ci_windows.bat | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Scripts/BuildScripts/build_ci_windows.bat b/Scripts/BuildScripts/build_ci_windows.bat index 6cb6f2f4254..1b0bca57d2b 100644 --- a/Scripts/BuildScripts/build_ci_windows.bat +++ b/Scripts/BuildScripts/build_ci_windows.bat @@ -34,15 +34,17 @@ IF NOT EXIST %BUILD_FOLDER%\..\ogre-next-deps ( mkdir %BUILD_FOLDER%\..\ogre-next-deps echo --- Cloning ogre-next-deps --- git clone --recurse-submodules --shallow-submodules https://github.com/OGRECave/ogre-next-deps %BUILD_FOLDER%\..\ogre-next-deps + + mkdir %BUILD_FOLDER%\..\ogre-next-deps\build + cd %BUILD_FOLDER%\..\ogre-next-deps\build + echo --- Building ogre-next-deps --- + %CMAKE_BIN% -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER%\..\ogre-next-deps + %CMAKE_BIN% --build . --config %CONFIGURATION% + %CMAKE_BIN% --build . --target install --config %CONFIGURATION% ) ELSE ( echo --- ogre-next-deps repo detected. Cloning skipped --- + echo --- ogre-next-deps repo detected. Building skipped --- ) -mkdir %BUILD_FOLDER%\..\ogre-next-deps\build -cd %BUILD_FOLDER%\..\ogre-next-deps\build -echo --- Building ogre-next-deps --- -%CMAKE_BIN% -G %GENERATOR% -A %PLATFORM% %BUILD_FOLDER%\..\ogre-next-deps -%CMAKE_BIN% --build . --config %CONFIGURATION% -%CMAKE_BIN% --build . --target install --config %CONFIGURATION% cd %BUILD_FOLDER% mkdir %BUILD_FOLDER%\build From 798d1f98d9fd1984b9baf734bbc7a6bf64b26b22 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 28 Apr 2023 14:50:25 +0200 Subject: [PATCH 118/124] when compiling i have this warning: OpenGL_GL_PREFERENCE has not been set to "GLVND" or "LEGACY", so for compatibility with CMake 3.10 and below the legacy GL library will be used. Policy CMP0072 says that I need to set OpenGL_GL_PREFERENCE to LEGACY. --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 570e24b3017..93ec6f46844 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,8 @@ if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android") set(CMAKE_LINK_LIBRARY_FLAG "") endif() +#fix Policy CMP0072 is not set +set(OpenGL_GL_PREFERENCE LEGACY) # Use relative paths # This is mostly to reduce path size for command-line limits on windows From 04c575ec91cd730b85c1f960c43f952b6a0dd29f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 1 Mar 2024 20:00:27 -0300 Subject: [PATCH 119/124] Revert "[Vk] Fixed assert "Delayed buffer must be destroyed in the last buffered frame!" - new command buffers could happen without frame advancing, causing unexpected mFrameCount incrementing not compensated by undo code" This reverts commit b85e1a64bbb9d539042a08924990235aaa5e825f. --- .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index cc9cd3467f8..5750c29cd1f 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -1988,6 +1988,10 @@ namespace Ogre } } + VaoManager::_update(); + // Undo the increment from VaoManager::_update. This is done by _notifyNewCommandBuffer + --mFrameCount; + mUsedDescriptorPools.clear(); uint64 currentTimeMs = mTimer->getMilliseconds(); @@ -2032,14 +2036,6 @@ namespace Ogre } } - if( !mFenceFlushed ) - { - // We could only reach here if _update() was called - // twice in a row without completing a full frame. - // Without this, waitForTailFrameToFinish becomes unsafe. - mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); - } - if( !mUsedSemaphores.empty() ) { waitForTailFrameToFinish(); @@ -2090,13 +2086,23 @@ namespace Ogre deallocateEmptyVbos( false ); - VaoManager::_update(); + if( !mFenceFlushed ) + { + // We could only reach here if _update() was called + // twice in a row without completing a full frame. + // Without this, waitForTailFrameToFinish becomes unsafe. + mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); + } mFenceFlushed = false; - mDynamicBufferCurrentFrame = ( mDynamicBufferCurrentFrame + 1 ) % mDynamicBufferMultiplier; } //----------------------------------------------------------------------------------- - void VulkanVaoManager::_notifyNewCommandBuffer() { mFenceFlushed = true; } + void VulkanVaoManager::_notifyNewCommandBuffer() + { + mFenceFlushed = true; + mDynamicBufferCurrentFrame = ( mDynamicBufferCurrentFrame + 1 ) % mDynamicBufferMultiplier; + ++mFrameCount; + } //----------------------------------------------------------------------------------- void VulkanVaoManager::getAvailableSempaphores( VkSemaphoreArray &semaphoreArray, size_t numSemaphores ) From 1257b4db8e2a373d4931ea4bf6321d6fdec1fb64 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Fri, 1 Mar 2024 20:04:40 -0300 Subject: [PATCH 120/124] Attempt to fix edge case _notifyNewCommandBuffer gets called w/out VaoManager::_update Add EndFrameOnceFailure test Affects #433 --- .../Vulkan/include/Vao/OgreVulkanVaoManager.h | 11 +- .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 27 +- Samples/2.0/CMakeLists.txt | 1 + .../Tests/EndFrameOnceFailure/CMakeLists.txt | 25 ++ .../EndFrameOnceFailure.cpp | 47 +++ .../EndFrameOnceFailureGameState.cpp | 287 ++++++++++++++++++ .../EndFrameOnceFailureGameState.h | 38 +++ 7 files changed, 429 insertions(+), 7 deletions(-) create mode 100644 Samples/2.0/Tests/EndFrameOnceFailure/CMakeLists.txt create mode 100644 Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp create mode 100644 Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp create mode 100644 Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h diff --git a/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h b/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h index d1c4c5eebd9..ebb9e12f14a 100644 --- a/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h +++ b/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h @@ -266,7 +266,16 @@ namespace Ogre typedef FastArray VulkanDelayedFuncBaseArray; FastArray mDelayedFuncs; - bool mFenceFlushed; + uint8 mFenceFlushedWarningCount; + + enum FenceFlushState : uint8 + { + FenceUnflushed, + FenceFlushed, + GpuStalled, + }; + + FenceFlushState mFenceFlushed; bool mSupportsCoherentMemory : 1; bool mSupportsNonCoherentMemory : 1; bool mPreferCoherentMemory : 1; diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 5750c29cd1f..1bb48241746 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -101,7 +101,8 @@ namespace Ogre mDrawId( 0 ), mDevice( device ), mVkRenderSystem( renderSystem ), - mFenceFlushed( true ), + mFenceFlushedWarningCount( 0u ), + mFenceFlushed( FenceUnflushed ), mSupportsCoherentMemory( false ), mSupportsNonCoherentMemory( false ), mReadMemoryIsCoherent( false ) @@ -2086,20 +2087,34 @@ namespace Ogre deallocateEmptyVbos( false ); - if( !mFenceFlushed ) + if( mFenceFlushed == FenceUnflushed ) { // We could only reach here if _update() was called // twice in a row without completing a full frame. - // Without this, waitForTailFrameToFinish becomes unsafe. + // Without this, mFrameCount won't actually advance, and if we increment + // mFrameCount ourselves, waitForTailFrameToFinish would become unsafe. mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); } - mFenceFlushed = false; + mFenceFlushed = FenceUnflushed; } //----------------------------------------------------------------------------------- void VulkanVaoManager::_notifyNewCommandBuffer() { - mFenceFlushed = true; + if( mFenceFlushed == FenceFlushed ) + { + if( mFenceFlushedWarningCount < 5u ) + { + LogManager::getSingleton().logMessage( + "WARNING: Calling RenderSystem::_endFrameOnce() twice in a row without calling " + "RenderSystem::_update. This can lead to strange results.", + LML_CRITICAL ); + ++mFenceFlushedWarningCount; + } + + _update(); + } + mFenceFlushed = FenceFlushed; mDynamicBufferCurrentFrame = ( mDynamicBufferCurrentFrame + 1 ) % mDynamicBufferMultiplier; ++mFrameCount; } @@ -2248,7 +2263,7 @@ namespace Ogre //----------------------------------------------------------------------------------- void VulkanVaoManager::_notifyDeviceStalled() { - mFenceFlushed = true; + mFenceFlushed = GpuStalled; flushAllGpuDelayedBlocks( false ); diff --git a/Samples/2.0/CMakeLists.txt b/Samples/2.0/CMakeLists.txt index 43432d122f1..0e2867af36f 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/EndFrameOnceFailure) add_subdirectory(Tests/InternalCore) add_subdirectory(Tests/MemoryCleanup) add_subdirectory(Tests/NearFarProjection) diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/CMakeLists.txt b/Samples/2.0/Tests/EndFrameOnceFailure/CMakeLists.txt new file mode 100644 index 00000000000..3f2de799cf9 --- /dev/null +++ b/Samples/2.0/Tests/EndFrameOnceFailure/CMakeLists.txt @@ -0,0 +1,25 @@ +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (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) + +include_directories(${CMAKE_SOURCE_DIR}/Components/Hlms/Common/include) +ogre_add_component_include_dir(Hlms/Unlit) + +add_recursive( ./ SOURCE_FILES ) + +ogre_add_executable(Test_EndFrameOnceFailure WIN32 MACOSX_BUNDLE ${SOURCE_FILES} ${SAMPLE_COMMON_RESOURCES}) + +target_link_libraries(Test_EndFrameOnceFailure ${OGRE_LIBRARIES} ${OGRE_SAMPLES_LIBRARIES}) +ogre_config_sample_lib(Test_EndFrameOnceFailure) +ogre_config_sample_pkg(Test_EndFrameOnceFailure) diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp new file mode 100644 index 00000000000..959a4184598 --- /dev/null +++ b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp @@ -0,0 +1,47 @@ + +#include "GraphicsSystem.h" +#include "EndFrameOnceFailureGameState.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 +{ + void MainEntryPoints::createSystems( GameState **outGraphicsGameState, + GraphicsSystem **outGraphicsSystem, + GameState **outLogicGameState, LogicSystem **outLogicSystem ) + { + EndFrameOnceFailureGameState *gfxGameState = new EndFrameOnceFailureGameState( + "Checks the value read matches what is drawn\n" + "It tries to check there are no race conditions when drawing and reading back\n" + "This is very important for Vulkan." ); + + GraphicsSystem *graphicsSystem = new GraphicsSystem( 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( void ) { return "Test near and far plane"; } +} // namespace Demo diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp new file mode 100644 index 00000000000..49698c30899 --- /dev/null +++ b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp @@ -0,0 +1,287 @@ + +#include "EndFrameOnceFailureGameState.h" + +#include "GraphicsSystem.h" + +#include "OgreHlmsUnlitDatablock.h" + +#include "Compositor/OgreCompositorManager2.h" +#include "Compositor/OgreCompositorNodeDef.h" +#include "Compositor/OgreCompositorWorkspace.h" +#include "Compositor/OgreCompositorWorkspaceDef.h" +#include "Compositor/Pass/PassScene/OgreCompositorPassSceneDef.h" +#include "OgreCamera.h" +#include "OgreHlms.h" +#include "OgreItem.h" +#include "OgreLogManager.h" +#include "OgreLwString.h" +#include "OgreMesh.h" +#include "OgreMesh2.h" +#include "OgreMeshManager.h" +#include "OgreMeshManager2.h" +#include "OgreRoot.h" +#include "OgreSceneManager.h" +#include "OgreTextureBox.h" +#include "OgreTextureGpu.h" +#include "OgreTextureGpuManager.h" +#include "Vao/OgreVaoManager.h" + +using namespace Demo; + +namespace Demo +{ + EndFrameOnceFailureGameState::EndFrameOnceFailureGameState( const Ogre::String &helpDescription ) : + TutorialGameState( helpDescription ), + mUnlitDatablock( 0 ), + mRgbaReference( 0 ), + mTextureBox( 0 ), + mRaceConditionDetected( false ) + { + } + //----------------------------------------------------------------------------------- + void EndFrameOnceFailureGameState::createScene01() + { + Ogre::SceneManager *sceneManager = mGraphicsSystem->getSceneManager(); + + Ogre::TextureGpuManager *textureManager = + mGraphicsSystem->getRoot()->getRenderSystem()->getTextureGpuManager(); + textureManager->setStagingTextureMaxBudgetBytes( 1u ); + + Ogre::v1::MeshPtr planeMeshV1 = Ogre::v1::MeshManager::getSingleton().createPlane( + "Plane v1", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::Plane( Ogre::Vector3::UNIT_Z, 0.0f ), 50.0f, 50.0f, 1, 1, true, 1, 4.0f, 4.0f, + Ogre::Vector3::UNIT_Y, Ogre::v1::HardwareBuffer::HBU_STATIC, + Ogre::v1::HardwareBuffer::HBU_STATIC ); + + Ogre::MeshPtr planeMesh = Ogre::MeshManager::getSingleton().createByImportingV1( + "Plane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, planeMeshV1.get(), true, + true, true ); + + { + Ogre::Hlms *hlmsUnlit = + mGraphicsSystem->getRoot()->getHlmsManager()->getHlms( Ogre::HLMS_UNLIT ); + + mUnlitDatablock = static_cast( hlmsUnlit->createDatablock( + "EndFrameOnceFailure Test Material", "EndFrameOnceFailure Test Material", + Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec() ) ); + mUnlitDatablock->setUseColour( true ); + } + + { + // We must alter the AABB because we want to always pass frustum culling + // Otherwise frustum culling may hide bugs in the projection matrix math + planeMesh->load(); + Ogre::Aabb aabb = planeMesh->getAabb(); + aabb.mHalfSize.z = aabb.mHalfSize.x; + planeMesh->_setBounds( aabb ); + } + + Ogre::Item *item = sceneManager->createItem( planeMesh, Ogre::SCENE_DYNAMIC ); + item->setDatablock( mUnlitDatablock ); + Ogre::SceneNode *sceneNode = sceneManager->getRootSceneNode( Ogre::SCENE_DYNAMIC ) + ->createChildSceneNode( Ogre::SCENE_DYNAMIC ); + sceneNode->setScale( Ogre::Vector3( 1000.0f ) ); + sceneNode->attachObject( item ); + + Ogre::Light *light = sceneManager->createLight(); + Ogre::SceneNode *lightNode = sceneManager->getRootSceneNode()->createChildSceneNode(); + lightNode->attachObject( light ); + light->setPowerScale( Ogre::Math::PI ); // Since we don't do HDR, counter the PBS' division by + // PI + light->setType( Ogre::Light::LT_DIRECTIONAL ); + light->setDirection( Ogre::Vector3( -1, -1, -1 ).normalisedCopy() ); + + Ogre::Camera *camera = mGraphicsSystem->getCamera(); + camera->setPosition( 0, 0, 0 ); + camera->setOrientation( Ogre::Quaternion::IDENTITY ); + + camera->setNearClipDistance( 0.5f ); + sceneNode->setPosition( 0, 0, -camera->getNearClipDistance() - 50.0f ); + + { + using namespace Ogre; + CompositorManager2 *compositorManager = mGraphicsSystem->getRoot()->getCompositorManager2(); + CompositorNodeDef *nodeDef = + compositorManager->addNodeDefinition( "EndFrameOnceFailure Node" ); + + // Input texture + nodeDef->addTextureSourceName( "WindowRT", 0, TextureDefinitionBase::TEXTURE_INPUT ); + + nodeDef->setNumTargetPass( 1 ); + { + CompositorTargetDef *targetDef = nodeDef->addTargetPass( "WindowRT" ); + targetDef->setNumPasses( 1 ); + { + { + CompositorPassSceneDef *passScene = + static_cast( targetDef->addPass( PASS_SCENE ) ); + passScene->setAllClearColours( Ogre::ColourValue( 1.0f, 0.5f, 0.0f, 1.0f ) ); + passScene->setAllLoadActions( LoadAction::Clear ); + passScene->mIncludeOverlays = false; + } + } + } + + CompositorWorkspaceDef *workDef = + compositorManager->addWorkspaceDefinition( "EndFrameOnceFailure Workspace" ); + workDef->connectExternal( 0, nodeDef->getName(), 0 ); + } + + TutorialGameState::createScene01(); + } + //----------------------------------------------------------------------------------- + void EndFrameOnceFailureGameState::update( float timeSinceLast ) + { + Ogre::RenderSystem *renderSystem = mGraphicsSystem->getRoot()->getRenderSystem(); + Ogre::TextureGpuManager *textureManager = renderSystem->getTextureGpuManager(); + + Ogre::VaoManager *vaoManager = renderSystem->getVaoManager(); + + Ogre::IndexBufferPacked *dummyBuffer = vaoManager->createIndexBuffer( + Ogre::IT_16BIT, 16000, Ogre::BT_DYNAMIC_PERSISTENT, 0, false ); + dummyBuffer->map( 0, dummyBuffer->getNumElements() ); + dummyBuffer->unmap( Ogre::UO_UNMAP_ALL ); + vaoManager->destroyIndexBuffer( dummyBuffer ); + + Ogre::TextureGpu *readbackTex = textureManager->createTexture( + "EndFrameOnceFailure Tex", Ogre::GpuPageOutStrategy::Discard, + Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D ); + const Ogre::uint32 resolution = 96u; + readbackTex->setResolution( resolution, resolution ); + readbackTex->setPixelFormat( Ogre::PFG_RGBA8_UNORM ); + readbackTex->scheduleTransitionTo( Ogre::GpuResidency::Resident ); + + // const Ogre::PixelFormatGpu pixelFormat = readbackTex->getPixelFormat(); + + mGraphicsSystem->getSceneManager()->updateSceneGraph(); + + Ogre::CompositorManager2 *compositorManager = + mGraphicsSystem->getRoot()->getCompositorManager2(); + Ogre::CompositorWorkspace *workspace = compositorManager->addWorkspace( + mGraphicsSystem->getSceneManager(), readbackTex, mGraphicsSystem->getCamera(), + "EndFrameOnceFailure Workspace", false ); + + const size_t iterations = size_t( std::ceil( Ogre::Math::RangeRandom( 1.0f, 50.0f ) ) ); + for( size_t i = 0u; i < iterations; ++i ) + { + Ogre::IndexBufferPacked *dummyBuffer = vaoManager->createIndexBuffer( + Ogre::IT_16BIT, 16000, Ogre::BT_DYNAMIC_PERSISTENT, 0, false ); + dummyBuffer->map( 0, dummyBuffer->getNumElements() ); + dummyBuffer->unmap( Ogre::UO_UNMAP_ALL ); + vaoManager->destroyIndexBuffer( dummyBuffer ); + + // Choose random colour + Ogre::ColourValue randColour( + Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ), + Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ) ); + + // Quantize + const Ogre::RGBA asRgba = randColour.getAsRGBA(); + randColour.setAsRGBA( asRgba ); + mRgbaReference = asRgba; + + mUnlitDatablock->setColour( randColour ); + + uint32_t rgba = randColour.getAsABGR(); + const uint8_t *rgba8 = reinterpret_cast( &rgba ); + + Ogre::LogManager::getSingleton().logMessage( + "Testing colour: " + std::to_string( rgba8[0] ) + " " + std::to_string( rgba8[1] ) + + " " + std::to_string( rgba8[2] ) + " " + std::to_string( rgba8[3] ), + Ogre::LML_CRITICAL ); + + workspace->_validateFinalTarget(); + workspace->_beginUpdate( false ); + workspace->_update(); + workspace->_endUpdate( false ); + + Ogre::Image2 image; + image.convertFromTexture( readbackTex, 0u, 0u ); + + renderSystem->_endFrameOnce(); + + if( ( i & 0x1u ) == 0u ) + { + Ogre::TextureBox box = image.getData( 0u ); + mTextureBox = &box; + + mGraphicsSystem->getSceneManager()->executeUserScalableTask( this, true ); + // execute(0u,1u); + + if( mRaceConditionDetected ) + { + Ogre::LogManager::getSingleton().logMessage( + "Race condition detected!. Expected value: " + std::to_string( rgba8[0] ) + " " + + std::to_string( rgba8[1] ) + " " + std::to_string( rgba8[2] ) + " " + + std::to_string( rgba8[3] ) + + " Got instead: " + std::to_string( mRgbaResult[0] ) + " " + + std::to_string( mRgbaResult[1] ) + " " + std::to_string( mRgbaResult[2] ) + + " " + std::to_string( mRgbaResult[3] ), + Ogre::LML_CRITICAL ); + + mRaceConditionDetected = false; + + OGRE_EXCEPT( Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Race condition detected!", + "Test failed!" ); + } + } + } + + compositorManager->removeWorkspace( workspace ); + textureManager->destroyTexture( readbackTex ); + + // We don't to give a seizure to users + mUnlitDatablock->setColour( Ogre::ColourValue::Black ); + + TutorialGameState::update( timeSinceLast ); + } + //----------------------------------------------------------------------------------- + void EndFrameOnceFailureGameState::execute( size_t threadId, size_t numThreads ) + { + const Ogre::uint32 rgbaRef = mRgbaReference; + const Ogre::TextureBox box = *mTextureBox; + + const uint8_t *refValue = reinterpret_cast( &rgbaRef ); + + const size_t heightToProcess = std::max( 1u, box.height / numThreads ); + const size_t heightStart = heightToProcess * threadId; + + // Clamp heightEnd (in case there's more threads than rows) + // Ceil heightEnd for the last thread (when box.height / numThreads is not perfectly divisible) + size_t heightEnd = heightToProcess * ( threadId + 1u ); + if( ( threadId + 2u ) * heightToProcess > box.height ) + heightEnd = box.height; + + for( size_t y = heightStart; y < heightEnd; ++y ) + { + for( size_t x = 0u; x < box.width; ++x ) + { + const Ogre::uint8 *dataPtr = reinterpret_cast( box.data ) + + y * box.bytesPerRow + x * box.bytesPerPixel; + + // const Ogre::ColourValue readValue = box.getColourAt( x, y, 0u, pixelFormat ); + // if( readValue != randColour ) + if( dataPtr[0] != refValue[3] || dataPtr[1] != refValue[2] || + dataPtr[2] != refValue[1] || dataPtr[3] != refValue[0] ) + { + if( !mRaceConditionDetected ) + { + mRgbaResult[0] = dataPtr[0]; + mRgbaResult[1] = dataPtr[1]; + mRgbaResult[2] = dataPtr[2]; + mRgbaResult[3] = dataPtr[3]; + } + mRaceConditionDetected = true; + } + } + } + } + //----------------------------------------------------------------------------------- + void EndFrameOnceFailureGameState::generateDebugText( float timeSinceLast, Ogre::String &outText ) + { + TutorialGameState::generateDebugText( timeSinceLast, outText ); + outText += + "\nThis test draws a random colour to an offscreen RTT and downloads\n" + "its contents. If the colour doesn't match we throw an error."; + } +} // namespace Demo diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h new file mode 100644 index 00000000000..52e9c11082d --- /dev/null +++ b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h @@ -0,0 +1,38 @@ + +#ifndef _Demo_EndFrameOnceFailureGameState_H_ +#define _Demo_EndFrameOnceFailureGameState_H_ + +#include "OgrePrerequisites.h" +#include "TutorialGameState.h" + +#include "Threading/OgreUniformScalableTask.h" + +namespace Ogre +{ + class HlmsUnlitDatablock; +} + +namespace Demo +{ + class EndFrameOnceFailureGameState final : public TutorialGameState, public Ogre::UniformScalableTask + { + Ogre::HlmsUnlitDatablock *mUnlitDatablock; + + Ogre::uint32 mRgbaReference; + Ogre::uint8 mRgbaResult[4]; + Ogre::TextureBox const *mTextureBox; + bool mRaceConditionDetected; + + void generateDebugText( float timeSinceLast, Ogre::String &outText ) override; + + public: + EndFrameOnceFailureGameState( const Ogre::String &helpDescription ); + + void createScene01() override; + void update( float timeSinceLast ) override; + + void execute( size_t threadId, size_t numThreads ) override; + }; +} // namespace Demo + +#endif From d7ac11a5d15cd298537202639b9d72c9d66f5820 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 2 Mar 2024 18:23:07 -0300 Subject: [PATCH 121/124] [Vk] Fix asserts if calling VaoManager::_update() twice in a row (#433) Affects #433 --- .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index 1bb48241746..fc12fd1b5f4 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -1978,6 +1978,37 @@ namespace Ogre //----------------------------------------------------------------------------------- void VulkanVaoManager::_update() { + if( mFenceFlushed == FenceUnflushed ) + { + // We could only reach here if _update() was called + // twice in a row without completing a full frame. + // + // Without this, mFrameCount won't actually advance, and if we increment + // mFrameCount ourselves, waitForTailFrameToFinish would become unsafe. + // + // This must be done at the beginning, because normally the following sequence would happen: + // 1. VulkanVaoManager::_update - mFrameCount = 0 + // 2. _notifyNewCommandBuffer - mFrameCount = 1 + // 3. VulkanVaoManager::_update - mFrameCount = 1 + // 4. _notifyNewCommandBuffer - mFrameCount = 2 + // 5. And so on... + // + // However we reached here because we performed the following: + // 1. VulkanVaoManager::_update - mFrameCount = 0 + // 2. VulkanVaoManager::_update - mFrameCount = ??? + // + // Thus we MUST insert a _notifyNewCommandBuffer in-between the first two: + // 1. VulkanVaoManager::_update - mFrameCount = 0 + // 2a._notifyNewCommandBuffer - mFrameCount = 1 + // 2b.VulkanVaoManager::_update - mFrameCount = 1 + // + // Previously this block of code was at the end of VulkanVaoManager::_update + // and this was causing troubles. See https://github.com/OGRECave/ogre-next/issues/433 + mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); + } + + mFenceFlushed = FenceUnflushed; + { FastArray::const_iterator itor = mUsedDescriptorPools.begin(); FastArray::const_iterator endt = mUsedDescriptorPools.end(); @@ -2086,17 +2117,6 @@ namespace Ogre } deallocateEmptyVbos( false ); - - if( mFenceFlushed == FenceUnflushed ) - { - // We could only reach here if _update() was called - // twice in a row without completing a full frame. - // Without this, mFrameCount won't actually advance, and if we increment - // mFrameCount ourselves, waitForTailFrameToFinish would become unsafe. - mDevice->commitAndNextCommandBuffer( SubmissionType::NewFrameIdx ); - } - - mFenceFlushed = FenceUnflushed; } //----------------------------------------------------------------------------------- void VulkanVaoManager::_notifyNewCommandBuffer() From baec86dc5423ebca3063b6aed5a444ed511f4798 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 2 Mar 2024 19:13:41 -0300 Subject: [PATCH 122/124] Update EndFrameOnceFailure test to check for regressions on #433 --- .../EndFrameOnceFailure.cpp | 11 +- .../EndFrameOnceFailureGameState.cpp | 122 ++++++++++-------- .../EndFrameOnceFailureGameState.h | 4 + 3 files changed, 81 insertions(+), 56 deletions(-) diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp index 959a4184598..541e72c29ad 100644 --- a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp +++ b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailure.cpp @@ -1,6 +1,6 @@ -#include "GraphicsSystem.h" #include "EndFrameOnceFailureGameState.h" +#include "GraphicsSystem.h" // Declares WinMain / main #include "MainEntryPointHelper.h" @@ -24,8 +24,8 @@ namespace Demo GameState **outLogicGameState, LogicSystem **outLogicSystem ) { EndFrameOnceFailureGameState *gfxGameState = new EndFrameOnceFailureGameState( - "Checks the value read matches what is drawn\n" - "It tries to check there are no race conditions when drawing and reading back\n" + "Checks two edge cases that should happen rarely don't break\n" + "See https://github.com/OGRECave/ogre-next/issues/433\n" "This is very important for Vulkan." ); GraphicsSystem *graphicsSystem = new GraphicsSystem( gfxGameState ); @@ -43,5 +43,8 @@ namespace Demo delete graphicsGameState; } - const char *MainEntryPoints::getWindowTitle( void ) { return "Test near and far plane"; } + const char *MainEntryPoints::getWindowTitle( void ) + { + return "Test VaoManager mFrameCount advancement"; + } } // namespace Demo diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp index 49698c30899..46edd4ebe9c 100644 --- a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp +++ b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.cpp @@ -35,7 +35,8 @@ namespace Demo mUnlitDatablock( 0 ), mRgbaReference( 0 ), mTextureBox( 0 ), - mRaceConditionDetected( false ) + mRaceConditionDetected( false ), + mCurrFrame( 0u ) { } //----------------------------------------------------------------------------------- @@ -130,11 +131,9 @@ namespace Demo TutorialGameState::createScene01(); } //----------------------------------------------------------------------------------- - void EndFrameOnceFailureGameState::update( float timeSinceLast ) + void EndFrameOnceFailureGameState::simulateSpuriousBufferDisposal() { Ogre::RenderSystem *renderSystem = mGraphicsSystem->getRoot()->getRenderSystem(); - Ogre::TextureGpuManager *textureManager = renderSystem->getTextureGpuManager(); - Ogre::VaoManager *vaoManager = renderSystem->getVaoManager(); Ogre::IndexBufferPacked *dummyBuffer = vaoManager->createIndexBuffer( @@ -142,6 +141,15 @@ namespace Demo dummyBuffer->map( 0, dummyBuffer->getNumElements() ); dummyBuffer->unmap( Ogre::UO_UNMAP_ALL ); vaoManager->destroyIndexBuffer( dummyBuffer ); + } + //----------------------------------------------------------------------------------- + void EndFrameOnceFailureGameState::update( float timeSinceLast ) + { + Ogre::RenderSystem *renderSystem = mGraphicsSystem->getRoot()->getRenderSystem(); + Ogre::TextureGpuManager *textureManager = renderSystem->getTextureGpuManager(); + Ogre::VaoManager *vaoManager = renderSystem->getVaoManager(); + + simulateSpuriousBufferDisposal(); Ogre::TextureGpu *readbackTex = textureManager->createTexture( "EndFrameOnceFailure Tex", Ogre::GpuPageOutStrategy::Discard, @@ -164,65 +172,73 @@ namespace Demo const size_t iterations = size_t( std::ceil( Ogre::Math::RangeRandom( 1.0f, 50.0f ) ) ); for( size_t i = 0u; i < iterations; ++i ) { - Ogre::IndexBufferPacked *dummyBuffer = vaoManager->createIndexBuffer( - Ogre::IT_16BIT, 16000, Ogre::BT_DYNAMIC_PERSISTENT, 0, false ); - dummyBuffer->map( 0, dummyBuffer->getNumElements() ); - dummyBuffer->unmap( Ogre::UO_UNMAP_ALL ); - vaoManager->destroyIndexBuffer( dummyBuffer ); + if( mCurrFrame % 64u < 32u ) + { + // Check that multiple VaoManager::_update in a row don't break. + for( size_t i = 0u; i < iterations; ++i ) + simulateSpuriousBufferDisposal(); + vaoManager->_update(); + } + else + { + // Check that unexpected calls to _endFrameOnce don't break. + simulateSpuriousBufferDisposal(); - // Choose random colour - Ogre::ColourValue randColour( - Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ), - Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ) ); + // Choose random colour + Ogre::ColourValue randColour( + Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ), + Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ) ); - // Quantize - const Ogre::RGBA asRgba = randColour.getAsRGBA(); - randColour.setAsRGBA( asRgba ); - mRgbaReference = asRgba; + // Quantize + const Ogre::RGBA asRgba = randColour.getAsRGBA(); + randColour.setAsRGBA( asRgba ); + mRgbaReference = asRgba; - mUnlitDatablock->setColour( randColour ); + mUnlitDatablock->setColour( randColour ); - uint32_t rgba = randColour.getAsABGR(); - const uint8_t *rgba8 = reinterpret_cast( &rgba ); + uint32_t rgba = randColour.getAsABGR(); + const uint8_t *rgba8 = reinterpret_cast( &rgba ); - Ogre::LogManager::getSingleton().logMessage( - "Testing colour: " + std::to_string( rgba8[0] ) + " " + std::to_string( rgba8[1] ) + - " " + std::to_string( rgba8[2] ) + " " + std::to_string( rgba8[3] ), - Ogre::LML_CRITICAL ); + Ogre::LogManager::getSingleton().logMessage( + "Testing colour: " + std::to_string( rgba8[0] ) + " " + std::to_string( rgba8[1] ) + + " " + std::to_string( rgba8[2] ) + " " + std::to_string( rgba8[3] ), + Ogre::LML_CRITICAL ); - workspace->_validateFinalTarget(); - workspace->_beginUpdate( false ); - workspace->_update(); - workspace->_endUpdate( false ); + workspace->_validateFinalTarget(); + workspace->_beginUpdate( false ); + workspace->_update(); + workspace->_endUpdate( false ); - Ogre::Image2 image; - image.convertFromTexture( readbackTex, 0u, 0u ); + Ogre::Image2 image; + image.convertFromTexture( readbackTex, 0u, 0u ); - renderSystem->_endFrameOnce(); + renderSystem->_endFrameOnce(); - if( ( i & 0x1u ) == 0u ) - { - Ogre::TextureBox box = image.getData( 0u ); - mTextureBox = &box; + if( ( i & 0x1u ) == 0u ) + { + Ogre::TextureBox box = image.getData( 0u ); + mTextureBox = &box; - mGraphicsSystem->getSceneManager()->executeUserScalableTask( this, true ); - // execute(0u,1u); + mGraphicsSystem->getSceneManager()->executeUserScalableTask( this, true ); + // execute(0u,1u); - if( mRaceConditionDetected ) - { - Ogre::LogManager::getSingleton().logMessage( - "Race condition detected!. Expected value: " + std::to_string( rgba8[0] ) + " " + - std::to_string( rgba8[1] ) + " " + std::to_string( rgba8[2] ) + " " + - std::to_string( rgba8[3] ) + - " Got instead: " + std::to_string( mRgbaResult[0] ) + " " + - std::to_string( mRgbaResult[1] ) + " " + std::to_string( mRgbaResult[2] ) + - " " + std::to_string( mRgbaResult[3] ), - Ogre::LML_CRITICAL ); - - mRaceConditionDetected = false; - - OGRE_EXCEPT( Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Race condition detected!", - "Test failed!" ); + if( mRaceConditionDetected ) + { + Ogre::LogManager::getSingleton().logMessage( + "Race condition detected!. Expected value: " + std::to_string( rgba8[0] ) + + " " + std::to_string( rgba8[1] ) + " " + std::to_string( rgba8[2] ) + + " " + std::to_string( rgba8[3] ) + + " Got instead: " + std::to_string( mRgbaResult[0] ) + " " + + std::to_string( mRgbaResult[1] ) + " " + + std::to_string( mRgbaResult[2] ) + " " + + std::to_string( mRgbaResult[3] ), + Ogre::LML_CRITICAL ); + + mRaceConditionDetected = false; + + OGRE_EXCEPT( Ogre::Exception::ERR_RT_ASSERTION_FAILED, + "Race condition detected!", "Test failed!" ); + } } } } @@ -234,6 +250,8 @@ namespace Demo mUnlitDatablock->setColour( Ogre::ColourValue::Black ); TutorialGameState::update( timeSinceLast ); + + ++mCurrFrame; } //----------------------------------------------------------------------------------- void EndFrameOnceFailureGameState::execute( size_t threadId, size_t numThreads ) diff --git a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h index 52e9c11082d..45ecb614fe9 100644 --- a/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h +++ b/Samples/2.0/Tests/EndFrameOnceFailure/EndFrameOnceFailureGameState.h @@ -23,6 +23,10 @@ namespace Demo Ogre::TextureBox const *mTextureBox; bool mRaceConditionDetected; + Ogre::uint32 mCurrFrame; + + void simulateSpuriousBufferDisposal(); + void generateDebugText( float timeSinceLast, Ogre::String &outText ) override; public: From c8e51714c0c2bf432bdf102a7d45edb82bbcfec1 Mon Sep 17 00:00:00 2001 From: mosfet80 Date: Mon, 4 Mar 2024 05:33:26 +0100 Subject: [PATCH 123/124] Delete Other/VC7_AppWizard.msi removed unused file --- Other/VC7_AppWizard.msi | Bin 171008 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Other/VC7_AppWizard.msi diff --git a/Other/VC7_AppWizard.msi b/Other/VC7_AppWizard.msi deleted file mode 100644 index afe279b5a4872115e3f5909e7cc0067215364979..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171008 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�cjdiZ6PRXmk{60YjVtYno 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 From d48d6fbcabf3b3495b13928533ca829ab2d46de6 Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Tue, 5 Mar 2024 18:42:18 -0300 Subject: [PATCH 124/124] Mark 3.0.0 as stable --- OgreMain/include/OgrePrerequisites.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OgreMain/include/OgrePrerequisites.h b/OgreMain/include/OgrePrerequisites.h index cb713e1c895..de73ec7792a 100644 --- a/OgreMain/include/OgrePrerequisites.h +++ b/OgreMain/include/OgrePrerequisites.h @@ -73,7 +73,7 @@ namespace Ogre #define OGRE_VERSION_MAJOR 3 #define OGRE_VERSION_MINOR 0 #define OGRE_VERSION_PATCH 0 -#define OGRE_VERSION_SUFFIX "unstable" +#define OGRE_VERSION_SUFFIX "" #define OGRE_VERSION_NAME "Eris" #define OGRE_MAKE_VERSION( maj, min, patch ) ( ( maj << 16 ) | ( min << 8 ) | patch )