osgXR: Update to 0.3.8
Update 3rdparty/osgXR to version 0.3.8, which gets us non-linear sRGB swapchain formats by default. This avoids double gamma correction with Monado when FlightGear renders non-linear sRGB data into linear RGB swapchain images.
This commit is contained in:
parent
fe8b7bea21
commit
276835f74c
9 changed files with 516 additions and 34 deletions
54
3rdparty/osgXR/CHANGELOG.md
vendored
54
3rdparty/osgXR/CHANGELOG.md
vendored
|
@ -1,3 +1,57 @@
|
|||
Version 0.3.8
|
||||
-------------
|
||||
|
||||
Highlights:
|
||||
* Swapchain format preferences, allowing more formats to be chosen, and using
|
||||
sRGB formats by default.
|
||||
* Handle building as a CMake subproject.
|
||||
|
||||
New/expanded APIs:
|
||||
* Settings::preferRGBEncoding(), Settings::allowRGBEncoding() - For choosing
|
||||
preferred and allowed RGB encodings from linear, floating point (linear), and
|
||||
sRGB (non-linear).
|
||||
* Settings::preferDepthEncoding(), Settings::allowDepthEncoding() - For
|
||||
choosing preferred and allowed depth encodings from linear, and floating
|
||||
point.
|
||||
* Settings::getRGBBits(), Settings::setRGBBits() - For choosing preferred
|
||||
number of bits per RGB channel (for linear & float encodings only),
|
||||
overriding the graphics window traits bit depths.
|
||||
* Settings::getAlphaBits(), Settings::setAlphaBits() - For choosing preferred
|
||||
number of alpha channel bits, overriding the graphics window traits bit
|
||||
depths.
|
||||
* Settings::getDepthBits(), Settings::setDepthBits() - For choosing preferred
|
||||
number of depth channel bits, overriding the graphics window traits bit
|
||||
depths.
|
||||
* Settings::getStencilBits(), Settings::setStencilBits() - For choosing
|
||||
preferred number of stencil channel bits, overriding the graphics window
|
||||
traits bit depths.
|
||||
* Settings::getPreferredRGBEncodingMask(),
|
||||
Settings::setPreferredRGBEncodingMask(),
|
||||
Settings::getAllowedRGBEncodingMask(),
|
||||
Settings::setAllowedRGBEncodingMask() - Largely internal for directly
|
||||
accessing the masks of preferred and allowed RGB encodings.
|
||||
* Settings::getPreferredDepthEncodingMask(),
|
||||
Settings::setPreferredDepthEncodingMask(),
|
||||
Settings::getAllowedDepthEncodingMask(),
|
||||
Settings::setAllowedDepthEncodingMask() - Largely internal for directly
|
||||
accessing the masks of preferred and allowed depth encodings.
|
||||
|
||||
Documentation:
|
||||
* Settings: Tweak comment wording for consistency.
|
||||
|
||||
Behaviour changes:
|
||||
* Determine swapchain formats using new preferences specified in Settings,
|
||||
using sRGB formats by default instead of linear.
|
||||
* Choose a suitable depth/stencil fallback for when a depth swapchain cannot be
|
||||
used.
|
||||
* Enable gamma correction when rendering VR mirror to sRGB framebuffer.
|
||||
|
||||
Build system:
|
||||
* Handle building as a subproject.
|
||||
* Reduce minimum CMake version to 3.11.
|
||||
* Add OSGXR\_WARNINGS option to enable compiler warnings (for development use).
|
||||
* Drop osgXR\_INCLUDE\_DIR use since newer CMake handles automatically.
|
||||
|
||||
Version 0.3.7
|
||||
-------------
|
||||
|
||||
|
|
5
3rdparty/osgXR/CMakeLists.txt
vendored
5
3rdparty/osgXR/CMakeLists.txt
vendored
|
@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.11)
|
|||
|
||||
set(osgXR_MAJOR_VERSION 0)
|
||||
set(osgXR_MINOR_VERSION 3)
|
||||
set(osgXR_PATCH_VERSION 7)
|
||||
set(osgXR_SOVERSION 5)
|
||||
set(osgXR_PATCH_VERSION 8)
|
||||
set(osgXR_SOVERSION 6)
|
||||
|
||||
set(osgXR_VERSION "${osgXR_MAJOR_VERSION}.${osgXR_MINOR_VERSION}.${osgXR_PATCH_VERSION}")
|
||||
|
||||
|
@ -22,6 +22,7 @@ if(CMAKE_PROJECT_NAME STREQUAL osgXR)
|
|||
# Build options
|
||||
option(BUILD_SHARED_LIBS "Whether to build as a shared library" ON)
|
||||
option(BUILD_OSGXR_EXAMPLES "Enable to build osgXR examples" OFF)
|
||||
option(OSGXR_WARNINGS "Enable compiler warnings for osgXR" OFF)
|
||||
|
||||
# Source files in src/
|
||||
add_subdirectory(src)
|
||||
|
|
2
3rdparty/osgXR/README.md
vendored
2
3rdparty/osgXR/README.md
vendored
|
@ -41,7 +41,7 @@ Getting Started
|
|||
To import osgXR into a CMake based project, you can use the included CMake
|
||||
module, adding something like this to your CMakeLists.txt:
|
||||
```cmake
|
||||
find_package(osgXR 0.3.5 REQUIRED)
|
||||
find_package(osgXR 0.3.8 REQUIRED)
|
||||
|
||||
target_link_libraries(target
|
||||
..
|
||||
|
|
195
3rdparty/osgXR/include/osgXR/Settings
vendored
195
3rdparty/osgXR/include/osgXR/Settings
vendored
|
@ -171,7 +171,7 @@ class OSGXR_EXPORT Settings : public osg::Referenced
|
|||
} BlendMode;
|
||||
/**
|
||||
* Specify a preferred environment blend mode.
|
||||
* The chosen environment blend mode is permitted for use, and will be
|
||||
* The chosen environment blend mode is allowed for use, and will be
|
||||
* chosen in preference to any other supported environment blend modes
|
||||
* specified by allowEnvBlendMode() if supported by OpenXR.
|
||||
* @param mode Environment blend mode to prefer.
|
||||
|
@ -183,8 +183,8 @@ class OSGXR_EXPORT Settings : public osg::Referenced
|
|||
_allowedEnvBlendModeMask |= mask;
|
||||
}
|
||||
/**
|
||||
* Specify a permitted environment blend mode.
|
||||
* The chosen environment blend mode is permitted for use, and may be
|
||||
* Specify an allowed environment blend mode.
|
||||
* The chosen environment blend mode is allowed for use, and may be
|
||||
* chosen if supported by OpenXR when none of the preferred environment
|
||||
* blend modes specified by preferEnvBlenMode() are supported by OpenXR.
|
||||
* @param mode Environment blend mode to prefer.
|
||||
|
@ -204,7 +204,7 @@ class OSGXR_EXPORT Settings : public osg::Referenced
|
|||
{
|
||||
_preferredEnvBlendModeMask = preferredEnvBlendModeMask;
|
||||
}
|
||||
/// Get the bitmask of permitted environment blend modes.
|
||||
/// Get the bitmask of allowed environment blend modes.
|
||||
uint32_t getAllowedEnvBlendModeMask() const
|
||||
{
|
||||
return _allowedEnvBlendModeMask;
|
||||
|
@ -264,6 +264,172 @@ class OSGXR_EXPORT Settings : public osg::Referenced
|
|||
return _swapchainMode;
|
||||
}
|
||||
|
||||
/// RGB(A) / depth encodings.
|
||||
typedef enum Encoding
|
||||
{
|
||||
/** Discrete linear encoding of RGB(A).
|
||||
* The OpenXR runtime may perform its own conversion from RGB to
|
||||
* sRGB for display on HMD, so the app should ensure it leaves RGB
|
||||
* values linear to avoid an over-bright image.
|
||||
*/
|
||||
ENCODING_LINEAR = 0,
|
||||
/** Floating-point linear encoding of RGB(A).
|
||||
* The OpenXR runtime may perform its own conversion from RGB to
|
||||
* sRGB for display on HMD, so the app should ensure it leaves RGB
|
||||
* values linear to avoid an over-bright image.
|
||||
*/
|
||||
ENCODING_FLOAT = 1,
|
||||
/** Discrete non-linear sRGB encoding with linear (A).
|
||||
* Linear RGB values should be converted to sRGB, for example with
|
||||
* GL_FRAMEBUFFER_SRGB or via fragment shader code, as the OpenXR
|
||||
* runtime will treat them as non-linear.
|
||||
* Not applicable to depth/stencil swapchains.
|
||||
*/
|
||||
ENCODING_SRGB = 2,
|
||||
} Encoding;
|
||||
|
||||
/**
|
||||
* Specify a preferred RGB(A) encoding.
|
||||
* The chosen RGB(A) encoding is allowed for use, and a format with this
|
||||
* encoding will be chosen in preference to other allowed encodings
|
||||
* specified by allowRGBEncoding() if possible.
|
||||
* @param encoding RGB(A) encoding to prefer.
|
||||
*/
|
||||
void preferRGBEncoding(Encoding encoding)
|
||||
{
|
||||
uint32_t mask = (1u << (unsigned int)encoding);
|
||||
_preferredRGBEncodingMask |= mask;
|
||||
_allowedRGBEncodingMask |= mask;
|
||||
}
|
||||
/**
|
||||
* Specify an allowed RGB(A) encoding.
|
||||
* The chosen RGB(A) encoding is allowed for use, and a format with this
|
||||
* encoding may be chosen when none of the preferred color encodings
|
||||
* specified by preferRGBEncoding() are useable.
|
||||
* @param encoding RGB(A) encoding to permit.
|
||||
*/
|
||||
void allowRGBEncoding(Encoding encoding)
|
||||
{
|
||||
uint32_t mask = (1u << (unsigned int)encoding);
|
||||
_allowedRGBEncodingMask |= mask;
|
||||
}
|
||||
/// Get the bitmask of preferred RGB(A) encodings.
|
||||
uint32_t getPreferredRGBEncodingMask() const
|
||||
{
|
||||
return _preferredRGBEncodingMask;
|
||||
}
|
||||
/// Set the bitmask of preferred RGB(A) encodings.
|
||||
void setPreferredRGBEncodingMask(uint32_t preferredRGBEncodingMask)
|
||||
{
|
||||
_preferredRGBEncodingMask = preferredRGBEncodingMask;
|
||||
}
|
||||
/// Get the bitmask of allowed RGB(A) encodings.
|
||||
uint32_t getAllowedRGBEncodingMask() const
|
||||
{
|
||||
return _allowedRGBEncodingMask;
|
||||
}
|
||||
/// Set the bitmask of allowed RGB(A) encodings.
|
||||
void setAllowedRGBEncodingMask(uint32_t allowedRGBEncodingMask)
|
||||
{
|
||||
_allowedRGBEncodingMask = allowedRGBEncodingMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a preferred depth encoding.
|
||||
* The chosen depth encoding is allowed for use, and a format with this
|
||||
* encoding will be chosen in preference to other allowed encodings
|
||||
* specified by allowDepthEncoding() if possible.
|
||||
* @param encoding Depth encoding to prefer.
|
||||
*/
|
||||
void preferDepthEncoding(Encoding encoding)
|
||||
{
|
||||
uint32_t mask = (1u << (unsigned int)encoding);
|
||||
_preferredDepthEncodingMask |= mask;
|
||||
_allowedDepthEncodingMask |= mask;
|
||||
}
|
||||
/**
|
||||
* Specify an allowed depth encoding.
|
||||
* The chosen depth encoding is allowed for use, and a format with this
|
||||
* encoding may be chosen when none of the preferred color encodings
|
||||
* specified by preferDepthEncoding() are useable.
|
||||
* @param encoding Depth encoding to permit.
|
||||
*/
|
||||
void allowDepthEncoding(Encoding encoding)
|
||||
{
|
||||
uint32_t mask = (1u << (unsigned int)encoding);
|
||||
_allowedDepthEncodingMask |= mask;
|
||||
}
|
||||
/// Get the bitmask of preferred depth encodings.
|
||||
uint32_t getPreferredDepthEncodingMask() const
|
||||
{
|
||||
return _preferredDepthEncodingMask;
|
||||
}
|
||||
/// Set the bitmask of preferred depth encodings.
|
||||
void setPreferredDepthEncodingMask(uint32_t preferredDepthEncodingMask)
|
||||
{
|
||||
_preferredDepthEncodingMask = preferredDepthEncodingMask;
|
||||
}
|
||||
/// Get the bitmask of allowed depth encodings.
|
||||
uint32_t getAllowedDepthEncodingMask() const
|
||||
{
|
||||
return _allowedDepthEncodingMask;
|
||||
}
|
||||
/// Set the bitmask of allowed depth encodings.
|
||||
void setAllowedDepthEncodingMask(uint32_t allowedDepthEncodingMask)
|
||||
{
|
||||
_allowedDepthEncodingMask = allowedDepthEncodingMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of desired bits for each RGB channel in RGB(A) swapchain.
|
||||
* This only applies to linear RGB formats, not sRGB formats.
|
||||
*/
|
||||
int getRGBBits() const
|
||||
{
|
||||
return _rgbBits;
|
||||
}
|
||||
/**
|
||||
* Set number of desired bits for each RGB channel in RGB(A) swapchain.
|
||||
* This only applies to linear RGB formats, not sRGB formats.
|
||||
*/
|
||||
void setRGBBits(int rgbBits = -1)
|
||||
{
|
||||
_rgbBits = rgbBits;
|
||||
}
|
||||
|
||||
/// Get number of desired alpha bits in RGB(A) swapchain.
|
||||
int getAlphaBits() const
|
||||
{
|
||||
return _alphaBits;
|
||||
}
|
||||
/// Set the number of desired alpha bits in RGB(A) swapchain.
|
||||
void setAlphaBits(int alphaBits = -1)
|
||||
{
|
||||
_alphaBits = alphaBits;
|
||||
}
|
||||
|
||||
/// Get number of desired depth bits in depth/stencil swapchain.
|
||||
int getDepthBits() const
|
||||
{
|
||||
return _depthBits;
|
||||
}
|
||||
/// Set the number of desired depth bits in depth/stencil swapchain.
|
||||
void setDepthBits(int depthBits = -1)
|
||||
{
|
||||
_depthBits = depthBits;
|
||||
}
|
||||
|
||||
/// Get number of desired stencil bits in depth/stencil swapchain.
|
||||
int getStencilBits() const
|
||||
{
|
||||
return _stencilBits;
|
||||
}
|
||||
/// Set the number of desired stenil bits in depth/stencil swapchain.
|
||||
void setStencilBits(int stencilBits = -1)
|
||||
{
|
||||
_stencilBits = stencilBits;
|
||||
}
|
||||
|
||||
/// Get mirror settings.
|
||||
MirrorSettings &getMirrorSettings()
|
||||
{
|
||||
|
@ -303,8 +469,14 @@ class OSGXR_EXPORT Settings : public osg::Referenced
|
|||
DIFF_BLEND_MODE = (1u << 5),
|
||||
DIFF_VR_MODE = (1u << 6),
|
||||
DIFF_SWAPCHAIN_MODE = (1u << 7),
|
||||
DIFF_MIRROR = (1u << 8),
|
||||
DIFF_SCALE = (1u << 9),
|
||||
DIFF_RGB_ENCODING = (1u << 8),
|
||||
DIFF_DEPTH_ENCODING = (1u << 9),
|
||||
DIFF_RGB_BITS = (1u << 10),
|
||||
DIFF_ALPHA_BITS = (1u << 11),
|
||||
DIFF_DEPTH_BITS = (1u << 12),
|
||||
DIFF_STENCIL_BITS = (1u << 13),
|
||||
DIFF_MIRROR = (1u << 14),
|
||||
DIFF_SCALE = (1u << 15),
|
||||
} _ChangeMask;
|
||||
|
||||
unsigned int _diff(const Settings &other) const;
|
||||
|
@ -333,6 +505,17 @@ class OSGXR_EXPORT Settings : public osg::Referenced
|
|||
VRMode _vrMode;
|
||||
SwapchainMode _swapchainMode;
|
||||
|
||||
// Swapchain requirements
|
||||
uint32_t _preferredRGBEncodingMask;
|
||||
uint32_t _allowedRGBEncodingMask;
|
||||
uint32_t _preferredDepthEncodingMask;
|
||||
uint32_t _allowedDepthEncodingMask;
|
||||
// These default to -1: get bit depths from graphics window traits
|
||||
int _rgbBits; // for linear RGB formats, per channel
|
||||
int _alphaBits;
|
||||
int _depthBits;
|
||||
int _stencilBits;
|
||||
|
||||
// Mirror settings
|
||||
MirrorSettings _mirrorSettings;
|
||||
|
||||
|
|
15
3rdparty/osgXR/src/CMakeLists.txt
vendored
15
3rdparty/osgXR/src/CMakeLists.txt
vendored
|
@ -97,7 +97,20 @@ target_compile_features(osgXR
|
|||
# smart pointers
|
||||
PUBLIC cxx_std_11
|
||||
# std::optional
|
||||
PRIVATE cxx_std_17)
|
||||
PRIVATE cxx_std_17
|
||||
)
|
||||
|
||||
# Enable compiler warnings
|
||||
if(OSGXR_WARNINGS)
|
||||
target_compile_options(osgXR PRIVATE
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
|
||||
-Wall -pedantic
|
||||
-Wextra -Wno-missing-field-initializers
|
||||
-Wno-unused-parameter>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:
|
||||
/W4>
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(osgXR
|
||||
PRIVATE
|
||||
|
|
2
3rdparty/osgXR/src/Mirror.cpp
vendored
2
3rdparty/osgXR/src/Mirror.cpp
vendored
|
@ -127,8 +127,10 @@ void Mirror::setupQuad(unsigned int viewIndex,
|
|||
|
||||
osg::ref_ptr<osg::StateSet> state = quad->getOrCreateStateSet();
|
||||
int forceOff = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED;
|
||||
int forceOn = osg::StateAttribute::ON | osg::StateAttribute::PROTECTED;
|
||||
state->setMode(GL_LIGHTING, forceOff);
|
||||
state->setMode(GL_DEPTH_TEST, forceOff);
|
||||
state->setMode(GL_FRAMEBUFFER_SRGB, forceOn);
|
||||
|
||||
_camera->addChild(quad);
|
||||
|
||||
|
|
22
3rdparty/osgXR/src/Settings.cpp
vendored
22
3rdparty/osgXR/src/Settings.cpp
vendored
|
@ -20,6 +20,14 @@ Settings::Settings() :
|
|||
_allowedEnvBlendModeMask(0),
|
||||
_vrMode(VRMODE_AUTOMATIC),
|
||||
_swapchainMode(SWAPCHAIN_AUTOMATIC),
|
||||
_preferredRGBEncodingMask(0),
|
||||
_allowedRGBEncodingMask(0),
|
||||
_preferredDepthEncodingMask(0),
|
||||
_allowedDepthEncodingMask(0),
|
||||
_rgbBits(-1),
|
||||
_alphaBits(-1),
|
||||
_depthBits(-1),
|
||||
_stencilBits(-1),
|
||||
_unitsPerMeter(1.0f)
|
||||
{
|
||||
}
|
||||
|
@ -55,6 +63,20 @@ unsigned int Settings::_diff(const Settings &other) const
|
|||
ret |= DIFF_VR_MODE;
|
||||
if (_swapchainMode != other._swapchainMode)
|
||||
ret |= DIFF_SWAPCHAIN_MODE;
|
||||
if (_preferredRGBEncodingMask != other._preferredRGBEncodingMask ||
|
||||
_allowedRGBEncodingMask != other._allowedRGBEncodingMask)
|
||||
ret |= DIFF_RGB_ENCODING;
|
||||
if (_preferredDepthEncodingMask != other._preferredDepthEncodingMask ||
|
||||
_allowedDepthEncodingMask != other._allowedDepthEncodingMask)
|
||||
ret |= DIFF_DEPTH_ENCODING;
|
||||
if (_rgbBits != other._rgbBits)
|
||||
ret |= DIFF_RGB_BITS;
|
||||
if (_alphaBits != other._alphaBits)
|
||||
ret |= DIFF_ALPHA_BITS;
|
||||
if (_depthBits != other._depthBits)
|
||||
ret |= DIFF_DEPTH_BITS;
|
||||
if (_stencilBits != other._stencilBits)
|
||||
ret |= DIFF_STENCIL_BITS;
|
||||
if (_mirrorSettings != other._mirrorSettings)
|
||||
ret |= DIFF_MIRROR;
|
||||
if (_unitsPerMeter != other._unitsPerMeter)
|
||||
|
|
246
3rdparty/osgXR/src/XRState.cpp
vendored
246
3rdparty/osgXR/src/XRState.cpp
vendored
|
@ -62,7 +62,8 @@ XRState::XRSwapchain::XRSwapchain(XRState *state,
|
|||
osg::ref_ptr<OpenXR::Session> session,
|
||||
const OpenXR::System::ViewConfiguration::View &view,
|
||||
int64_t chosenSwapchainFormat,
|
||||
int64_t chosenDepthSwapchainFormat) :
|
||||
int64_t chosenDepthSwapchainFormat,
|
||||
GLenum fallbackDepthFormat) :
|
||||
OpenXR::SwapchainGroup(session, view,
|
||||
XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
chosenSwapchainFormat,
|
||||
|
@ -95,6 +96,7 @@ XRState::XRSwapchain::XRSwapchain(XRState *state,
|
|||
XRFramebuffer *fb = new XRFramebuffer(getWidth(),
|
||||
getHeight(),
|
||||
texture, depthTexture);
|
||||
fb->setDepthFormat(fallbackDepthFormat);
|
||||
_imageFramebuffers.push_back(fb);
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +520,13 @@ void XRState::syncSettings()
|
|||
else if (diff & (Settings::DIFF_DEPTH_INFO |
|
||||
Settings::DIFF_VISIBILITY_MASK |
|
||||
Settings::DIFF_VR_MODE |
|
||||
Settings::DIFF_SWAPCHAIN_MODE))
|
||||
Settings::DIFF_SWAPCHAIN_MODE |
|
||||
Settings::DIFF_RGB_ENCODING |
|
||||
Settings::DIFF_DEPTH_ENCODING |
|
||||
Settings::DIFF_RGB_BITS |
|
||||
Settings::DIFF_ALPHA_BITS |
|
||||
Settings::DIFF_DEPTH_BITS |
|
||||
Settings::DIFF_STENCIL_BITS))
|
||||
// Recreate session
|
||||
setDownState(VRSTATE_SYSTEM);
|
||||
}
|
||||
|
@ -952,6 +960,14 @@ XRState::UpResult XRState::upSession()
|
|||
_settingsCopy.setVisibilityMask(_settings->getVisibilityMask());
|
||||
_settingsCopy.setVRMode(_settings->getVRMode());
|
||||
_settingsCopy.setSwapchainMode(_settings->getSwapchainMode());
|
||||
_settingsCopy.setPreferredRGBEncodingMask(_settings->getPreferredRGBEncodingMask());
|
||||
_settingsCopy.setAllowedRGBEncodingMask(_settings->getAllowedRGBEncodingMask());
|
||||
_settingsCopy.setPreferredDepthEncodingMask(_settings->getPreferredDepthEncodingMask());
|
||||
_settingsCopy.setAllowedDepthEncodingMask(_settings->getAllowedDepthEncodingMask());
|
||||
_settingsCopy.setRGBBits(_settings->getRGBBits());
|
||||
_settingsCopy.setAlphaBits(_settings->getAlphaBits());
|
||||
_settingsCopy.setDepthBits(_settings->getDepthBits());
|
||||
_settingsCopy.setStencilBits(_settings->getStencilBits());
|
||||
_useDepthInfo = _settingsCopy.getDepthInfo();
|
||||
_useVisibilityMask = _settingsCopy.getVisibilityMask();
|
||||
_vrMode = _settingsCopy.getVRMode();
|
||||
|
@ -967,6 +983,31 @@ XRState::UpResult XRState::upSession()
|
|||
OSG_WARN << "osgXR: VisibilityMask extension not supported, visibility masking will be disabled" << std::endl;
|
||||
_useVisibilityMask = false;
|
||||
}
|
||||
if (_settingsCopy.getAllowedRGBEncodingMask() == 0)
|
||||
{
|
||||
// Play safe and default to preferring sRGB over linear/float RGB, since
|
||||
// this is what apps are normally tuned for. This avoids incorrect
|
||||
// behaviour in SteamVR (no gamma correction) and also correct but
|
||||
// potentially unexpected behaviour in Monado (extra gamma correction of
|
||||
// linear RGB framebuffer when app produces sRGBish images already).
|
||||
_settingsCopy.allowRGBEncoding(Settings::ENCODING_SRGB);
|
||||
}
|
||||
if (_settingsCopy.getPreferredRGBEncodingMask() == 0)
|
||||
{
|
||||
// If no preferred RGB encodings, mark all allowed ones as preferred.
|
||||
_settingsCopy.setPreferredRGBEncodingMask(_settingsCopy.getAllowedRGBEncodingMask());
|
||||
}
|
||||
if (_settingsCopy.getAllowedDepthEncodingMask() == 0)
|
||||
{
|
||||
// Default to allowing both discrete or floating point depth.
|
||||
_settingsCopy.allowDepthEncoding(Settings::ENCODING_LINEAR);
|
||||
_settingsCopy.allowDepthEncoding(Settings::ENCODING_FLOAT);
|
||||
}
|
||||
if (_settingsCopy.getPreferredDepthEncodingMask() == 0)
|
||||
{
|
||||
// If no preferred depth encodings, mark all allowed ones as preferred.
|
||||
_settingsCopy.setPreferredDepthEncodingMask(_settingsCopy.getAllowedDepthEncodingMask());
|
||||
}
|
||||
|
||||
// Decide on the algorithm to use. SceneView mode is faster.
|
||||
if (_vrMode == VRMode::VRMODE_AUTOMATIC)
|
||||
|
@ -1009,52 +1050,209 @@ XRState::UpResult XRState::upSession()
|
|||
return UP_ABORT;
|
||||
}
|
||||
|
||||
// Decide on ideal depth bits
|
||||
unsigned int bestDepthBits = 24;
|
||||
// Decide on ideal bit depths
|
||||
unsigned int bestRGBBits = 24; // combined
|
||||
unsigned int bestAlphaBits = 0;
|
||||
unsigned int bestDepthBits = 16;
|
||||
unsigned int bestStencilBits = 0;
|
||||
// Use graphics window traits
|
||||
auto *traits = _window->getTraits();
|
||||
if (traits)
|
||||
{
|
||||
bestRGBBits = traits->red + traits->green + traits->blue;
|
||||
bestAlphaBits = traits->alpha;
|
||||
bestDepthBits = traits->depth;
|
||||
bestStencilBits = traits->stencil;
|
||||
}
|
||||
// Override from osgXR::Settings
|
||||
if (_settingsCopy.getRGBBits() >= 0)
|
||||
bestRGBBits = _settingsCopy.getRGBBits() * 3;
|
||||
if (_settingsCopy.getAlphaBits() >= 0)
|
||||
bestAlphaBits = _settingsCopy.getAlphaBits();
|
||||
if (_settingsCopy.getDepthBits() >= 0)
|
||||
bestDepthBits = _settingsCopy.getDepthBits();
|
||||
if (_settingsCopy.getStencilBits() >= 0)
|
||||
bestStencilBits = _settingsCopy.getStencilBits();
|
||||
|
||||
// Choose a fallback depth format in case we can't submit depth to OpenXR
|
||||
GLenum fallbackDepthFormat = 0;
|
||||
if (_settingsCopy.getPreferredDepthEncodingMask() &
|
||||
(1u << (unsigned int)Settings::ENCODING_LINEAR))
|
||||
{
|
||||
bool allowFloatDepth = _settingsCopy.getAllowedDepthEncodingMask() &
|
||||
(1u << (unsigned int)Settings::ENCODING_FLOAT);
|
||||
if (bestDepthBits > 24 && allowFloatDepth)
|
||||
fallbackDepthFormat = bestStencilBits ? GL_DEPTH32F_STENCIL8
|
||||
: GL_DEPTH_COMPONENT32F;
|
||||
else if (bestStencilBits)
|
||||
fallbackDepthFormat = GL_DEPTH24_STENCIL8;
|
||||
else if (bestDepthBits > 16)
|
||||
fallbackDepthFormat = GL_DEPTH_COMPONENT24;
|
||||
else
|
||||
fallbackDepthFormat = GL_DEPTH_COMPONENT16;
|
||||
}
|
||||
else // getPreferredDepthEncodingMask & (1 << ENCODING_FLOAT)
|
||||
{
|
||||
if (bestStencilBits)
|
||||
fallbackDepthFormat = GL_DEPTH32F_STENCIL8;
|
||||
else
|
||||
fallbackDepthFormat = GL_DEPTH_COMPONENT32F;
|
||||
}
|
||||
|
||||
// Choose a swapchain format
|
||||
int64_t chosenSwapchainFormat = 0;
|
||||
int64_t chosenDepthSwapchainFormat = 0;
|
||||
unsigned int chosenAlphaBits = 0;
|
||||
unsigned int chosenDepthBits = 0;
|
||||
unsigned int chosenStencilBits = 0;
|
||||
uint32_t chosenRGBSat = 0;
|
||||
uint32_t chosenDepthSat = 0;
|
||||
for (int64_t format: _session->getSwapchainFormats())
|
||||
{
|
||||
auto thisEncoding = Settings::ENCODING_LINEAR;
|
||||
uint32_t encodingMask = 0;
|
||||
unsigned int thisRGBBits = 0;
|
||||
unsigned int thisAlphaBits = 0;
|
||||
unsigned int thisDepthBits = 0;
|
||||
unsigned int thisStencilBits = 0;
|
||||
unsigned int thisSat = 0;
|
||||
switch (format)
|
||||
{
|
||||
// Discrete linear RGB(A)
|
||||
case GL_RGBA16:
|
||||
thisRGBBits = 16 * 3;
|
||||
thisAlphaBits = 16;
|
||||
goto handleRGBA;
|
||||
case GL_RGB10_A2:
|
||||
thisRGBBits = 10 * 3;
|
||||
thisAlphaBits = 2;
|
||||
goto handleRGBA;
|
||||
case GL_RGBA8:
|
||||
// Choose the first supported format suggested by the runtime
|
||||
if (!chosenSwapchainFormat)
|
||||
chosenSwapchainFormat = format;
|
||||
break;
|
||||
thisRGBBits = 8 * 3;
|
||||
thisAlphaBits = 8;
|
||||
goto handleRGBA;
|
||||
// Linear floating point RGB(A)
|
||||
case GL_RGB16F:
|
||||
thisRGBBits = 16 * 3;
|
||||
thisEncoding = Settings::ENCODING_FLOAT;
|
||||
goto handleRGBA;
|
||||
case GL_RGBA16F:
|
||||
thisRGBBits = 16 * 3;
|
||||
thisEncoding = Settings::ENCODING_FLOAT;
|
||||
thisAlphaBits = 16;
|
||||
goto handleRGBA;
|
||||
// Discrete sRGB (linear A)
|
||||
case GL_SRGB8_ALPHA8:
|
||||
thisEncoding = Settings::ENCODING_SRGB;
|
||||
thisAlphaBits = 8;
|
||||
goto handleRGBA;
|
||||
case GL_SRGB8:
|
||||
thisEncoding = Settings::ENCODING_SRGB;
|
||||
goto handleRGBA;
|
||||
|
||||
// Discrete depth (stencil)
|
||||
case GL_DEPTH_COMPONENT16:
|
||||
thisDepthBits = 16;
|
||||
goto handle_depth;
|
||||
goto handleDepth;
|
||||
case GL_DEPTH_COMPONENT24:
|
||||
thisDepthBits = 24;
|
||||
goto handle_depth;
|
||||
goto handleDepth;
|
||||
#if 0 // crashes nvidia (495.46, with monado)
|
||||
case GL_DEPTH24_STENCIL8:
|
||||
thisDepthBits = 24;
|
||||
thisStencilBits = 8;
|
||||
goto handleDepth;
|
||||
#endif
|
||||
case GL_DEPTH_COMPONENT32:
|
||||
thisDepthBits = 32;
|
||||
// fall through
|
||||
handle_depth:
|
||||
goto handleDepth;
|
||||
// Floating point depth, discrete stencil
|
||||
case GL_DEPTH_COMPONENT32F:
|
||||
thisEncoding = Settings::ENCODING_FLOAT;
|
||||
thisDepthBits = 32;
|
||||
goto handleDepth;
|
||||
case GL_DEPTH32F_STENCIL8:
|
||||
thisEncoding = Settings::ENCODING_FLOAT;
|
||||
thisDepthBits = 32;
|
||||
thisStencilBits = 8;
|
||||
goto handleDepth;
|
||||
|
||||
handleRGBA:
|
||||
// Don't even consider a disallowed RGB encoding
|
||||
encodingMask = (1u << (unsigned int)thisEncoding);
|
||||
if (!(_settingsCopy.getAllowedRGBEncodingMask() & encodingMask))
|
||||
break;
|
||||
|
||||
// Consider whether our preferences are satisfied
|
||||
if (_settingsCopy.getPreferredRGBEncodingMask() & encodingMask)
|
||||
thisSat |= 0x1;
|
||||
if (thisEncoding == Settings::ENCODING_SRGB || thisRGBBits >= bestRGBBits)
|
||||
thisSat |= 0x2;
|
||||
if (thisAlphaBits >= bestAlphaBits)
|
||||
thisSat |= 0x4;
|
||||
|
||||
// Skip formats that no longer satisfies some preference
|
||||
if (chosenRGBSat & ~thisSat)
|
||||
break;
|
||||
|
||||
// Decide whether to choose this format
|
||||
if (// Anything is better than nothing
|
||||
!chosenSwapchainFormat ||
|
||||
// New preferences satisfied is always better
|
||||
(~chosenRGBSat & thisSat) ||
|
||||
// All else being equal, allow improved alpha bits
|
||||
// A higher number of alpha bits is better than not enough
|
||||
(thisAlphaBits > chosenAlphaBits && chosenAlphaBits < bestAlphaBits))
|
||||
{
|
||||
chosenSwapchainFormat = format;
|
||||
chosenAlphaBits = thisAlphaBits;
|
||||
chosenRGBSat = thisSat;
|
||||
}
|
||||
break;
|
||||
|
||||
handleDepth:
|
||||
if (_useDepthInfo)
|
||||
{
|
||||
// Don't even consider a disallowed depth encoding
|
||||
encodingMask = (1u << (unsigned int)thisEncoding);
|
||||
if (!(_settingsCopy.getAllowedDepthEncodingMask() & encodingMask))
|
||||
break;
|
||||
|
||||
// Consider whether our preferences are satisfied
|
||||
if (_settingsCopy.getPreferredDepthEncodingMask() & encodingMask)
|
||||
thisSat |= 0x1;
|
||||
if (thisDepthBits >= bestDepthBits)
|
||||
thisSat |= 0x2;
|
||||
if (thisStencilBits >= bestStencilBits)
|
||||
thisSat |= 0x4;
|
||||
|
||||
// Skip formats that no longer satisfies some preference
|
||||
if (chosenDepthSat & ~thisSat)
|
||||
break;
|
||||
|
||||
if (// Anything is better than nothing
|
||||
!chosenDepthSwapchainFormat ||
|
||||
// A higher number of bits is better than not enough
|
||||
// New preferences satisfied is always better
|
||||
(~chosenRGBSat & thisSat) ||
|
||||
// A higher number of depth bits is better than not enough
|
||||
(thisDepthBits > chosenDepthBits && chosenDepthBits < bestDepthBits) ||
|
||||
// A lower number of bits may still be enough
|
||||
(bestDepthBits < thisDepthBits && thisDepthBits < chosenDepthBits))
|
||||
// A higher number of stencil bits is better than not enough
|
||||
// so long as depth bits are no worse or good enough
|
||||
((thisDepthBits >= chosenDepthBits || thisDepthBits >= bestDepthBits) &&
|
||||
thisStencilBits > chosenStencilBits && chosenStencilBits < bestStencilBits) ||
|
||||
// A lower number of depth bits may still be enough
|
||||
// so long as stencil bits are no worse or good enough
|
||||
((thisStencilBits >= chosenStencilBits || thisStencilBits >= bestStencilBits) &&
|
||||
bestDepthBits < thisDepthBits && thisDepthBits < chosenDepthBits))
|
||||
{
|
||||
chosenDepthSwapchainFormat = format;
|
||||
chosenDepthBits = thisDepthBits;
|
||||
chosenStencilBits = thisStencilBits;
|
||||
chosenDepthSat = thisSat;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1086,7 +1284,8 @@ XRState::UpResult XRState::upSession()
|
|||
{
|
||||
case SwapchainMode::SWAPCHAIN_SINGLE:
|
||||
if (!setupSingleSwapchain(chosenSwapchainFormat,
|
||||
chosenDepthSwapchainFormat))
|
||||
chosenDepthSwapchainFormat,
|
||||
fallbackDepthFormat))
|
||||
{
|
||||
_session = nullptr;
|
||||
return UP_ABORT;
|
||||
|
@ -1097,7 +1296,8 @@ XRState::UpResult XRState::upSession()
|
|||
// Should already have been handled by upSession()
|
||||
case SwapchainMode::SWAPCHAIN_MULTIPLE:
|
||||
if (!setupMultipleSwapchains(chosenSwapchainFormat,
|
||||
chosenDepthSwapchainFormat))
|
||||
chosenDepthSwapchainFormat,
|
||||
fallbackDepthFormat))
|
||||
{
|
||||
_session = nullptr;
|
||||
return UP_ABORT;
|
||||
|
@ -1172,7 +1372,8 @@ XRState::DownResult XRState::downActions()
|
|||
return DOWN_SUCCESS;
|
||||
}
|
||||
|
||||
bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat)
|
||||
bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat,
|
||||
GLenum fallbackDepthFormat)
|
||||
{
|
||||
const auto &views = _chosenViewConfig->getViews();
|
||||
_xrViews.reserve(views.size());
|
||||
|
@ -1187,7 +1388,8 @@ bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat)
|
|||
// Create a single swapchain
|
||||
osg::ref_ptr<XRSwapchain> xrSwapchain = new XRSwapchain(this, _session,
|
||||
singleView, format,
|
||||
depthFormat);
|
||||
depthFormat,
|
||||
fallbackDepthFormat);
|
||||
// And the views
|
||||
_xrViews.reserve(views.size());
|
||||
for (uint32_t i = 0; i < views.size(); ++i)
|
||||
|
@ -1205,7 +1407,8 @@ bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool XRState::setupMultipleSwapchains(int64_t format, int64_t depthFormat)
|
||||
bool XRState::setupMultipleSwapchains(int64_t format, int64_t depthFormat,
|
||||
GLenum fallbackDepthFormat)
|
||||
{
|
||||
const auto &views = _chosenViewConfig->getViews();
|
||||
_xrViews.reserve(views.size());
|
||||
|
@ -1215,7 +1418,8 @@ bool XRState::setupMultipleSwapchains(int64_t format, int64_t depthFormat)
|
|||
const auto &vcView = views[i];
|
||||
osg::ref_ptr<XRSwapchain> xrSwapchain = new XRSwapchain(this, _session,
|
||||
vcView, format,
|
||||
depthFormat);
|
||||
depthFormat,
|
||||
fallbackDepthFormat);
|
||||
osg::ref_ptr<XRView> xrView = new XRView(this, i, xrSwapchain);
|
||||
if (!xrView.valid())
|
||||
{
|
||||
|
|
9
3rdparty/osgXR/src/XRState.h
vendored
9
3rdparty/osgXR/src/XRState.h
vendored
|
@ -62,7 +62,8 @@ class XRState : public OpenXR::EventHandler
|
|||
osg::ref_ptr<OpenXR::Session> session,
|
||||
const OpenXR::System::ViewConfiguration::View &view,
|
||||
int64_t chosenSwapchainFormat,
|
||||
int64_t chosenDepthSwapchainFormat);
|
||||
int64_t chosenDepthSwapchainFormat,
|
||||
GLenum fallbackDepthFormat);
|
||||
|
||||
// GL context must be current (for XRFramebuffer)
|
||||
virtual ~XRSwapchain();
|
||||
|
@ -502,9 +503,11 @@ class XRState : public OpenXR::EventHandler
|
|||
DownResult downActions();
|
||||
|
||||
// Set up a single swapchain containing multiple viewports
|
||||
bool setupSingleSwapchain(int64_t format, int64_t depthFormat = 0);
|
||||
bool setupSingleSwapchain(int64_t format, int64_t depthFormat = 0,
|
||||
GLenum fallbackDepthFormat = 0);
|
||||
// Set up a swapchain for each view
|
||||
bool setupMultipleSwapchains(int64_t format, int64_t depthFormat = 0);
|
||||
bool setupMultipleSwapchains(int64_t format, int64_t depthFormat = 0,
|
||||
GLenum fallbackDepthFormat = 0);
|
||||
// Set up slave cameras
|
||||
void setupSlaveCameras();
|
||||
// Set up SceneView VR mode cameras
|
||||
|
|
Loading…
Add table
Reference in a new issue