src/Viewer/splash: VR splash screen
Use a quad composition layer object from osgXR 0.3.9 to make the splash screen VR friendly. This allows the OpenXR compositor to redraw the quad without any updates from flightgear, which is particularly helpful as flightgear makes no attempt at a reasonable VR frame rate during initialisation. The quad is positioned 2 meters from the user, with an aspect ratio matching the desktop window. The quad is blended using an unpremultiplied alpha channel which is forced to a given alpha value by osgXR. The splash is effectively already rendered to an FBO as non-linear SRGB, so this is made explicit in the internal texture format, with the rendering to the desktop window using GL_FRAMEBUFFER_SRGB to ensure it is properly re-encoded.
This commit is contained in:
parent
bb0d7fc0a7
commit
b9efba55e7
3 changed files with 52 additions and 2 deletions
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue