New feature: Hidden RenderWindows

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

As the comment for setVSyncInterval states, it says how many vertical retraces to wait for before switching buffers. So, with an interval of 1 your frame rate is limited to the refresh rate of your monitor. With an interval of 2, it's limited to half your monitor's refresh rate, etc.
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

Cabalistic: Where did you add these setVsyncEnabled etc calls? I looked in RenderWindow and RenderSystem? It sounds like you have in fact implemented a way to switch vsync on/off without recreating the window? That would be awesome!
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

They are in RenderWindow, just like the setHidden function. And yes, they allow switching vsync on/off without recreating the window.
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

Just tried it out in GL, works like a dream. Except when I set vsync interval to anything other than 1 or 0 it is set to 1. I assume my hardware does not support this. (NVIDIA 3700M, like an 8800 but a quadro).

What about D3D9? I had a look and it looks like you haven't implemented that, which makes sense because we don't know how yet :)

Still, this is a great start, I'll see if I can find someone who knows about D3D9 vsync switching...
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

No, D3D9 is implemented. Was quite easy, actually. All I needed was to tell Ogre that the renderwindow should be considered invalid, at which point Ogre would automatically reset the D3D9 device and at that point adopt the new vsync settings.
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

But setVSyncEnabled and friends are not implemented in D3D9RenderWindow, they always return false and setting them does nothing.
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

? Yes, they are implemented, and yes, I've properly committed it. Maybe you need to update again :)
http://bitbucket.org/sinbad/ogre/changeset/90f4a002251d
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

This is weird, I can see your change:

Code: Select all

spark@expensive:~/ogre$ hg log -r 2313
changeset:   2313:90f4a002251d
user:        Holger Frydrych <h.frydrych@gmx.de>
date:        Wed Aug 25 10:32:33 2010 +0200
summary:     Implement vsync adjustment for Win32 GL and D3D9 rendersystems.

spark@expensive:~/ogre$ hg diff -c 2313
diff -r d2a9c4566477 -r 90f4a002251d RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h
--- a/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h    Wed Aug 25 10:01:32 2010 +0200
+++ b/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h    Wed Aug 25 10:32:33 2010 +0200
@@ -57,6 +57,10 @@
                bool                            isVSync                         () const { return mVSync; }
                bool                            isHidden                        () const { return mHidden; }
                void                            setHidden                       (bool hidden);
+               void                            setVSyncEnabled         (bool vsync);
+               bool                            isVSyncEnabled          () const;
+               void                            setVSyncInterval        (unsigned int interval);
+               unsigned int            getVSyncInterval        () const;
                void                            reposition                      (int left, int top);
                void                            resize                          (unsigned int width, unsigned int height);
                void                            swapBuffers                     ( bool waitForVSync = true );
diff -r d2a9c4566477 -r 90f4a002251d RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp
--- a/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp      Wed Aug 25 10:01:32 2010 +0200
+++ b/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp      Wed Aug 25 10:32:33 2010 +0200
@@ -693,6 +693,34 @@
                }
        }
 
+       void D3D9RenderWindow::setVSyncEnabled(bool vsync)
+       {
+               mVSync = vsync;
+               if (!mIsExternal)
+               {
+                       // we need to reset the device with new vsync params
+                       // invalidate the window to trigger this
+                       mDevice->invalidate(this);
+               }
+       }
+
+       bool D3D9RenderWindow::isVSyncEnabled() const
+       {
+               return mVSync;
+       }
+
+       void D3D9RenderWindow::setVSyncInterval(unsigned int interval)
+       {
+               mVSyncInterval = interval;
+               if (mVSync)
+                       setVSyncEnabled(true);
+       }
+
+       unsigned int D3D9RenderWindow::getVSyncInterval() const
+       {
+               return mVSyncInterval;
+       }
+
        void D3D9RenderWindow::reposition(int top, int left)
        {
                if (mHWnd && !mIsFullScreen)
diff -r d2a9c4566477 -r 90f4a002251d RenderSystems/GL/include/OgreWin32Window.h
--- a/RenderSystems/GL/include/OgreWin32Window.h        Wed Aug 25 10:01:32 2010 +0200
+++ b/RenderSystems/GL/include/OgreWin32Window.h        Wed Aug 25 10:32:33 2010 +0200
@@ -47,6 +47,10 @@
         bool isVisible() const;
                bool isHidden() const { return mHidden; }
                void setHidden(bool hidden);
+               void setVSyncEnabled(bool vsync);
+               bool isVSyncEnabled() const;
+               void setVSyncInterval(unsigned int interval);
+               unsigned int getVSyncInterval() const;
         bool isClosed(void) const;
         void reposition(int left, int top);
         void resize(unsigned int width, unsigned int height);
@@ -92,6 +96,8 @@
         bool    mSizing;
                bool    mClosed;
                bool    mHidden;
+               bool    mVSync;
+               unsigned int mVSyncInterval;
         int     mDisplayFrequency;      // fullscreen only, to restore display
         Win32Context *mContext;
                DWORD   mWindowedWinStyle;              // Windowed mode window style flags.
diff -r d2a9c4566477 -r 90f4a002251d RenderSystems/GL/src/OgreWin32Window.cpp
--- a/RenderSystems/GL/src/OgreWin32Window.cpp  Wed Aug 25 10:01:32 2010 +0200
+++ b/RenderSystems/GL/src/OgreWin32Window.cpp  Wed Aug 25 10:32:33 2010 +0200
@@ -59,6 +59,8 @@
                mSizing = false;
                mClosed = false;
                mHidden = false;
+               mVSync = false;
+               mVSyncInterval = 1;
                mDisplayFrequency = 0;
                mActive = false;
                mDeviceName = NULL;
@@ -99,9 +101,7 @@
                int top = -1; // Defaults to screen center
                HWND parent = 0;
                String title = name;
-               bool vsync = false;
                bool hidden = false;
-               unsigned int vsyncInterval = 1;
                String border;
                bool outerSize = false;
                bool hwGamma = false;
@@ -130,13 +130,13 @@
                        }
 
                        if ((opt = miscParams->find("vsync")) != end)
-                               vsync = StringConverter::parseBool(opt->second);
+                               mVSync = StringConverter::parseBool(opt->second);
 
                        if ((opt = miscParams->find("hidden")) != end)
                                hidden = StringConverter::parseBool(opt->second);
 
                        if ((opt = miscParams->find("vsyncInterval")) != end)
-                               vsyncInterval = StringConverter::parseUnsignedInt(opt->second);
+                               mVSyncInterval = StringConverter::parseUnsignedInt(opt->second);
 
                        if ((opt = miscParams->find("FSAA")) != end)
                                mFSAA = StringConverter::parseUnsignedInt(opt->second);
@@ -439,7 +439,7 @@
                        PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = 
                                (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
                        if (_wglSwapIntervalEXT)
-                               _wglSwapIntervalEXT(vsync? vsyncInterval : 0);
+                               _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0);
                }
 
         if (old_context && old_context != mGlrc)
@@ -671,6 +671,48 @@
                }
        }
 
+       void Win32Window::setVSyncEnabled(bool vsync)
+       {
+               mVSync = vsync;
+               HDC old_hdc = wglGetCurrentDC();
+               HGLRC old_context = wglGetCurrentContext();
+               if (!wglMakeCurrent(mHDC, mGlrc))
+                       OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::setVSyncEnabled");
+
+               // Do not change vsync if the external window has the OpenGL control
+               if (!mIsExternalGLControl) {
+                       // Don't use wglew as if this is the first window, we won't have initialised yet
+                       PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = 
+                               (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
+                       if (_wglSwapIntervalEXT)
+                               _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0);
+               }
+
+        if (old_context && old_context != mGlrc)
+        {
+            // Restore old context
+                   if (!wglMakeCurrent(old_hdc, old_context))
+                           OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::setVSyncEnabled");
+               }
+       }
+
+       void Win32Window::setVSyncInterval(unsigned int interval)
+       {
+               mVSyncInterval = interval;
+               if (mVSync)
+                       setVSyncEnabled(true);
+       }
+
+       bool Win32Window::isVSyncEnabled() const
+       {
+               return mVSync;
+       }
+
+       unsigned int Win32Window::getVSyncInterval() const
+       {
+               return mVSyncInterval;
+       }
+
        void Win32Window::reposition(int left, int top)
        {
                if (mHWnd && !mIsFullScreen)
spark@expensive:~/ogre$ 
However even though I have pulled the main ogre repository, merged it, and updated (I maintain a fork) there is no evidence of these changes in my working space, and neither is there any revision between now and hten that would have reverted them.

Here is my fork:

http://bitbucket.org/sparkprime/grit_ogre/
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

Your merge commit on hg quotes "Binary file changed" for the D3D9 files. Sounds as if those files somehow got corrupted in your hg repository? Or at least hg thinks them binary, and maybe that's why the merge didn't work quite as expected?
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

Yeah I am still an hg noob so quite possibly I was just doing it wrong. Any idea how I would go back to before that merge and then do it again?
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

Not an hg expert, either. You could probably update those files to a specific revision (before the merge), then do the merge manually and commit. Or if you didn't change them in your fork, just overwrite them entirely.
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

Fixed it: http://bitbucket.org/sparkprime/grit_ogre/changesets

For future generations, the fix is to do what cabalistic said: update to just before the merge (hg update 2288), then remerge in the ogre revision I wanted (hg merge 2313). This time do it *properly*, in fact I added an ~/.hgrc to make it use the old <<<< >>>> svn style of merge conflicts:

Code: Select all

[ui]
merge = internal:merge
After resolving the conflicts by editting the files, I explicitly marked the files as resolved (hg resolve -m file1 file2 ...) and then committed to get a new head. I cherry-picked the change above the broken merge (hg export 2316 | hg import -) and then pushed my new tip. I'll have to wait until I get home to try out D3D9 though as I only use Linux at work.
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

Yep it works flawlessly in D3D9 too... You are my hero :)

This means there's no point in having a hidden renderwindow right?
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

There's still FSAA settings. Also, I could imagine that when a user submits a graphics options dialog, it might be easier to just recreate the window with the current settings rather than manually check each setting for changes and applying those. But that depends on your design :)
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

Is it not possible to change FSAA without recreating the window? I would have thought recreating a buffer and keeping the same window would work just as well?
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: New feature: Hidden RenderWindows

Post by CABAListic »

Probably, but this might be quite a lot harder to implement. I imagine for D3D9 this might also be done with a device reset which would be quite easy to do because the logic for the reset is already built into Ogre (which is why I could implement vsync so easily). Not so sure about GL, though. In the GLX RenderWindow the fsaa setting appears to be passed directly to the context, and I don't think I really want to recreate the context :) Might be there are more direct options, though.
User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
x 13
Contact:

Re: New feature: Hidden RenderWindows

Post by sparkprime »

OK I am more than happy with just vsync working like this. It is very common to want to toggle it while performance tuning at runtime, whereas I think FSAA is just something you will turn on to see how much it costs, rather than turn on/off to facilitate general testing.
Post Reply