diff --git a/CMakeLists.txt b/CMakeLists.txt index 99e8c3ab9..29ac80778 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR endif() if (ENABLE_VR_DEFAULT) - find_package(osgXR 0.3.3 QUIET) + find_package(osgXR 0.3.9 QUIET) if (osgXR_FOUND) set(SYSTEM_OSGXR_DEFAULT 1) endif() diff --git a/src/Viewer/splash.cxx b/src/Viewer/splash.cxx index 6a874559d..8fec18368 100644 --- a/src/Viewer/splash.cxx +++ b/src/Viewer/splash.cxx @@ -57,6 +57,7 @@ #include <Main/util.hxx> #include "splash.hxx" #include "renderer.hxx" +#include "VRManager.hxx" #include <sstream> @@ -79,6 +80,19 @@ public: SplashScreen::SplashScreen() : _splashAlphaNode(fgGetNode("/sim/startup/splash-alpha", true)) { +#ifdef ENABLE_OSGXR + uint32_t splashW = 1920, splashH = 1080; + float aspect = (float)splashW / splashH; + _splashSwapchain = new osgXR::Swapchain(splashW, splashH); + _splashSwapchain->setAlphaBits(8); + _splashSwapchain->allowRGBEncoding(osgXR::Swapchain::Encoding::ENCODING_SRGB); + _splashLayer = new osgXR::CompositionLayerQuad(flightgear::VRManager::instance()); + _splashLayer->setSubImage(_splashSwapchain); + _splashLayer->setSize(osg::Vec2f(aspect, 1.0f)); + _splashLayer->setPosition(osg::Vec3f(0, 0, -2.0f)); + _splashLayer->setAlphaMode(osgXR::CompositionLayer::BLEND_ALPHA_UNPREMULT); +#endif + setName("splashGroup"); setUpdateCallback(new SplashScreenUpdateCallback); } @@ -91,7 +105,7 @@ void SplashScreen::createNodes() { // setup the base geometry _splashFBOTexture = new osg::Texture2D; - _splashFBOTexture->setInternalFormat(GL_RGB); + _splashFBOTexture->setInternalFormat(GL_SRGB8); _splashFBOTexture->setResizeNonPowerOfTwoHint(false); _splashFBOTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); _splashFBOTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); @@ -226,6 +240,7 @@ void SplashScreen::createNodes() stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); stateSet->setRenderBinDetails(1000, "RenderBin"); stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + stateSet->setMode(GL_FRAMEBUFFER_SRGB, osg::StateAttribute::ON); geometry = osg::createTexturedQuadGeometry(osg::Vec3(0.0, 0.0, 0.0), osg::Vec3(1.0, 0.0, 0.0), @@ -244,6 +259,9 @@ void SplashScreen::createNodes() geode = new osg::Geode; geode->addDrawable(geometry); +#ifdef ENABLE_OSGXR + _splashSwapchain->attachToMirror(stateSet); +#endif _splashQuadCamera->addChild(geode); addChild(_splashQuadCamera); } @@ -325,6 +343,9 @@ osg::ref_ptr<osg::Camera> SplashScreen::createFBOCamera() c->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); c->setRenderOrder(osg::Camera::PRE_RENDER); c->attach(osg::Camera::COLOR_BUFFER, _splashFBOTexture); +#ifdef ENABLE_OSGXR + _splashSwapchain->attachToCamera(c); +#endif osg::StateSet* stateSet = c->getOrCreateStateSet(); stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF); @@ -570,11 +591,18 @@ void SplashScreen::doUpdate() removeChild(0, getNumChildren()); _splashFBOCamera = nullptr; _splashQuadCamera = nullptr; +#ifdef ENABLE_OSGXR + _splashLayer->setVisible(false); +#endif } else if (getNumChildren() == 0) { createNodes(); _splashStartTime.stamp(); resize(fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize")); +#ifdef ENABLE_OSGXR + _splashLayer->setVisible(true); + _splashSwapchain->setForcedAlpha(alpha); +#endif } else { (*_splashFSQuadColor)[0] = osg::Vec4(1.0, 1.0, 1.0, _splashAlphaNode->getFloatValue()); _splashFSQuadColor->dirty(); @@ -603,6 +631,9 @@ void SplashScreen::doUpdate() } updateSplashSpinner(); updateTipText(); +#ifdef ENABLE_OSGXR + _splashSwapchain->setForcedAlpha(alpha); +#endif } } @@ -686,6 +717,11 @@ void SplashScreen::resize( int width, int height ) _splashFBOCamera->setViewport(0, 0, width, height); _splashFBOCamera->setProjectionMatrixAsOrtho2D(-width * 0.5, width * 0.5, -height * 0.5, height * 0.5); +#ifdef ENABLE_OSGXR + float aspect = (float)width / height; + _splashSwapchain->setSize(width, height); + _splashLayer->setSize(osg::Vec2f(aspect, 1.0f)); +#endif const double screenAspectRatio = static_cast<double>(width) / height; diff --git a/src/Viewer/splash.hxx b/src/Viewer/splash.hxx index 9350c8225..5b50059a4 100644 --- a/src/Viewer/splash.hxx +++ b/src/Viewer/splash.hxx @@ -25,9 +25,16 @@ #ifndef _SPLASH_HXX #define _SPLASH_HXX +#include <config.h> + #include <osg/Group> #include <osgText/Text> +#ifdef ENABLE_OSGXR +#include <osgXR/CompositionLayerQuad> +#include <osgXR/Swapchain> +#endif + #include <simgear/props/props.hxx> #include <simgear/timing/timestamp.hxx> @@ -117,6 +124,13 @@ private: osg::ref_ptr<osg::Camera> _splashQuadCamera; std::vector<ImageItem> _imageItems; + +#ifdef ENABLE_OSGXR + // Splash as OpenXR composition layer + osg::ref_ptr<osgXR::Swapchain> _splashSwapchain; + osg::ref_ptr<osgXR::CompositionLayerQuad> _splashLayer; +#endif + std::vector<TextItem> _items; SGTimeStamp _splashStartTime;