1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 22:45:34 +00:00

New config options

This commit is contained in:
Mads Buvik Sandvei 2020-08-07 23:33:21 +02:00
parent 290068b871
commit 89ff075936
7 changed files with 112 additions and 43 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -99,7 +99,7 @@ namespace MWVR
std::mutex mMutex{};
bool mConfigured{ false };
bool mFlipMirrorTextureOrder{ false };
std::vector<std::string> mMirrorTextureViews;
};
}

View file

@ -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

View file

@ -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