From e8c6f31e0cd200aca70b2bb1cc0eff2afde23204 Mon Sep 17 00:00:00 2001 From: "glassmancody.info" Date: Thu, 22 Jul 2021 15:55:30 -0700 Subject: [PATCH] add shader path for mygui (#6162) --- CHANGELOG.md | 1 + apps/openmw/engine.cpp | 8 +++++- apps/openmw/mwgui/windowmanagerimp.cpp | 6 ++++- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 1 - .../myguiplatform/myguirendermanager.cpp | 27 +++++++++++++++++++ .../myguiplatform/myguirendermanager.hpp | 7 +++++ files/shaders/CMakeLists.txt | 2 ++ files/shaders/gui_fragment.glsl | 11 ++++++++ files/shaders/gui_vertex.glsl | 11 ++++++++ 10 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 files/shaders/gui_fragment.glsl create mode 100644 files/shaders/gui_vertex.glsl diff --git a/CHANGELOG.md b/CHANGELOG.md index 801b48a1a3..50161358d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Feature #5489: MCP: Telekinesis fix for activators Feature #5996: Support Lua scripts in OpenMW Feature #6017: Separate persistent and temporary cell references when saving + Feature #6162: Refactor GUI to use shaders and to be GLES and GL3+ friendly 0.47.0 ------ diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index c98498dc9c..f968bbfac7 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -753,6 +753,12 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) else gameControllerdb = ""; //if it doesn't exist, pass in an empty string + // gui needs our shaders path before everything else + mResourceSystem->getSceneManager()->setShaderPath((mResDir / "shaders").string()); + + osg::ref_ptr exts = osg::GLExtensions::Get(0, false); + bool shadersSupported = exts && (exts->glslLanguageVersion >= 1.2f); + std::string myguiResources = (mResDir / "mygui").string(); osg::ref_ptr guiRoot = new osg::Group; guiRoot->setName("GUI Root"); @@ -761,7 +767,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) MWGui::WindowManager* window = new MWGui::WindowManager(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), mCfgMgr.getLogPath().string() + std::string("/"), myguiResources, mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, - Version::getOpenmwVersionDescription(mResDir.string()), mCfgMgr.getUserConfigPath().string()); + Version::getOpenmwVersionDescription(mResDir.string()), mCfgMgr.getUserConfigPath().string(), shadersSupported); mEnvironment.setWindowManager (window); MWInput::InputManager* input = new MWInput::InputManager (mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 544a0927e7..40c3da5482 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -35,6 +35,7 @@ #include #include +#include #include @@ -124,7 +125,7 @@ namespace MWGui WindowManager::WindowManager( SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& userDataPath) + ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& userDataPath, bool useShaders) : mOldUpdateMask(0) , mOldCullMask(0) , mStore(nullptr) @@ -275,6 +276,9 @@ namespace MWGui mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), Settings::Manager::getFloat("contrast", "Video")); + if (useShaders) + mGuiPlatform->getRenderManagerPtr()->enableShaders(mResourceSystem->getSceneManager()->getShaderManager()); + mStatsWatcher.reset(new StatsWatcher()); } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 8c7e365ec7..9a6b6b54a5 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -135,7 +135,7 @@ namespace MWGui WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& localPath); + ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& localPath, bool useShaders); virtual ~WindowManager(); /// Set the ESMStore to use for retrieving of GUI-related strings. diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 016149ed90..81687a712a 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -201,7 +201,6 @@ namespace MWRender auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::getString("lighting method", "Shaders")); resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); - resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); // Shadows and radial fog have problems with fixed-function mode bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") || Settings::Manager::getBool("force shaders", "Shaders") diff --git a/components/myguiplatform/myguirendermanager.cpp b/components/myguiplatform/myguirendermanager.cpp index 77a5ee533b..abc170c02e 100644 --- a/components/myguiplatform/myguirendermanager.cpp +++ b/components/myguiplatform/myguirendermanager.cpp @@ -14,6 +14,7 @@ #include #include +#include #include @@ -127,9 +128,13 @@ public: state->apply(); } + // A GUI element without an associated texture would be extremely rare. + // It is worth it to use a dummy 1x1 black texture sampler instead of either adding a conditional or relinking shaders. osg::Texture2D* texture = batch.mTexture; if(texture) state->applyTextureAttribute(0, texture); + else + state->applyTextureAttribute(0, mDummyTexture); osg::GLBufferObject* bufferobject = state->isVertexBufferObjectSupported() ? vbo->getOrCreateGLBufferObject(state->getContextID()) : nullptr; if (bufferobject) @@ -189,6 +194,10 @@ public: mStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); mStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); + mDummyTexture = new osg::Texture2D; + mDummyTexture->setInternalFormat(GL_RGB); + mDummyTexture->setTextureSize(1,1); + // need to flip tex coords since MyGUI uses DirectX convention of top left image origin osg::Matrix flipMat; flipMat.preMultTranslate(osg::Vec3f(0,1,0)); @@ -201,6 +210,7 @@ public: , mStateSet(copy.mStateSet) , mWriteTo(0) , mReadFrom(0) + , mDummyTexture(copy.mDummyTexture) { } @@ -231,6 +241,11 @@ public: mBatchVector[mWriteTo].clear(); } + osg::StateSet* getDrawableStateSet() + { + return mStateSet; + } + META_Object(osgMyGUI, Drawable) private: @@ -242,6 +257,8 @@ private: int mWriteTo; mutable int mReadFrom; + + osg::ref_ptr mDummyTexture; }; class OSGVertexBuffer : public MyGUI::IVertexBuffer @@ -417,6 +434,16 @@ void RenderManager::shutdown() mSceneRoot->removeChild(mGuiRoot); } +void RenderManager::enableShaders(Shader::ShaderManager& shaderManager) +{ + auto vertexShader = shaderManager.getShader("gui_vertex.glsl", {}, osg::Shader::VERTEX); + auto fragmentShader = shaderManager.getShader("gui_fragment.glsl", {}, osg::Shader::FRAGMENT); + auto program = shaderManager.getProgram(vertexShader, fragmentShader); + + mDrawable->getDrawableStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON); + mDrawable->getDrawableStateSet()->addUniform(new osg::Uniform("diffuseMap", 0)); +} + MyGUI::IVertexBuffer* RenderManager::createVertexBuffer() { return new OSGVertexBuffer(); diff --git a/components/myguiplatform/myguirendermanager.hpp b/components/myguiplatform/myguirendermanager.hpp index 3c3fb672d6..8ef9691e4f 100644 --- a/components/myguiplatform/myguirendermanager.hpp +++ b/components/myguiplatform/myguirendermanager.hpp @@ -12,6 +12,11 @@ namespace Resource class ImageManager; } +namespace Shader +{ + class ShaderManager; +} + namespace osgViewer { class Viewer; @@ -62,6 +67,8 @@ public: void initialise(); void shutdown(); + void enableShaders(Shader::ShaderManager& shaderManager); + void setScalingFactor(float factor); static RenderManager& getInstance() { return *getInstancePtr(); } diff --git a/files/shaders/CMakeLists.txt b/files/shaders/CMakeLists.txt index c4a8637767..5297b2e752 100644 --- a/files/shaders/CMakeLists.txt +++ b/files/shaders/CMakeLists.txt @@ -31,6 +31,8 @@ set(SHADER_FILES nv_default_fragment.glsl nv_nolighting_vertex.glsl nv_nolighting_fragment.glsl + gui_vertex.glsl + gui_fragment.glsl ) copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_SHADERS_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}") diff --git a/files/shaders/gui_fragment.glsl b/files/shaders/gui_fragment.glsl new file mode 100644 index 0000000000..a8c9434711 --- /dev/null +++ b/files/shaders/gui_fragment.glsl @@ -0,0 +1,11 @@ +#version 120 + +uniform sampler2D diffuseMap; + +varying vec2 diffuseMapUV; +varying vec4 passColor; + +void main() +{ + gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV) * passColor; +} diff --git a/files/shaders/gui_vertex.glsl b/files/shaders/gui_vertex.glsl new file mode 100644 index 0000000000..b378b097bd --- /dev/null +++ b/files/shaders/gui_vertex.glsl @@ -0,0 +1,11 @@ +#version 120 + +varying vec2 diffuseMapUV; +varying vec4 passColor; + +void main() +{ + gl_Position = vec4(gl_Vertex.xyz, 1.0); + diffuseMapUV = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy; + passColor = gl_Color; +}