mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 16:15:31 +00:00
New config options
This commit is contained in:
parent
290068b871
commit
89ff075936
7 changed files with 112 additions and 43 deletions
|
@ -346,7 +346,7 @@ namespace MWVR
|
|||
|
||||
for (auto format : swapchainFormats)
|
||||
{
|
||||
ss << " Enum=" << std::dec << format << " (0x=" << std::hex << format << ")" << std::endl;
|
||||
ss << " Enum=" << std::dec << format << " (0x=" << std::hex << format << ")" << std::dec << std::endl;
|
||||
}
|
||||
|
||||
Log(Debug::Verbose) << ss.str();
|
||||
|
@ -375,7 +375,7 @@ namespace MWVR
|
|||
auto error = glGetError();
|
||||
while (error != GL_NO_ERROR)
|
||||
{
|
||||
Log(Debug::Warning) << "glGetError: " << std::dec << error << " (0x" << std::hex << error << ")";
|
||||
Log(Debug::Warning) << "glGetError: " << std::dec << error << " (0x" << std::hex << error << ")" << std::dec;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,12 +745,12 @@ namespace MWVR
|
|||
std::array<SwapchainConfig, 2> config{};
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
config[i] = SwapchainConfig{
|
||||
mConfigViews[i].recommendedImageRectWidth,
|
||||
mConfigViews[i].maxImageRectWidth,
|
||||
mConfigViews[i].recommendedImageRectHeight,
|
||||
mConfigViews[i].maxImageRectHeight,
|
||||
mConfigViews[i].recommendedSwapchainSampleCount,
|
||||
mConfigViews[i].recommendedSwapchainSampleCount,
|
||||
(int)mConfigViews[i].recommendedImageRectWidth,
|
||||
(int)mConfigViews[i].recommendedImageRectHeight,
|
||||
(int)mConfigViews[i].recommendedSwapchainSampleCount,
|
||||
(int)mConfigViews[i].maxImageRectWidth,
|
||||
(int)mConfigViews[i].maxImageRectHeight,
|
||||
(int)mConfigViews[i].maxSwapchainSampleCount,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
namespace MWVR {
|
||||
OpenXRSwapchainImpl::OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config)
|
||||
: mWidth((int)config.recommendedWidth)
|
||||
, mHeight((int)config.recommendedHeight)
|
||||
, mSamples((int)config.recommendedSamples)
|
||||
: mWidth(config.selectedWidth)
|
||||
, mHeight(config.selectedHeight)
|
||||
, mSamples(config.selectedSamples)
|
||||
{
|
||||
if (mWidth <= 0)
|
||||
throw std::invalid_argument("Width must be a positive integer");
|
||||
|
@ -48,7 +48,7 @@ namespace MWVR {
|
|||
throw std::runtime_error("Swapchain color format not supported");
|
||||
}
|
||||
mSwapchainColorFormat = *swapchainFormatIt;
|
||||
Log(Debug::Verbose) << "Selected color format: " << std::dec << mSwapchainColorFormat << " (" << std::hex << mSwapchainColorFormat << ")";
|
||||
Log(Debug::Verbose) << "Selected color format: " << std::dec << mSwapchainColorFormat << " (" << std::hex << mSwapchainColorFormat << ")" << std::dec;
|
||||
|
||||
if (xr->xrExtensionIsEnabled(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME))
|
||||
{
|
||||
|
@ -69,16 +69,10 @@ namespace MWVR {
|
|||
{
|
||||
mSwapchainDepthFormat = *swapchainFormatIt;
|
||||
mHaveDepthSwapchain = true;
|
||||
Log(Debug::Verbose) << "Selected depth format: " << std::dec << mSwapchainDepthFormat << " (" << std::hex << mSwapchainDepthFormat << ")";
|
||||
Log(Debug::Verbose) << "Selected depth format: " << std::dec << mSwapchainDepthFormat << " (" << std::hex << mSwapchainDepthFormat << ")" << std::dec;
|
||||
}
|
||||
}
|
||||
|
||||
mSamples = Settings::Manager::getInt("antialiasing", "Video");
|
||||
// OpenXR requires a non-zero value
|
||||
if (mSamples < 1)
|
||||
mSamples = 1;
|
||||
|
||||
|
||||
XrSwapchainCreateInfo swapchainCreateInfo{ XR_TYPE_SWAPCHAIN_CREATE_INFO };
|
||||
swapchainCreateInfo.arraySize = 1;
|
||||
swapchainCreateInfo.width = mWidth;
|
||||
|
|
|
@ -99,12 +99,15 @@ namespace MWVR
|
|||
|
||||
struct SwapchainConfig
|
||||
{
|
||||
uint32_t recommendedWidth = -1;
|
||||
uint32_t maxWidth = -1;
|
||||
uint32_t recommendedHeight = -1;
|
||||
uint32_t maxHeight = -1;
|
||||
uint32_t recommendedSamples = -1;
|
||||
uint32_t maxSamples = -1;
|
||||
int recommendedWidth = -1;
|
||||
int recommendedHeight = -1;
|
||||
int recommendedSamples = -1;
|
||||
int maxWidth = -1;
|
||||
int maxHeight = -1;
|
||||
int maxSamples = -1;
|
||||
int selectedWidth = -1;
|
||||
int selectedHeight = -1;
|
||||
int selectedSamples = -1;
|
||||
};
|
||||
|
||||
struct FrameInfo
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include <components/sceneutil/mwshadowtechnique.hpp>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
|
||||
|
@ -52,6 +54,28 @@ namespace MWVR
|
|||
mViewer->renderingTraversals();
|
||||
}
|
||||
|
||||
int parseResolution(std::string conf, int recommended, int max)
|
||||
{
|
||||
if (Misc::StringUtils::isNumber(conf))
|
||||
{
|
||||
int res = std::atoi(conf.c_str());
|
||||
if (res <= 0)
|
||||
return recommended;
|
||||
if (res > max)
|
||||
return max;
|
||||
return res;
|
||||
}
|
||||
conf = Misc::StringUtils::lowerCase(conf);
|
||||
if (conf == "auto" || conf == "recommended")
|
||||
{
|
||||
return recommended;
|
||||
}
|
||||
if (conf == "max")
|
||||
{
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
void VRViewer::realize(osg::GraphicsContext* context)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
|
@ -86,19 +110,49 @@ namespace MWVR
|
|||
osg::Vec4 clearColor = mainCamera->getClearColor();
|
||||
auto config = xr->getRecommendedSwapchainConfig();
|
||||
bool mirror = Settings::Manager::getBool("mirror texture", "VR");
|
||||
mFlipMirrorTextureOrder = Settings::Manager::getBool("flip mirror texture order", "VR");
|
||||
std::string mirrorTextureEyeString = Settings::Manager::getString("mirror texture eye", "VR");
|
||||
mirrorTextureEyeString = Misc::StringUtils::lowerCase(mirrorTextureEyeString);
|
||||
if (mirrorTextureEyeString == "left" || mirrorTextureEyeString == "both")
|
||||
mMirrorTextureViews.push_back(sViewNames[(int)Side::LEFT_SIDE]);
|
||||
if (mirrorTextureEyeString == "right" || mirrorTextureEyeString == "both")
|
||||
mMirrorTextureViews.push_back(sViewNames[(int)Side::RIGHT_SIDE]);
|
||||
if (Settings::Manager::getBool("flip mirror texture order", "VR"))
|
||||
std::reverse(mMirrorTextureViews.begin(), mMirrorTextureViews.end());
|
||||
// TODO: If mirror is false either hide the window or paste something meaningful into it.
|
||||
// E.g. Fanart of Dagoth UR wearing a VR headset
|
||||
|
||||
std::array<std::string, 2> xConfString;
|
||||
std::array<std::string, 2> yConfString;
|
||||
xConfString[0] = Settings::Manager::getString("left eye resolution x", "VR");
|
||||
yConfString[0] = Settings::Manager::getString("left eye resolution y", "VR");
|
||||
|
||||
xConfString[1] = Settings::Manager::getString("right eye resolution x", "VR");
|
||||
yConfString[1] = Settings::Manager::getString("right eye resolution y", "VR");
|
||||
|
||||
for (unsigned i = 0; i < sViewNames.size(); i++)
|
||||
{
|
||||
auto view = new VRView(sViewNames[i], config[i], context->getState());
|
||||
mViews[sViewNames[i]] = view;
|
||||
auto camera = mCameras[sViewNames[i]] = view->createCamera(i + 2, clearColor, context);
|
||||
auto name = sViewNames[i];
|
||||
|
||||
config[i].selectedWidth = parseResolution(xConfString[i], config[i].recommendedWidth, config[i].maxWidth);
|
||||
config[i].selectedHeight = parseResolution(yConfString[i], config[i].recommendedHeight, config[i].maxHeight);
|
||||
|
||||
config[i].selectedSamples = Settings::Manager::getInt("antialiasing", "Video");
|
||||
// OpenXR requires a non-zero value
|
||||
if (config[i].selectedSamples < 1)
|
||||
config[i].selectedSamples = 1;
|
||||
|
||||
Log(Debug::Verbose) << name << " resolution: Recommended x=" << config[i].recommendedWidth << ", y=" << config[i].recommendedHeight;
|
||||
Log(Debug::Verbose) << name << " resolution: Max x=" << config[i].maxWidth << ", y=" << config[i].maxHeight;
|
||||
Log(Debug::Verbose) << name << " resolution: Selected x=" << config[i].selectedWidth << ", y=" << config[i].selectedHeight;
|
||||
|
||||
|
||||
auto view = new VRView(name, config[i], context->getState());
|
||||
mViews[name] = view;
|
||||
auto camera = mCameras[name] = view->createCamera(i + 2, clearColor, context);
|
||||
camera->setPreDrawCallback(mPreDraw);
|
||||
camera->setFinalDrawCallback(mPostDraw);
|
||||
camera->setCullMask(~MWRender::Mask_GUI & ~MWRender::Mask_SimpleWater & ~MWRender::Mask_UpdateVisitor);
|
||||
camera->setName(sViewNames[i]);
|
||||
camera->setName(name);
|
||||
if (smallFeatureCulling)
|
||||
camera->setSmallFeatureCullingPixelSize(smallFeatureCullingPixelSize);
|
||||
camera->setCullingMode(cullingMode);
|
||||
|
@ -154,22 +208,18 @@ namespace MWVR
|
|||
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||
|
||||
int screenWidth = mCameras["MainCamera"]->getViewport()->width();
|
||||
int mirrorWidth = screenWidth / 2;
|
||||
int mirrorWidth = screenWidth / mMirrorTextureViews.size();
|
||||
int screenHeight = mCameras["MainCamera"]->getViewport()->height();
|
||||
|
||||
// Since OpenXR does not include native support for mirror textures, we have to generate them ourselves
|
||||
// which means resolving msaa twice. If this is a performance concern, add an option to disable the mirror texture.
|
||||
for (unsigned i = 0; i < sViewNames.size(); i++)
|
||||
// which means resolving msaa twice.
|
||||
for (unsigned i = 0; i < mMirrorTextureViews.size(); i++)
|
||||
{
|
||||
auto& resolveTexture = *mMsaaResolveMirrorTexture[i];
|
||||
resolveTexture.bindFramebuffer(gc, GL_FRAMEBUFFER_EXT);
|
||||
mViews[sViewNames[i]]->swapchain().renderBuffer()->blit(gc, 0, 0, resolveTexture.width(), resolveTexture.height());
|
||||
mViews[mMirrorTextureViews[i]]->swapchain().renderBuffer()->blit(gc, 0, 0, resolveTexture.width(), resolveTexture.height());
|
||||
mMirrorTexture->bindFramebuffer(gc, GL_FRAMEBUFFER_EXT);
|
||||
|
||||
unsigned mirrorIndex = i;
|
||||
if (mFlipMirrorTextureOrder)
|
||||
mirrorIndex = sViewNames.size() - 1 - i;
|
||||
resolveTexture.blit(gc, mirrorIndex * mirrorWidth, 0, (mirrorIndex + 1) * mirrorWidth, screenHeight);
|
||||
resolveTexture.blit(gc, i * mirrorWidth, 0, (i + 1) * mirrorWidth, screenHeight);
|
||||
}
|
||||
|
||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace MWVR
|
|||
std::mutex mMutex{};
|
||||
|
||||
bool mConfigured{ false };
|
||||
bool mFlipMirrorTextureOrder{ false };
|
||||
std::vector<std::string> mMirrorTextureViews;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,19 @@ public:
|
|||
return out;
|
||||
}
|
||||
|
||||
/// true if the string is a number
|
||||
static bool isNumber(const std::string& in)
|
||||
{
|
||||
for (auto c : in)
|
||||
{
|
||||
if (!std::isdigit(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct CiComp
|
||||
{
|
||||
bool operator()(const std::string& left, const std::string& right) const
|
||||
|
|
|
@ -909,6 +909,18 @@ real height = 1.85
|
|||
# If enabled, the game window will show your VR view. If not, it will show nothing.
|
||||
mirror texture = true
|
||||
|
||||
# If mirror texture is enabled, what eye to pick. Must be 'left', 'right', or 'both'.
|
||||
mirror texture eye = right
|
||||
|
||||
# If true, draw left eye on the right and vice versa to allow cross-eyed view.
|
||||
flip mirror texture order = false
|
||||
|
||||
# Resolution of each eye. 'auto' or 'recommended' uses the resolution recommended by openxr. 'max' uses the greater available resolution. If a resolution greater than the maximum reported by openxr is selected, the max recommended by openxr is used instead. The recommended and maximum resolutions will be output in openmw.log during startup.
|
||||
left eye resolution x = auto
|
||||
left eye resolution y = auto
|
||||
right eye resolution x = auto
|
||||
right eye resolution y = auto
|
||||
|
||||
# Openmw will sync with openxr at the beginning of this phase in the rendering pipeline. From early to late in the pipeline the options are update, cull, draw, and swap in that order. If you experience visual glitches such as frames jittering across your vision, try changing this to an earlier phase.
|
||||
openxr sync phase = draw
|
||||
|
||||
|
@ -921,9 +933,6 @@ realistic combat maximum swing velocity = 4.0
|
|||
# Enables controller vibrations when you hit or are hit.
|
||||
haptics enabled = true
|
||||
|
||||
# Flip the order of eyes in the mirror texture (to allow cross eyed view)
|
||||
flip mirror texture order = false
|
||||
|
||||
# Work around for some preview openxr runtimes whose display time predictions do not work
|
||||
# Use this if tracking seems crazy.
|
||||
use steady clock = false
|
||||
|
|
Loading…
Reference in a new issue