1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-05 14:15:40 +00:00

With the 1x1 background window trick, we can apply VSync without restart. Some issues left though.

This commit is contained in:
scrawl 2013-02-05 19:22:08 +01:00
parent 499f3ac0d1
commit c4d518132f
8 changed files with 90 additions and 16 deletions

View file

@ -39,6 +39,9 @@ namespace MWBase
virtual int getNumActions() = 0; virtual int getNumActions() = 0;
virtual void enableDetectingBindingMode (int action) = 0; virtual void enableDetectingBindingMode (int action) = 0;
virtual void resetToDefaultBindings() = 0; virtual void resetToDefaultBindings() = 0;
virtual void create () = 0;
virtual void destroy () = 0;
}; };
} }

View file

@ -370,14 +370,10 @@ namespace MWGui
apply(); apply();
} }
} }
else if (_sender == mVSyncButton)
{
Settings::Manager::setBool("vsync", "Video", newState);
MWBase::Environment::get().getWindowManager()->
messageBox("VSync will be applied after a restart", std::vector<std::string>());
}
else else
{ {
if (_sender == mVSyncButton)
Settings::Manager::setBool("vsync", "Video", newState);
if (_sender == mWaterShaderButton) if (_sender == mWaterShaderButton)
Settings::Manager::setBool("shader", "Water", newState); Settings::Manager::setBool("shader", "Water", newState);
else if (_sender == mRefractionButton) else if (_sender == mRefractionButton)

View file

@ -41,9 +41,11 @@ namespace MWInput
, mMouseX(ogre.getWindow()->getWidth ()/2.f) , mMouseX(ogre.getWindow()->getWidth ()/2.f)
, mMouseY(ogre.getWindow()->getHeight ()/2.f) , mMouseY(ogre.getWindow()->getHeight ()/2.f)
, mMouseWheel(0) , mMouseWheel(0)
, mUserFile(userFile)
, mDragDrop(false) , mDragDrop(false)
, mGuiCursorEnabled(false) , mGuiCursorEnabled(false)
, mDebug(debug)
, mUserFile(userFile)
, mUserFileExists(userFileExists)
, mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
, mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input"))
, mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input"))
@ -51,8 +53,15 @@ namespace MWInput
, mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input")) , mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input"))
, mPreviewPOVDelay(0.f) , mPreviewPOVDelay(0.f)
, mTimeIdle(0.f) , mTimeIdle(0.f)
, mCreated(false)
{ {
Ogre::RenderWindow* window = ogre.getWindow (); create();
}
void InputManager::create()
{
Ogre::RenderWindow* window = mOgre.getWindow ();
size_t windowHnd; size_t windowHnd;
resetIdleTime(); resetIdleTime();
@ -67,7 +76,7 @@ namespace MWInput
// Set non-exclusive mouse and keyboard input if the user requested // Set non-exclusive mouse and keyboard input if the user requested
// it. // it.
if (debug) if (mDebug)
{ {
#if defined OIS_WIN32_PLATFORM #if defined OIS_WIN32_PLATFORM
pl.insert(std::make_pair(std::string("w32_mouse"), pl.insert(std::make_pair(std::string("w32_mouse"),
@ -112,7 +121,7 @@ namespace MWInput
MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs); MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs);
std::string file = userFileExists ? userFile : ""; std::string file = mUserFileExists ? mUserFile : "";
mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
loadKeyDefaults(); loadKeyDefaults();
@ -131,9 +140,11 @@ namespace MWInput
mControlSwitch["vanitymode"] = true; mControlSwitch["vanitymode"] = true;
changeInputMode(false); changeInputMode(false);
mCreated = true;
} }
InputManager::~InputManager() void InputManager::destroy()
{ {
mInputCtrl->save (mUserFile); mInputCtrl->save (mUserFile);
@ -142,6 +153,12 @@ namespace MWInput
mInputManager->destroyInputObject(mKeyboard); mInputManager->destroyInputObject(mKeyboard);
mInputManager->destroyInputObject(mMouse); mInputManager->destroyInputObject(mMouse);
OIS::InputManager::destroyInputSystem(mInputManager); OIS::InputManager::destroyInputSystem(mInputManager);
mCreated = false;
}
InputManager::~InputManager()
{
destroy();
} }
void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue)
@ -239,6 +256,7 @@ namespace MWInput
void InputManager::update(float dt, bool loading) void InputManager::update(float dt, bool loading)
{ {
if (!mCreated) return;
// Tell OIS to handle all input events // Tell OIS to handle all input events
mKeyboard->capture(); mKeyboard->capture();
mMouse->capture(); mMouse->capture();

View file

@ -131,6 +131,8 @@ namespace MWInput
std::string mUserFile; std::string mUserFile;
bool mCreated;
bool mDragDrop; bool mDragDrop;
bool mInvertY; bool mInvertY;
@ -148,9 +150,15 @@ namespace MWInput
float mMouseX; float mMouseX;
float mMouseY; float mMouseY;
int mMouseWheel; int mMouseWheel;
bool mDebug;
bool mUserFileExists;
std::map<std::string, bool> mControlSwitch; std::map<std::string, bool> mControlSwitch;
public:
virtual void create();
virtual void destroy();
private: private:
void adjustMouseRegion(int width, int height); void adjustMouseRegion(int width, int height);

View file

@ -46,7 +46,8 @@ namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine)
: mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) : mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine),
mRecreateWindowInNextFrame(false)
{ {
// select best shader mode // select best shader mode
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
@ -323,6 +324,22 @@ RenderingManager::moveObjectToCell(
void RenderingManager::update (float duration, bool paused) void RenderingManager::update (float duration, bool paused)
{ {
if (mRecreateWindowInNextFrame)
{
MWBase::Environment::get().getInputManager()->destroy();
OEngine::Render::WindowSettings windowSettings;
windowSettings.fullscreen = Settings::Manager::getBool("fullscreen", "Video");
windowSettings.window_x = Settings::Manager::getInt("resolution x", "Video");
windowSettings.window_y = Settings::Manager::getInt("resolution y", "Video");
windowSettings.vsync = Settings::Manager::getBool("vsync", "Video");
std::string aa = Settings::Manager::getString("antialiasing", "Video");
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
mRendering.recreateWindow("OpenMW", windowSettings);
MWBase::Environment::get().getInputManager()->create();
mRecreateWindowInNextFrame = false;
}
Ogre::Vector3 orig, dest; Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance(); mPlayer->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) { if (!mPlayer->getPosition(orig, dest)) {
@ -756,6 +773,7 @@ Compositors* RenderingManager::getCompositors()
void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings)
{ {
bool changeRes = false; bool changeRes = false;
bool recreateWindow = false;
bool rebuild = false; // rebuild static geometry (necessary after any material changes) bool rebuild = false; // rebuild static geometry (necessary after any material changes)
for (Settings::CategorySettingVector::const_iterator it=settings.begin(); for (Settings::CategorySettingVector::const_iterator it=settings.begin();
it != settings.end(); ++it) it != settings.end(); ++it)
@ -774,6 +792,8 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
|| it->second == "resolution y" || it->second == "resolution y"
|| it->second == "fullscreen")) || it->second == "fullscreen"))
changeRes = true; changeRes = true;
else if (it->first == "Video" && it->second == "vsync")
recreateWindow = true;
else if (it->second == "field of view" && it->first == "General") else if (it->second == "field of view" && it->first == "General")
mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); mRendering.setFov(Settings::Manager::getFloat("field of view", "General"));
else if ((it->second == "texture filtering" && it->first == "General") else if ((it->second == "texture filtering" && it->first == "General")
@ -845,6 +865,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y);
} }
if (recreateWindow)
{
mRecreateWindowInNextFrame = true;
// We can not do this now, because this might get triggered from the input listener
// and destroying/recreating the input system at that point would cause a crash
}
if (mWater) if (mWater)
mWater->processChangedSettings(settings); mWater->processChangedSettings(settings);

View file

@ -260,6 +260,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
MWRender::Compositors* mCompositors; MWRender::Compositors* mCompositors;
VideoPlayer* mVideoPlayer; VideoPlayer* mVideoPlayer;
bool mRecreateWindowInNextFrame;
}; };
} }

View file

@ -205,13 +205,31 @@ void OgreRenderer::configure(const std::string &logPath,
rs->setConfigOption ("RTT Preferred Mode", rttMode); rs->setConfigOption ("RTT Preferred Mode", rttMode);
} }
void OgreRenderer::recreateWindow(const std::string &title, const WindowSettings &settings)
{
Ogre::ColourValue viewportBG = mView->getBackgroundColour();
mRoot->destroyRenderTarget(mWindow);
NameValuePairList params;
params.insert(std::make_pair("title", title));
params.insert(std::make_pair("FSAA", settings.fsaa));
params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false"));
mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, &params);
// Create one viewport, entire window
mView = mWindow->addViewport(mCamera);
mView->setBackgroundColour(viewportBG);
adjustViewport();
}
void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings) void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings)
{ {
assert(mRoot); assert(mRoot);
mRoot->initialise(false); mRoot->initialise(false);
// create a hidden 1x1 background window to keep resources when recreating the secondary (real) window // create a hidden 1x1 background window to keep resources when recreating the secondary (real) window
/*
NameValuePairList params_; NameValuePairList params_;
params_.insert(std::make_pair("title", title)); params_.insert(std::make_pair("title", title));
params_.insert(std::make_pair("FSAA", "0")); params_.insert(std::make_pair("FSAA", "0"));
@ -219,7 +237,6 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings&
params_.insert(std::make_pair("hidden", "true")); params_.insert(std::make_pair("hidden", "true"));
Ogre::RenderWindow* hiddenWindow = mRoot->createRenderWindow("InactiveHidden", 1, 1, false, &params_); Ogre::RenderWindow* hiddenWindow = mRoot->createRenderWindow("InactiveHidden", 1, 1, false, &params_);
hiddenWindow->setActive(false); hiddenWindow->setActive(false);
*/
NameValuePairList params; NameValuePairList params;
params.insert(std::make_pair("title", title)); params.insert(std::make_pair("title", title));
@ -271,12 +288,12 @@ void OgreRenderer::adjustViewport()
void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener) void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener)
{ {
Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener); //Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener);
} }
void OgreRenderer::removeWindowEventListener(Ogre::WindowEventListener* listener) void OgreRenderer::removeWindowEventListener(Ogre::WindowEventListener* listener)
{ {
Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener); //Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener);
} }
void OgreRenderer::setFov(float fov) void OgreRenderer::setFov(float fov)

View file

@ -66,6 +66,7 @@ namespace OEngine
#endif #endif
class Fader; class Fader;
class OgreRenderer class OgreRenderer
{ {
#if defined(__APPLE__) && !defined(__LP64__) #if defined(__APPLE__) && !defined(__LP64__)
@ -138,6 +139,8 @@ namespace OEngine
/// Create a window with the given title /// Create a window with the given title
void createWindow(const std::string &title, const WindowSettings& settings); void createWindow(const std::string &title, const WindowSettings& settings);
void recreateWindow (const std::string &title, const WindowSettings& settings);
/// Set up the scene manager, camera and viewport /// Set up the scene manager, camera and viewport
void createScene(const std::string& camName="Camera",// Camera name void createScene(const std::string& camName="Camera",// Camera name
float fov=55, // Field of view angle float fov=55, // Field of view angle