mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	#5534 remove OSG 3.4 support and require at least 3.6.5 support
This commit is contained in:
		
							parent
							
								
									bb9884c024
								
							
						
					
					
						commit
						b551e69b6f
					
				
					 14 changed files with 59 additions and 348 deletions
				
			
		| 
						 | 
				
			
			@ -157,6 +157,7 @@
 | 
			
		|||
    Feature #2766: Warn user if their version of Morrowind is not the latest.
 | 
			
		||||
    Feature #2780: A way to see current OpenMW version in the console
 | 
			
		||||
    Feature #2858: Add a tab to the launcher for handling datafolders
 | 
			
		||||
    Feature #3180: Support uncompressed colour-mapped TGA files
 | 
			
		||||
    Feature #3245: Grid and angle snapping for the OpenMW-CS
 | 
			
		||||
    Feature #3616: Allow Zoom levels on the World Map
 | 
			
		||||
    Feature #4067: Post Processing
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +204,7 @@
 | 
			
		|||
    Feature #6867: Add a way to localize hardcoded strings in GUI
 | 
			
		||||
    Feature #6888: Add switch for armor degradation fix
 | 
			
		||||
    Feature #6925: Allow to use a mouse wheel to rotate a head in the race selection menu
 | 
			
		||||
    Task #5534: Remove support for OSG 3.4
 | 
			
		||||
    Task #6161: Refactor Sky to use shaders and be GLES/GL3 friendly
 | 
			
		||||
    Task #6162: Refactor GUI to use shaders and to be GLES and GL3+ friendly
 | 
			
		||||
    Task #6435: Add support for MSVC 2022
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -407,10 +407,7 @@ if(NOT HAVE_STDINT_H)
 | 
			
		|||
endif()
 | 
			
		||||
 | 
			
		||||
if(OPENMW_USE_SYSTEM_OSG)
 | 
			
		||||
    find_package(OpenSceneGraph 3.4.0 REQUIRED ${USED_OSG_COMPONENTS})
 | 
			
		||||
    if (${OPENSCENEGRAPH_VERSION} VERSION_GREATER 3.6.2 AND ${OPENSCENEGRAPH_VERSION} VERSION_LESS 3.6.5)
 | 
			
		||||
        message(FATAL_ERROR "OpenSceneGraph version ${OPENSCENEGRAPH_VERSION} has critical regressions which cause crashes. Please upgrade to 3.6.5 or later. We strongly recommend using the tip of the official 'OpenSceneGraph-3.6' branch or the tip of '3.6' OpenMW/osg (OSGoS).")
 | 
			
		||||
    endif()
 | 
			
		||||
    find_package(OpenSceneGraph 3.6.5 REQUIRED ${USED_OSG_COMPONENTS})  # Bump to 3.6.6 when released
 | 
			
		||||
 | 
			
		||||
    if(OSG_STATIC)
 | 
			
		||||
        find_package(OSGPlugins REQUIRED COMPONENTS ${USED_OSG_PLUGINS})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,6 @@
 | 
			
		|||
#include <osgViewer/ViewerEventHandlers>
 | 
			
		||||
#include <osg/LightModel>
 | 
			
		||||
#include <osg/Material>
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
 | 
			
		||||
#include <components/debug/debuglog.hpp>
 | 
			
		||||
#include <components/resource/scenemanager.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -97,14 +96,6 @@ RenderWidget::~RenderWidget()
 | 
			
		|||
    try
 | 
			
		||||
    {
 | 
			
		||||
        CompositeViewer::get().removeView(mView);
 | 
			
		||||
 | 
			
		||||
#if OSG_VERSION_LESS_THAN(3,6,5)
 | 
			
		||||
        // before OSG 3.6.4, the default font was a static object, and if it wasn't attached to the scene when a graphics context was destroyed, it's program wouldn't be released.
 | 
			
		||||
        // 3.6.4 moved it into the object cache, which meant it usually got released, but not here.
 | 
			
		||||
        // 3.6.5 improved cleanup with osgViewer::CompositeViewer::removeView so it more reliably released associated state for objects in the object cache.
 | 
			
		||||
        osg::ref_ptr<osg::GraphicsContext> graphicsContext = mView->getCamera()->getGraphicsContext();
 | 
			
		||||
        osgText::Font::getDefaultFont()->releaseGLObjects(graphicsContext->getState());
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    catch(const std::exception& e)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -146,9 +137,7 @@ CompositeViewer::CompositeViewer()
 | 
			
		|||
    // https://gitlab.com/OpenMW/openmw/-/issues/5481
 | 
			
		||||
    setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
 | 
			
		||||
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,5)
 | 
			
		||||
    setUseConfigureAffinity(false);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // disable the default setting of viewer.done() by pressing Escape.
 | 
			
		||||
    setKeyEventSetsDone(0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,8 +7,6 @@
 | 
			
		|||
 | 
			
		||||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
 | 
			
		||||
#include <osgViewer/ViewerEventHandlers>
 | 
			
		||||
#include <osgDB/WriteFile>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1032,10 +1030,8 @@ void OMW::Engine::go()
 | 
			
		|||
    mViewer = new osgViewer::Viewer;
 | 
			
		||||
    mViewer->setReleaseContextAtEndOfFrameHint(false);
 | 
			
		||||
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,5)
 | 
			
		||||
    // Do not try to outsmart the OS thread scheduler (see bug #4785).
 | 
			
		||||
    mViewer->setUseConfigureAffinity(false);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    mEnvironment.setFrameRateLimit(Settings::Manager::getFloat("framerate limit", "Video"));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,10 @@
 | 
			
		|||
#include "loadingscreen.hpp"
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <condition_variable>
 | 
			
		||||
 | 
			
		||||
#include <osgViewer/Viewer>
 | 
			
		||||
 | 
			
		||||
#include <osg/Texture2D>
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
 | 
			
		||||
#include <MyGUI_ScrollBar.h>
 | 
			
		||||
#include <MyGUI_Gui.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -305,12 +303,8 @@ namespace MWGui
 | 
			
		|||
            mCopyFramebufferToTextureCallback = new CopyFramebufferToTextureCallback(mTexture);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 10)
 | 
			
		||||
        mViewer->getCamera()->removeInitialDrawCallback(mCopyFramebufferToTextureCallback);
 | 
			
		||||
        mViewer->getCamera()->addInitialDrawCallback(mCopyFramebufferToTextureCallback);
 | 
			
		||||
#else
 | 
			
		||||
        mViewer->getCamera()->setInitialDrawCallback(mCopyFramebufferToTextureCallback);
 | 
			
		||||
#endif
 | 
			
		||||
        mCopyFramebufferToTextureCallback->reset();
 | 
			
		||||
 | 
			
		||||
        mSplashImage->setBackgroundImage("");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,6 @@
 | 
			
		|||
#include <osg/ColorMask>
 | 
			
		||||
#include <osg/BlendFunc>
 | 
			
		||||
#include <osg/AlphaFunc>
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
#include <osg/observer_ptr>
 | 
			
		||||
#include <osg/PositionAttitudeTransform>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -855,12 +854,8 @@ namespace MWRender
 | 
			
		|||
        osg::ref_ptr<osg::OcclusionQueryNode> oqn = new osg::OcclusionQueryNode;
 | 
			
		||||
        oqn->setQueriesEnabled(true);
 | 
			
		||||
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3, 6, 5)
 | 
			
		||||
        // With OSG 3.6.5, the method of providing user defined query geometry has been completely replaced
 | 
			
		||||
        osg::ref_ptr<osg::QueryGeometry> queryGeom = new osg::QueryGeometry(oqn->getName());
 | 
			
		||||
#else
 | 
			
		||||
        osg::ref_ptr<osg::QueryGeometry> queryGeom = oqn->getQueryGeometry();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        // Make it fast! A DYNAMIC query geometry means we can't break frame until the flare is rendered (which is rendered after all the other geometry,
 | 
			
		||||
        // so that would be pretty bad). STATIC should be safe, since our node's local bounds are static, thus computeBounds() which modifies the queryGeometry
 | 
			
		||||
| 
						 | 
				
			
			@ -881,9 +876,7 @@ namespace MWRender
 | 
			
		|||
        // Still need a proper bounding sphere.
 | 
			
		||||
        oqn->setInitialBound(queryGeom->getBound());
 | 
			
		||||
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3, 6, 5)
 | 
			
		||||
        oqn->setQueryGeometry(queryGeom.release());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        osg::StateSet* queryStateSet = new osg::StateSet;
 | 
			
		||||
        if (queryVisible)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										70
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								appveyor.yml
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,70 +0,0 @@
 | 
			
		|||
version: "{build}"
 | 
			
		||||
 | 
			
		||||
branches:
 | 
			
		||||
    only:
 | 
			
		||||
        - master
 | 
			
		||||
        - /openmw-.*$/
 | 
			
		||||
        - appveyor
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
    matrix:
 | 
			
		||||
        - msvc: 2017
 | 
			
		||||
          APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
 | 
			
		||||
        - msvc: 2019
 | 
			
		||||
          APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
 | 
			
		||||
 | 
			
		||||
platform:
 | 
			
		||||
    - x64
 | 
			
		||||
 | 
			
		||||
configuration:
 | 
			
		||||
#    - Debug
 | 
			
		||||
    - Release
 | 
			
		||||
#    - RelWithDebInfo
 | 
			
		||||
 | 
			
		||||
# We want the git revision for versioning,
 | 
			
		||||
# so shallow clones don't work.
 | 
			
		||||
clone_depth: 1
 | 
			
		||||
 | 
			
		||||
cache:
 | 
			
		||||
    - C:\projects\openmw\deps\Bullet-2.89-msvc2017-win64-double.7z
 | 
			
		||||
    - C:\projects\openmw\deps\MyGUI-3.4.1-msvc2017-win64.7z
 | 
			
		||||
    - C:\projects\openmw\deps\MyGUI-3.4.1-msvc2019-win64.7z
 | 
			
		||||
    - C:\projects\openmw\deps\OSGoS-3.6.5-b02abe2-msvc2017-win64.7z
 | 
			
		||||
    - C:\projects\openmw\deps\OSGoS-3.6.5-b02abe2-msvc2019-win64.7z
 | 
			
		||||
    - C:\projects\openmw\deps\ffmpeg-4.2.2-dev-win64.zip
 | 
			
		||||
    - C:\projects\openmw\deps\ffmpeg-4.2.2-win64.zip
 | 
			
		||||
    - C:\projects\openmw\deps\OpenAL-Soft-1.20.1.zip
 | 
			
		||||
    - C:\projects\openmw\deps\SDL2-2.0.18.zip
 | 
			
		||||
 | 
			
		||||
clone_folder: C:\projects\openmw
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
    - set PATH=C:\Program Files\Git\mingw64\bin;%PATH%
 | 
			
		||||
 | 
			
		||||
before_build:
 | 
			
		||||
    - cmd: git submodule update --init --recursive
 | 
			
		||||
    - cmd: sh %APPVEYOR_BUILD_FOLDER%\CI\before_script.msvc.sh -c %configuration% -p %PLATFORM% -v %msvc% -V -i %APPVEYOR_BUILD_FOLDER%\install
 | 
			
		||||
 | 
			
		||||
build_script:
 | 
			
		||||
    - cmd: if %PLATFORM%==x64 set build=MSVC%msvc%_64
 | 
			
		||||
    - cmd: msbuild %build%\OpenMW.sln /t:Build /p:Configuration=%configuration% /m:2 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
 | 
			
		||||
    - cmd: cmake --install %build% --config %configuration%
 | 
			
		||||
 | 
			
		||||
after_build:
 | 
			
		||||
    - cmd: if %PLATFORM%==x64 7z a OpenMW_MSVC%msvc%_%platform%_%appveyor_pull_request_number%_%appveyor_pull_request_head_commit%.zip %APPVEYOR_BUILD_FOLDER%\install -xr"!*.pdb"
 | 
			
		||||
    #- cmd: if %PLATFORM%==x64 7z a OpenMW_MSVC%msvc%_%platform%_%appveyor_pull_request_number%_%appveyor_pull_request_head_commit%_pdb.zip %APPVEYOR_BUILD_FOLDER%\MSVC%msvc%_64\%configuration%\*.pdb
 | 
			
		||||
 | 
			
		||||
test: off
 | 
			
		||||
 | 
			
		||||
#notifications:
 | 
			
		||||
#    - provider: Email
 | 
			
		||||
#    to:
 | 
			
		||||
#        -
 | 
			
		||||
#    on_build_failure: true
 | 
			
		||||
#    on_build_status_changed: true
 | 
			
		||||
 | 
			
		||||
artifacts:
 | 
			
		||||
  - path: OpenMW_MSVC%msvc%_%platform%_%appveyor_pull_request_number%_%appveyor_pull_request_head_commit%.zip
 | 
			
		||||
    name: OpenMW_MSVC%msvc%_%platform%_%appveyor_pull_request_number%_%appveyor_pull_request_head_commit%
 | 
			
		||||
  #- path: OpenMW_MSVC%msvc%_%platform%_%appveyor_pull_request_number%_%appveyor_pull_request_head_commit%_pdb.zip
 | 
			
		||||
  #  name: OpenMW_MSVC%msvc%_%platform%_%appveyor_pull_request_number%_%appveyor_pull_request_head_commit%_pdb
 | 
			
		||||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
#include <limits>
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
#include <osg/MatrixTransform>
 | 
			
		||||
#include <osg/Geometry>
 | 
			
		||||
#include <osg/ValueObject>
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +137,6 @@ osgParticle::Particle* ParticleSystem::createParticle(const osgParticle::Particl
 | 
			
		|||
void ParticleSystem::drawImplementation(osg::RenderInfo& renderInfo) const
 | 
			
		||||
{
 | 
			
		||||
    osg::State & state = *renderInfo.getState();
 | 
			
		||||
#if OSG_MIN_VERSION_REQUIRED(3, 5, 6)
 | 
			
		||||
    if(state.useVertexArrayObject(getUseVertexArrayObject()))
 | 
			
		||||
    {
 | 
			
		||||
        state.getCurrentVertexArrayState()->assignNormalArrayDispatcher();
 | 
			
		||||
| 
						 | 
				
			
			@ -148,9 +146,6 @@ void ParticleSystem::drawImplementation(osg::RenderInfo& renderInfo) const
 | 
			
		|||
    {
 | 
			
		||||
        state.getAttributeDispatchers().activateNormalArray(mNormalArray);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
     state.Normal(0.3, 0.3, 0.3);
 | 
			
		||||
#endif
 | 
			
		||||
     osgParticle::ParticleSystem::drawImplementation(renderInfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
#include <osg/BufferObject>
 | 
			
		||||
#include <osg/BufferIndexBinding>
 | 
			
		||||
#include <osg/Endian>
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
#include <osg/ValueObject>
 | 
			
		||||
 | 
			
		||||
#include <osgUtil/CullVisitor>
 | 
			
		||||
| 
						 | 
				
			
			@ -301,11 +300,7 @@ namespace SceneUtil
 | 
			
		|||
 | 
			
		||||
                osg::ref_ptr<osg::UniformBufferObject> ubo = new osg::UniformBufferObject;
 | 
			
		||||
                buffer->getData()->setBufferObject(ubo);
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,7)
 | 
			
		||||
                osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), buffer->getData(), 0, buffer->getData()->getTotalDataSize());
 | 
			
		||||
#else
 | 
			
		||||
                osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), ubo, 0, buffer->getData()->getTotalDataSize());
 | 
			
		||||
#endif
 | 
			
		||||
                stateset->setAttributeAndModes(ubb, mode);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -613,11 +608,7 @@ namespace SceneUtil
 | 
			
		|||
            for (size_t i = 0; i < mStateSet.size(); ++i)
 | 
			
		||||
            {
 | 
			
		||||
                auto& buffer = lightManager->getUBOManager()->getLightBuffer(i);
 | 
			
		||||
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,7)
 | 
			
		||||
                osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), buffer->getData(), 0, buffer->getData()->getTotalDataSize());
 | 
			
		||||
#else
 | 
			
		||||
                osg::ref_ptr<osg::UniformBufferBinding> ubb = new osg::UniformBufferBinding(static_cast<int>(Resource::SceneManager::UBOBinding::LightBuffer), buffer->getData()->getBufferObject(), 0, buffer->getData()->getTotalDataSize());
 | 
			
		||||
#endif
 | 
			
		||||
                mStateSet[i]->setAttributeAndModes(ubb, osg::StateAttribute::ON);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,6 @@
 | 
			
		|||
#include <cassert>
 | 
			
		||||
#include <components/resource/scenemanager.hpp>
 | 
			
		||||
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
 | 
			
		||||
namespace SceneUtil
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -189,9 +187,7 @@ void MorphGeometry::cull(osg::NodeVisitor *nv)
 | 
			
		|||
 | 
			
		||||
    positionDst->dirty();
 | 
			
		||||
 | 
			
		||||
#if OSG_MIN_VERSION_REQUIRED(3, 5, 10)
 | 
			
		||||
    geom.osg::Drawable::dirtyGLObjects();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    nv->pushOntoNodePath(&geom);
 | 
			
		||||
    nv->apply(geom);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,12 +13,8 @@
 | 
			
		|||
 | 
			
		||||
/* Modified for OpenMW */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "optimizer.hpp"
 | 
			
		||||
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
#include <osg/Transform>
 | 
			
		||||
#include <osg/MatrixTransform>
 | 
			
		||||
#include <osg/PositionAttitudeTransform>
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +33,6 @@
 | 
			
		|||
#include <osgUtil/Statistics>
 | 
			
		||||
#include <osgUtil/MeshOptimizers>
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <numeric>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -629,22 +624,11 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Node& node)
 | 
			
		|||
    traverse(node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool needvbo(const osg::Geometry* geom)
 | 
			
		||||
{
 | 
			
		||||
#if OSG_MIN_VERSION_REQUIRED(3,5,6)
 | 
			
		||||
    return true;
 | 
			
		||||
#else
 | 
			
		||||
    return geom->getUseVertexBufferObjects();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
osg::Array* cloneArray(osg::Array* array, osg::VertexBufferObject*& vbo, const osg::Geometry* geom)
 | 
			
		||||
{
 | 
			
		||||
    array = static_cast<osg::Array*>(array->clone(osg::CopyOp::DEEP_COPY_ALL));
 | 
			
		||||
    if (!vbo && needvbo(geom))
 | 
			
		||||
        vbo = new osg::VertexBufferObject;
 | 
			
		||||
    if (vbo)
 | 
			
		||||
        array->setVertexBufferObject(vbo);
 | 
			
		||||
    if (!vbo) vbo = new osg::VertexBufferObject;
 | 
			
		||||
    array->setVertexBufferObject(vbo);
 | 
			
		||||
    return array;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1199,10 +1183,8 @@ osg::PrimitiveSet* clonePrimitive(osg::PrimitiveSet* ps, osg::ElementBufferObjec
 | 
			
		|||
    osg::DrawElements* drawElements = ps->getDrawElements();
 | 
			
		||||
    if (!drawElements) return ps;
 | 
			
		||||
 | 
			
		||||
    if (!ebo && needvbo(geom))
 | 
			
		||||
        ebo = new osg::ElementBufferObject;
 | 
			
		||||
    if (ebo)
 | 
			
		||||
        drawElements->setElementBufferObject(ebo);
 | 
			
		||||
    if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
    drawElements->setElementBufferObject(ebo);
 | 
			
		||||
 | 
			
		||||
    return ps;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1808,11 +1790,8 @@ bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geom
 | 
			
		|||
                {
 | 
			
		||||
                    // must promote to a DrawElementsUInt
 | 
			
		||||
                    osg::DrawElementsUInt* new_primitive = new osg::DrawElementsUInt(primitive->getMode());
 | 
			
		||||
                    if (needvbo(&lhs))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
                         new_primitive->setElementBufferObject(ebo);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
                    new_primitive->setElementBufferObject(ebo);
 | 
			
		||||
                    std::copy(primitiveUByte->begin(),primitiveUByte->end(),std::back_inserter(*new_primitive));
 | 
			
		||||
                    new_primitive->offsetIndices(base);
 | 
			
		||||
                    (*primItr) = new_primitive;
 | 
			
		||||
| 
						 | 
				
			
			@ -1820,11 +1799,8 @@ bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geom
 | 
			
		|||
                {
 | 
			
		||||
                    // must promote to a DrawElementsUShort
 | 
			
		||||
                    osg::DrawElementsUShort* new_primitive = new osg::DrawElementsUShort(primitive->getMode());
 | 
			
		||||
                    if (needvbo(&lhs))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
                         new_primitive->setElementBufferObject(ebo);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
                    new_primitive->setElementBufferObject(ebo);
 | 
			
		||||
                    std::copy(primitiveUByte->begin(),primitiveUByte->end(),std::back_inserter(*new_primitive));
 | 
			
		||||
                    new_primitive->offsetIndices(base);
 | 
			
		||||
                    (*primItr) = new_primitive;
 | 
			
		||||
| 
						 | 
				
			
			@ -1851,11 +1827,8 @@ bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geom
 | 
			
		|||
                {
 | 
			
		||||
                    // must promote to a DrawElementsUInt
 | 
			
		||||
                    osg::DrawElementsUInt* new_primitive = new osg::DrawElementsUInt(primitive->getMode());
 | 
			
		||||
                    if (needvbo(&lhs))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
                         new_primitive->setElementBufferObject(ebo);
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!ebo) ebo = new osg::ElementBufferObject;
 | 
			
		||||
                    new_primitive->setElementBufferObject(ebo);
 | 
			
		||||
                    std::copy(primitiveUShort->begin(),primitiveUShort->end(),std::back_inserter(*new_primitive));
 | 
			
		||||
                    new_primitive->offsetIndices(base);
 | 
			
		||||
                    (*primItr) = new_primitive;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,5 @@
 | 
			
		|||
#include "riggeometry.hpp"
 | 
			
		||||
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
 | 
			
		||||
#include <components/debug/debuglog.hpp>
 | 
			
		||||
#include <components/resource/scenemanager.hpp>
 | 
			
		||||
#include <osg/MatrixTransform>
 | 
			
		||||
| 
						 | 
				
			
			@ -260,9 +258,7 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
 | 
			
		|||
    if (tangentDst)
 | 
			
		||||
        tangentDst->dirty();
 | 
			
		||||
 | 
			
		||||
#if OSG_MIN_VERSION_REQUIRED(3, 5, 10)
 | 
			
		||||
    geom.osg::Drawable::dirtyGLObjects();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    nv->pushOntoNodePath(&geom);
 | 
			
		||||
    nv->apply(geom);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@
 | 
			
		|||
 | 
			
		||||
#include <osg/Drawable>
 | 
			
		||||
#include <osg/NodeVisitor>
 | 
			
		||||
#include <osg/Version>
 | 
			
		||||
 | 
			
		||||
#include <components/debug/debuglog.hpp>
 | 
			
		||||
#include <components/resource/scenemanager.hpp>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,6 @@
 | 
			
		|||
#include "sdlcursormanager.hpp"
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
#include <SDL_mouse.h>
 | 
			
		||||
#include <SDL_endian.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -26,180 +24,6 @@
 | 
			
		|||
USE_GRAPHICSWINDOW()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace CursorDecompression
 | 
			
		||||
{
 | 
			
		||||
    // macOS builds use the OSG fork that includes DXTC commit
 | 
			
		||||
    #if OSG_VERSION_GREATER_OR_EQUAL(3, 5, 8) || defined(__APPLE__)
 | 
			
		||||
    static const bool DXTCSupported = true;
 | 
			
		||||
    #else
 | 
			
		||||
    static const bool DXTCSupported = false;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    class MyGraphicsContext {
 | 
			
		||||
        public:
 | 
			
		||||
            MyGraphicsContext(int w, int h)
 | 
			
		||||
            {
 | 
			
		||||
                osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
 | 
			
		||||
                traits->x = 0;
 | 
			
		||||
                traits->y = 0;
 | 
			
		||||
                traits->width = w;
 | 
			
		||||
                traits->height = h;
 | 
			
		||||
                traits->red = 8;
 | 
			
		||||
                traits->green = 8;
 | 
			
		||||
                traits->blue = 8;
 | 
			
		||||
                traits->alpha = 8;
 | 
			
		||||
                traits->windowDecoration = false;
 | 
			
		||||
                traits->doubleBuffer = false;
 | 
			
		||||
                traits->sharedContext = nullptr;
 | 
			
		||||
                traits->pbuffer = true;
 | 
			
		||||
 | 
			
		||||
                osg::GraphicsContext::ScreenIdentifier si;
 | 
			
		||||
                si.readDISPLAY();
 | 
			
		||||
                if (si.displayNum<0) si.displayNum = 0;
 | 
			
		||||
                traits->displayNum = si.displayNum;
 | 
			
		||||
                traits->screenNum = si.screenNum;
 | 
			
		||||
                traits->hostName = si.hostName;
 | 
			
		||||
 | 
			
		||||
                _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
 | 
			
		||||
 | 
			
		||||
                if (!_gc)
 | 
			
		||||
                {
 | 
			
		||||
                    Log(Debug::Warning) << "Failed to create pbuffer, failing back to normal graphics window.";
 | 
			
		||||
 | 
			
		||||
                    traits->pbuffer = false;
 | 
			
		||||
                    _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
 | 
			
		||||
                    if (!_gc)
 | 
			
		||||
                        throw std::runtime_error("Failed to create graphics context for image decompression");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (_gc.valid())
 | 
			
		||||
                {
 | 
			
		||||
                    _gc->realize();
 | 
			
		||||
                    _gc->makeCurrent();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            osg::ref_ptr<osg::GraphicsContext> getContext()
 | 
			
		||||
            {
 | 
			
		||||
                return _gc;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            bool valid() const { return _gc.valid() && _gc->isRealized(); }
 | 
			
		||||
 | 
			
		||||
        private:
 | 
			
		||||
            osg::ref_ptr<osg::GraphicsContext> _gc;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    SDLUtil::SurfaceUniquePtr hardwareDecompress (osg::ref_ptr<osg::Image> source, float rotDegrees)
 | 
			
		||||
    {
 | 
			
		||||
        int width = source->s();
 | 
			
		||||
        int height = source->t();
 | 
			
		||||
 | 
			
		||||
        MyGraphicsContext context(width, height);
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::State> state = context.getContext()->getState();
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
 | 
			
		||||
        texture->setImage(source);
 | 
			
		||||
        texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER);
 | 
			
		||||
        texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER);
 | 
			
		||||
        texture->setBorderColor(osg::Vec4f(0.f, 0.f, 0.f, 0.f));
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat;
 | 
			
		||||
        osg::Matrix texRot (osg::Matrix::identity());
 | 
			
		||||
        float theta ( osg::DegreesToRadians(-rotDegrees) );
 | 
			
		||||
        float cosTheta = std::cos(theta);
 | 
			
		||||
        float sinTheta = std::sin(theta);
 | 
			
		||||
 | 
			
		||||
        texRot(0,0) = cosTheta;
 | 
			
		||||
        texRot(1,0) = -sinTheta;
 | 
			
		||||
        texRot(0,1) = sinTheta;
 | 
			
		||||
        texRot(1,1) = cosTheta;
 | 
			
		||||
        // Offset center of rotation to center of texture
 | 
			
		||||
        texRot(3,0) = 0.5f + ( (-0.5f * cosTheta) - (-0.5f * sinTheta) );
 | 
			
		||||
        texRot(3,1) = 0.5f + ( (-0.5f * sinTheta) + (-0.5f * cosTheta) );
 | 
			
		||||
 | 
			
		||||
        texmat->setMatrix(texRot);
 | 
			
		||||
 | 
			
		||||
        state->applyTextureAttribute(0, texmat);
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::RefMatrix> identity (new osg::RefMatrix(osg::Matrix::identity()));
 | 
			
		||||
        state->applyModelViewMatrix(identity);
 | 
			
		||||
        state->applyProjectionMatrix(identity);
 | 
			
		||||
 | 
			
		||||
        state->applyMode(GL_TEXTURE_2D, true);
 | 
			
		||||
        state->applyTextureAttribute(0, texture);
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::Image> resultImage = new osg::Image;
 | 
			
		||||
        resultImage->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
 | 
			
		||||
 | 
			
		||||
        osg::RenderInfo renderInfo;
 | 
			
		||||
        renderInfo.setState(state);
 | 
			
		||||
 | 
			
		||||
        glViewport(0, 0, width, height);
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::Geometry> geom;
 | 
			
		||||
 | 
			
		||||
        geom = osg::createTexturedQuadGeometry(osg::Vec3(-1,-1,0), osg::Vec3(2,0,0), osg::Vec3(0,2,0));
 | 
			
		||||
 | 
			
		||||
        geom->drawImplementation(renderInfo);
 | 
			
		||||
 | 
			
		||||
        glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, resultImage->data());
 | 
			
		||||
 | 
			
		||||
        geom->releaseGLObjects();
 | 
			
		||||
        source->releaseGLObjects();
 | 
			
		||||
        texture->releaseGLObjects();
 | 
			
		||||
 | 
			
		||||
        return SDLUtil::imageToSurface(resultImage, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDLUtil::SurfaceUniquePtr softwareDecompress (osg::ref_ptr<osg::Image> source, float rotDegrees)
 | 
			
		||||
    {
 | 
			
		||||
        int width = source->s();
 | 
			
		||||
        int height = source->t();
 | 
			
		||||
        bool useAlpha = source->isImageTranslucent();
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::Image> decompressedImage = new osg::Image;
 | 
			
		||||
        decompressedImage->setFileName(source->getFileName());
 | 
			
		||||
        decompressedImage->allocateImage(width, height, 1, useAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);
 | 
			
		||||
        for (int s=0; s<width; ++s)
 | 
			
		||||
            for (int t=0; t<height; ++t)
 | 
			
		||||
                decompressedImage->setColor(source->getColor(s,t,0), s,t,0);
 | 
			
		||||
 | 
			
		||||
        Uint32 redMask = 0x000000ff;
 | 
			
		||||
        Uint32 greenMask = 0x0000ff00;
 | 
			
		||||
        Uint32 blueMask = 0x00ff0000;
 | 
			
		||||
        Uint32 alphaMask = useAlpha ? 0xff000000 : 0;
 | 
			
		||||
 | 
			
		||||
        SDL_Surface *cursorSurface = SDL_CreateRGBSurfaceFrom(decompressedImage->data(),
 | 
			
		||||
            width,
 | 
			
		||||
            height,
 | 
			
		||||
            decompressedImage->getPixelSizeInBits(),
 | 
			
		||||
            decompressedImage->getRowSizeInBytes(),
 | 
			
		||||
            redMask,
 | 
			
		||||
            greenMask,
 | 
			
		||||
            blueMask,
 | 
			
		||||
            alphaMask);
 | 
			
		||||
 | 
			
		||||
        SDL_Surface *targetSurface = SDL_CreateRGBSurface(0, width, height, 32, redMask, greenMask, blueMask, alphaMask);
 | 
			
		||||
        SDL_Renderer *renderer = SDL_CreateSoftwareRenderer(targetSurface);
 | 
			
		||||
 | 
			
		||||
        SDL_RenderClear(renderer);
 | 
			
		||||
 | 
			
		||||
        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
 | 
			
		||||
        SDL_Texture *cursorTexture = SDL_CreateTextureFromSurface(renderer, cursorSurface);
 | 
			
		||||
 | 
			
		||||
        SDL_RenderCopyEx(renderer, cursorTexture, nullptr, nullptr, -rotDegrees, nullptr, SDL_FLIP_VERTICAL);
 | 
			
		||||
 | 
			
		||||
        SDL_DestroyTexture(cursorTexture);
 | 
			
		||||
        SDL_FreeSurface(cursorSurface);
 | 
			
		||||
        SDL_DestroyRenderer(renderer);
 | 
			
		||||
 | 
			
		||||
        return SDLUtil::SurfaceUniquePtr(targetSurface, SDL_FreeSurface);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace SDLUtil
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -262,22 +86,58 @@ namespace SDLUtil
 | 
			
		|||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDLUtil::SurfaceUniquePtr decompress(osg::ref_ptr<osg::Image> source, float rotDegrees)
 | 
			
		||||
    {
 | 
			
		||||
        int width = source->s();
 | 
			
		||||
        int height = source->t();
 | 
			
		||||
        bool useAlpha = source->isImageTranslucent();
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::Image> decompressedImage = new osg::Image;
 | 
			
		||||
        decompressedImage->setFileName(source->getFileName());
 | 
			
		||||
        decompressedImage->allocateImage(width, height, 1, useAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);
 | 
			
		||||
        for (int s=0; s<width; ++s)
 | 
			
		||||
            for (int t=0; t<height; ++t)
 | 
			
		||||
                decompressedImage->setColor(source->getColor(s,t,0), s,t,0);
 | 
			
		||||
 | 
			
		||||
        Uint32 redMask = 0x000000ff;
 | 
			
		||||
        Uint32 greenMask = 0x0000ff00;
 | 
			
		||||
        Uint32 blueMask = 0x00ff0000;
 | 
			
		||||
        Uint32 alphaMask = useAlpha ? 0xff000000 : 0;
 | 
			
		||||
 | 
			
		||||
        SDL_Surface *cursorSurface = SDL_CreateRGBSurfaceFrom(decompressedImage->data(),
 | 
			
		||||
                                                              width,
 | 
			
		||||
                                                              height,
 | 
			
		||||
                                                              decompressedImage->getPixelSizeInBits(),
 | 
			
		||||
                                                              decompressedImage->getRowSizeInBytes(),
 | 
			
		||||
                                                              redMask,
 | 
			
		||||
                                                              greenMask,
 | 
			
		||||
                                                              blueMask,
 | 
			
		||||
                                                              alphaMask);
 | 
			
		||||
 | 
			
		||||
        SDL_Surface *targetSurface = SDL_CreateRGBSurface(0, width, height, 32, redMask, greenMask, blueMask, alphaMask);
 | 
			
		||||
        SDL_Renderer *renderer = SDL_CreateSoftwareRenderer(targetSurface);
 | 
			
		||||
 | 
			
		||||
        SDL_RenderClear(renderer);
 | 
			
		||||
 | 
			
		||||
        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
 | 
			
		||||
        SDL_Texture *cursorTexture = SDL_CreateTextureFromSurface(renderer, cursorSurface);
 | 
			
		||||
 | 
			
		||||
        SDL_RenderCopyEx(renderer, cursorTexture, nullptr, nullptr, -rotDegrees, nullptr, SDL_FLIP_VERTICAL);
 | 
			
		||||
 | 
			
		||||
        SDL_DestroyTexture(cursorTexture);
 | 
			
		||||
        SDL_FreeSurface(cursorSurface);
 | 
			
		||||
        SDL_DestroyRenderer(renderer);
 | 
			
		||||
 | 
			
		||||
        return SDLUtil::SurfaceUniquePtr(targetSurface, SDL_FreeSurface);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SDLCursorManager::_createCursorFromResource(const std::string& name, int rotDegrees, osg::Image* image, Uint8 hotspot_x, Uint8 hotspot_y)
 | 
			
		||||
    {
 | 
			
		||||
        if (mCursorMap.find(name) != mCursorMap.end())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        static bool forceSoftwareDecompression = (getenv("OPENMW_DECOMPRESS_TEXTURES") != nullptr);
 | 
			
		||||
 | 
			
		||||
        SurfaceUniquePtr (*decompressionFunction)(osg::ref_ptr<osg::Image>, float);
 | 
			
		||||
        if (forceSoftwareDecompression || CursorDecompression::DXTCSupported) {
 | 
			
		||||
            decompressionFunction = CursorDecompression::softwareDecompress;
 | 
			
		||||
        } else {
 | 
			
		||||
            decompressionFunction = CursorDecompression::hardwareDecompress;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            auto surface = decompressionFunction(image, static_cast<float>(rotDegrees));
 | 
			
		||||
            auto surface = decompress(image, static_cast<float>(rotDegrees));
 | 
			
		||||
 | 
			
		||||
            //set the cursor and store it for later
 | 
			
		||||
            SDL_Cursor* curs = SDL_CreateColorCursor(surface.get(), hotspot_x, hotspot_y);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue