diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 953e3076b3..716a087d02 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "../widget/scenetoolmode.hpp" @@ -76,6 +77,8 @@ namespace CSVRender = new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height()); mWidget->setGraphicsWindowEmbedded(window); + mRenderer->setRealizeOperation(new SceneUtil::GetGLExtensionsOperation()); + int frameRateLimit = CSMPrefs::get()["Rendering"]["framerate-limit"].toInt(); mRenderer->setRunMaxFrameRate(frameRateLimit); mRenderer->setUseConfigureAffinity(false); diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 75687ff281..2e0e591538 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -600,6 +601,7 @@ void OMW::Engine::createWindow() mViewer->setRealizeOperation(realizeOperations); osg::ref_ptr identifyOp = new IdentifyOpenGLOperation(); realizeOperations->add(identifyOp); + realizeOperations->add(new SceneUtil::GetGLExtensionsOperation()); if (Debug::shouldDebugOpenGL()) realizeOperations->add(new Debug::EnableGLDebugOperation()); @@ -780,13 +782,13 @@ void OMW::Engine::prepareEngine() // gui needs our shaders path before everything else mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders"); - osg::ref_ptr exts = osg::GLExtensions::Get(0, false); - bool shadersSupported = exts && (exts->glslLanguageVersion >= 1.2f); + osg::GLExtensions& exts = SceneUtil::getGLExtensions(); + bool shadersSupported = exts.glslLanguageVersion >= 1.2f; #if OSG_VERSION_LESS_THAN(3, 6, 6) // hack fix for https://github.com/openscenegraph/OpenSceneGraph/issues/1028 - if (exts) - exts->glRenderbufferStorageMultisampleCoverageNV = nullptr; + if (!osg::isGLExtensionSupported(exts.contextID, "NV_framebuffer_multisample_coverage")) + exts.glRenderbufferStorageMultisampleCoverageNV = nullptr; #endif osg::ref_ptr guiRoot = new osg::Group; @@ -844,18 +846,18 @@ void OMW::Engine::prepareEngine() const MWWorld::Store* gmst = &mWorld->getStore().get(); mL10nManager->setGmstLoader( [gmst, misses = std::set>()](std::string_view gmstName) mutable { - const ESM::GameSetting* res = gmst->search(gmstName); - if (res && res->mValue.getType() == ESM::VT_String) - return res->mValue.getString(); - else + const ESM::GameSetting* res = gmst->search(gmstName); + if (res && res->mValue.getType() == ESM::VT_String) + return res->mValue.getString(); + else + { + if (misses.count(gmstName) == 0) { - if (misses.count(gmstName) == 0) - { - misses.emplace(gmstName); - Log(Debug::Error) << "GMST " << gmstName << " not found"; - } - return std::string("GMST:") + std::string(gmstName); + misses.emplace(gmstName); + Log(Debug::Error) << "GMST " << gmstName << " not found"; } + return std::string("GMST:") + std::string(gmstName); + } }); mWindowManager->setStore(mWorld->getStore()); diff --git a/apps/openmw/mwrender/ripples.cpp b/apps/openmw/mwrender/ripples.cpp index dea372666e..4599c2c946 100644 --- a/apps/openmw/mwrender/ripples.cpp +++ b/apps/openmw/mwrender/ripples.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "../mwworld/ptr.hpp" @@ -43,9 +44,9 @@ namespace MWRender mUseCompute = false; #else constexpr float minimumGLVersionRequiredForCompute = 4.4; - osg::GLExtensions* exts = osg::GLExtensions::Get(0, false); - mUseCompute = exts->glVersion >= minimumGLVersionRequiredForCompute - && exts->glslLanguageVersion >= minimumGLVersionRequiredForCompute; + osg::GLExtensions& exts = SceneUtil::getGLExtensions(); + mUseCompute = exts.glVersion >= minimumGLVersionRequiredForCompute + && exts.glslLanguageVersion >= minimumGLVersionRequiredForCompute; #endif if (mUseCompute) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index dc195d8d0b..9feec375a2 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -122,7 +122,7 @@ add_component_dir (sceneutil lightmanager lightutil positionattitudetransform workqueue pathgridutil waterutil writescene serialize optimizer detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller rtt screencapture depth color riggeometryosgaextension extradata unrefqueue lightcommon lightingmethod clearcolor - cullsafeboundsvisitor keyframe nodecallback textkeymap + cullsafeboundsvisitor keyframe nodecallback textkeymap glextensions ) add_component_dir (nif diff --git a/components/resource/imagemanager.cpp b/components/resource/imagemanager.cpp index 26fd60d7ea..124ff9b6ad 100644 --- a/components/resource/imagemanager.cpp +++ b/components/resource/imagemanager.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -65,12 +66,11 @@ namespace Resource case (GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): case (GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): { - osg::GLExtensions* exts = osg::GLExtensions::Get(0, false); - if (exts - && !exts->isTextureCompressionS3TCSupported + osg::GLExtensions& exts = SceneUtil::getGLExtensions(); + if (!exts.isTextureCompressionS3TCSupported // This one works too. Should it be included in isTextureCompressionS3TCSupported()? Submitted as a // patch to OSG. - && !osg::isGLExtensionSupported(0, "GL_S3_s3tc")) + && !osg::isGLExtensionSupported(exts.contextID, "GL_S3_s3tc")) { return false; } diff --git a/components/sceneutil/depth.cpp b/components/sceneutil/depth.cpp index 738fa93dd8..5232d321dc 100644 --- a/components/sceneutil/depth.cpp +++ b/components/sceneutil/depth.cpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace SceneUtil @@ -116,8 +117,7 @@ namespace SceneUtil if (Settings::camera().mReverseZ) { - osg::ref_ptr exts = osg::GLExtensions::Get(0, false); - if (exts && exts->isClipControlSupported) + if (SceneUtil::getGLExtensions().isClipControlSupported) { enableReverseZ = true; Log(Debug::Info) << "Using reverse-z depth buffer"; diff --git a/components/sceneutil/glextensions.cpp b/components/sceneutil/glextensions.cpp new file mode 100644 index 0000000000..078af90c3c --- /dev/null +++ b/components/sceneutil/glextensions.cpp @@ -0,0 +1,28 @@ +#include "glextensions.hpp" + +namespace SceneUtil +{ + namespace + { + osg::observer_ptr sGLExtensions; + } + + osg::GLExtensions& getGLExtensions() + { + if (!sGLExtensions) + throw std::runtime_error( + "GetGLExtensionsOperation was not used when the current context was created or there is no current " + "context"); + return *sGLExtensions; + } + + GetGLExtensionsOperation::GetGLExtensionsOperation() + : GraphicsOperation("GetGLExtensionsOperation", false) + { + } + + void GetGLExtensionsOperation::operator()(osg::GraphicsContext* graphicsContext) + { + sGLExtensions = graphicsContext->getState()->get(); + } +} diff --git a/components/sceneutil/glextensions.hpp b/components/sceneutil/glextensions.hpp new file mode 100644 index 0000000000..17a4eb8488 --- /dev/null +++ b/components/sceneutil/glextensions.hpp @@ -0,0 +1,20 @@ +#ifndef OPENMW_COMPONENTS_SCENEUTIL_GLEXTENSIONS_H +#define OPENMW_COMPONENTS_SCENEUTIL_GLEXTENSIONS_H + +#include +#include + +namespace SceneUtil +{ + osg::GLExtensions& getGLExtensions(); + + class GetGLExtensionsOperation : public osg::GraphicsOperation + { + public: + GetGLExtensionsOperation(); + + void operator()(osg::GraphicsContext* graphicsContext) override; + }; +} + +#endif diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index 8f7304416b..48efb7fda9 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -824,9 +825,9 @@ namespace SceneUtil , mPointLightFadeEnd(0.f) , mPointLightFadeStart(0.f) { - osg::GLExtensions* exts = osg::GLExtensions::Get(0, false); - bool supportsUBO = exts && exts->isUniformBufferObjectSupported; - bool supportsGPU4 = exts && exts->isGpuShader4Supported; + osg::GLExtensions& exts = SceneUtil::getGLExtensions(); + bool supportsUBO = exts.isUniformBufferObjectSupported; + bool supportsGPU4 = exts.isGpuShader4Supported; mSupported[static_cast(LightingMethod::FFP)] = true; mSupported[static_cast(LightingMethod::PerObjectUniform)] = true; diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index d0c270971a..d1553cc8d8 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -30,6 +30,7 @@ #include #include +#include "glextensions.hpp" #include "shadowsbin.hpp" namespace { @@ -920,8 +921,7 @@ void SceneUtil::MWShadowTechnique::setupCastingShader(Shader::ShaderManager & sh // This can't be part of the constructor as OSG mandates that there be a trivial constructor available osg::ref_ptr castingVertexShader = shaderManager.getShader("shadowcasting.vert"); - osg::ref_ptr exts = osg::GLExtensions::Get(0, false); - std::string useGPUShader4 = exts && exts->isGpuShader4Supported ? "1" : "0"; + std::string useGPUShader4 = SceneUtil::getGLExtensions().isGpuShader4Supported ? "1" : "0"; for (int alphaFunc = GL_NEVER; alphaFunc <= GL_ALWAYS; ++alphaFunc) { auto& program = _castingPrograms[alphaFunc - GL_NEVER]; diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index e281f64448..7bce9de2a6 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -676,8 +677,7 @@ namespace Shader defineMap["adjustCoverage"] = "1"; // Preventing alpha tested stuff shrinking as lower mip levels are used requires knowing the texture size - osg::ref_ptr exts = osg::GLExtensions::Get(0, false); - if (exts && exts->isGpuShader4Supported) + if (SceneUtil::getGLExtensions().isGpuShader4Supported) defineMap["useGPUShader4"] = "1"; // We could fall back to a texture size uniform if EXT_gpu_shader4 is missing }