Browse Source

Add monitor and refresh rate options for fullscreen/borderless

PredatorMF 8 years ago
parent
commit
07b9675dfd

+ 2 - 2
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -1840,7 +1840,7 @@ static void RegisterTerrain(asIScriptEngine* engine)
 
 
 static CScriptArray* GraphicsGetResolutions(Graphics* ptr)
 static CScriptArray* GraphicsGetResolutions(Graphics* ptr)
 {
 {
-    return VectorToArray<IntVector2>(ptr->GetResolutions(), "Array<IntVector2>");
+    return VectorToArray<IntVector3>(ptr->GetResolutions(), "Array<IntVector3>");
 }
 }
 
 
 static CScriptArray* GraphicsGetMultiSampleLevels(Graphics* ptr)
 static CScriptArray* GraphicsGetMultiSampleLevels(Graphics* ptr)
@@ -1867,7 +1867,7 @@ static Graphics* GetGraphics()
 static void RegisterGraphics(asIScriptEngine* engine)
 static void RegisterGraphics(asIScriptEngine* engine)
 {
 {
     RegisterObject<Graphics>(engine, "Graphics");
     RegisterObject<Graphics>(engine, "Graphics");
-    engine->RegisterObjectMethod("Graphics", "bool SetMode(int, int, bool, bool, bool, bool, bool, bool, int)", asMETHODPR(Graphics, SetMode, (int, int, bool, bool, bool, bool, bool, bool, int), bool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Graphics", "bool SetMode(int, int, bool, bool, bool, bool, bool, bool, int, int, int)", asMETHODPR(Graphics, SetMode, (int, int, bool, bool, bool, bool, bool, bool, int, int, int), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool SetMode(int, int)", asMETHODPR(Graphics, SetMode, (int, int), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool SetMode(int, int)", asMETHODPR(Graphics, SetMode, (int, int), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "void SetWindowPosition(int, int)", asMETHODPR(Graphics, SetWindowPosition, (int, int), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "void SetWindowPosition(int, int)", asMETHODPR(Graphics, SetWindowPosition, (int, int), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool ToggleFullscreen()", asMETHOD(Graphics, ToggleFullscreen), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool ToggleFullscreen()", asMETHOD(Graphics, ToggleFullscreen), asCALL_THISCALL);

+ 11 - 1
Source/Urho3D/Engine/Engine.cpp

@@ -248,7 +248,9 @@ bool Engine::Initialize(const VariantMap& parameters)
             GetParameter(parameters, EP_HIGH_DPI, true).GetBool(),
             GetParameter(parameters, EP_HIGH_DPI, true).GetBool(),
             GetParameter(parameters, EP_VSYNC, false).GetBool(),
             GetParameter(parameters, EP_VSYNC, false).GetBool(),
             GetParameter(parameters, EP_TRIPLE_BUFFER, false).GetBool(),
             GetParameter(parameters, EP_TRIPLE_BUFFER, false).GetBool(),
-            GetParameter(parameters, EP_MULTI_SAMPLE, 1).GetInt()
+            GetParameter(parameters, EP_MULTI_SAMPLE, 1).GetInt(),
+            GetParameter(parameters, EP_MONITOR, 0).GetInt(),
+            GetParameter(parameters, EP_REFRESH_RATE, 0).GetInt()
         ))
         ))
             return false;
             return false;
 
 
@@ -865,6 +867,14 @@ VariantMap Engine::ParseParameters(const Vector<String>& arguments)
                 ret[EP_WINDOW_HEIGHT] = ToInt(value);
                 ret[EP_WINDOW_HEIGHT] = ToInt(value);
                 ++i;
                 ++i;
             }
             }
+            else if (argument == "monitor" && !value.Empty()) {
+                ret[EP_MONITOR] = ToInt(value);
+                ++i;
+            }
+            else if (argument == "hz" && !value.Empty()) {
+                ret[EP_REFRESH_RATE] = ToInt(value);
+                ++i;
+            }
             else if (argument == "m" && !value.Empty())
             else if (argument == "m" && !value.Empty())
             {
             {
                 ret[EP_MULTI_SAMPLE] = ToInt(value);
                 ret[EP_MULTI_SAMPLE] = ToInt(value);

+ 2 - 0
Source/Urho3D/Engine/EngineDefs.h

@@ -42,10 +42,12 @@ static const String EP_LOG_NAME = "LogName";
 static const String EP_LOG_QUIET = "LogQuiet";
 static const String EP_LOG_QUIET = "LogQuiet";
 static const String EP_LOW_QUALITY_SHADOWS = "LowQualityShadows";
 static const String EP_LOW_QUALITY_SHADOWS = "LowQualityShadows";
 static const String EP_MATERIAL_QUALITY = "MaterialQuality";
 static const String EP_MATERIAL_QUALITY = "MaterialQuality";
+static const String EP_MONITOR = "Monitor";
 static const String EP_MULTI_SAMPLE = "MultiSample";
 static const String EP_MULTI_SAMPLE = "MultiSample";
 static const String EP_ORIENTATIONS = "Orientations";
 static const String EP_ORIENTATIONS = "Orientations";
 static const String EP_PACKAGE_CACHE_DIR = "PackageCacheDir";
 static const String EP_PACKAGE_CACHE_DIR = "PackageCacheDir";
 static const String EP_RENDER_PATH = "RenderPath";
 static const String EP_RENDER_PATH = "RenderPath";
+static const String EP_REFRESH_RATE = "RefreshRate";
 static const String EP_RESOURCE_PACKAGES = "ResourcePackages";
 static const String EP_RESOURCE_PACKAGES = "ResourcePackages";
 static const String EP_RESOURCE_PATHS = "ResourcePaths";
 static const String EP_RESOURCE_PATHS = "ResourcePaths";
 static const String EP_RESOURCE_PREFIX_PATHS = "ResourcePrefixPaths";
 static const String EP_RESOURCE_PREFIX_PATHS = "ResourcePrefixPaths";

+ 28 - 9
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -264,6 +264,8 @@ Graphics::Graphics(Context* context) :
     resizable_(false),
     resizable_(false),
     highDPI_(false),
     highDPI_(false),
     vsync_(false),
     vsync_(false),
+    monitor_(0),
+    refreshRate_(0),
     tripleBuffer_(false),
     tripleBuffer_(false),
     flushGPU_(false),
     flushGPU_(false),
     sRGB_(false),
     sRGB_(false),
@@ -328,7 +330,7 @@ Graphics::~Graphics()
 }
 }
 
 
 bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync,
 bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync,
-    bool tripleBuffer, int multiSample)
+    bool tripleBuffer, int multiSample, int monitor, int refreshRate)
 {
 {
     URHO3D_PROFILE(SetScreenMode);
     URHO3D_PROFILE(SetScreenMode);
 
 
@@ -336,9 +338,14 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
 
     bool maximize = false;
     bool maximize = false;
 
 
+    // make sure monitor index is not bigger than the currently detected monitors
+    int monitors = SDL_GetNumVideoDisplays();
+    if (monitor >= monitors)
+        monitor = 0; // this monitor is not present, use first monitor
+
     // Find out the full screen mode display format (match desktop color depth)
     // Find out the full screen mode display format (match desktop color depth)
     SDL_DisplayMode mode;
     SDL_DisplayMode mode;
-    SDL_GetDesktopDisplayMode(0, &mode);
+    SDL_GetDesktopDisplayMode(monitor, &mode);
     D3DFORMAT fullscreenFormat = SDL_BITSPERPIXEL(mode.format) == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
     D3DFORMAT fullscreenFormat = SDL_BITSPERPIXEL(mode.format) == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
 
 
     // If zero dimensions in windowed mode, set windowed mode to maximize and set a predefined default restored window size. If zero in fullscreen, use desktop mode
     // If zero dimensions in windowed mode, set windowed mode to maximize and set a predefined default restored window size. If zero in fullscreen, use desktop mode
@@ -394,7 +401,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     // Check fullscreen mode validity. Use a closest match if not found
     // Check fullscreen mode validity. Use a closest match if not found
     if (fullscreen)
     if (fullscreen)
     {
     {
-        PODVector<IntVector2> resolutions = GetResolutions();
+        PODVector<IntVector3> resolutions = GetResolutions(monitor);
         if (resolutions.Size())
         if (resolutions.Size())
         {
         {
             unsigned best = 0;
             unsigned best = 0;
@@ -412,6 +419,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
 
             width = resolutions[best].x_;
             width = resolutions[best].x_;
             height = resolutions[best].y_;
             height = resolutions[best].y_;
+            refreshRate = resolutions[best].z_;
         }
         }
     }
     }
 
 
@@ -422,7 +430,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
             multiSample = 1;
             multiSample = 1;
     }
     }
 
 
-    AdjustWindow(width, height, fullscreen, borderless);
+    AdjustWindow(width, height, fullscreen, borderless, monitor);
 
 
     if (maximize)
     if (maximize)
     {
     {
@@ -451,7 +459,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     impl_->presentParams_.EnableAutoDepthStencil = TRUE;
     impl_->presentParams_.EnableAutoDepthStencil = TRUE;
     impl_->presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
     impl_->presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
     impl_->presentParams_.Flags = D3DPRESENT_LINEAR_CONTENT;
     impl_->presentParams_.Flags = D3DPRESENT_LINEAR_CONTENT;
-    impl_->presentParams_.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
+    impl_->presentParams_.FullScreen_RefreshRateInHz = fullscreen ? refreshRate : D3DPRESENT_RATE_DEFAULT;
 
 
     if (vsync)
     if (vsync)
         impl_->presentParams_.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
         impl_->presentParams_.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
@@ -466,10 +474,12 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     highDPI_ = highDPI;
     highDPI_ = highDPI;
     vsync_ = vsync;
     vsync_ = vsync;
     tripleBuffer_ = tripleBuffer;
     tripleBuffer_ = tripleBuffer;
+    monitor_ = monitor;
+    refreshRate_ = refreshRate;
 
 
     if (!impl_->device_)
     if (!impl_->device_)
     {
     {
-        unsigned adapter = D3DADAPTER_DEFAULT;
+        unsigned adapter = monitor;
         unsigned deviceType = D3DDEVTYPE_HAL;
         unsigned deviceType = D3DDEVTYPE_HAL;
 
 
         // Check for PerfHUD adapter
         // Check for PerfHUD adapter
@@ -526,7 +536,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
 
 bool Graphics::SetMode(int width, int height)
 bool Graphics::SetMode(int width, int height)
 {
 {
-    return SetMode(width, height, fullscreen_, borderless_, resizable_, highDPI_, vsync_, tripleBuffer_, multiSample_);
+    return SetMode(width, height, fullscreen_, borderless_, resizable_, highDPI_, vsync_, tripleBuffer_, multiSample_, monitor_, refreshRate_);
 }
 }
 
 
 void Graphics::SetSRGB(bool enable)
 void Graphics::SetSRGB(bool enable)
@@ -2330,7 +2340,7 @@ bool Graphics::OpenWindow(int width, int height, bool resizable, bool borderless
     return true;
     return true;
 }
 }
 
 
-void Graphics::AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless)
+void Graphics::AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless, int& monitor)
 {
 {
     if (!externalWindow_)
     if (!externalWindow_)
     {
     {
@@ -2339,8 +2349,17 @@ void Graphics::AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen,
             SDL_MaximizeWindow(window_);
             SDL_MaximizeWindow(window_);
             SDL_GetWindowSize(window_, &newWidth, &newHeight);
             SDL_GetWindowSize(window_, &newWidth, &newHeight);
         }
         }
-        else
+        else {
+            if (newFullscreen || newBorderless) 
+            {
+                // reposition the window on the specified monitor
+                SDL_Rect display_rect;
+                SDL_GetDisplayBounds(monitor, &display_rect);
+                SDL_SetWindowPosition(window_, display_rect.x, display_rect.y);
+            }
+
             SDL_SetWindowSize(window_, newWidth, newHeight);
             SDL_SetWindowSize(window_, newWidth, newHeight);
+        }
 
 
         // Hack fix: on SDL 2.0.4 a fullscreen->windowed transition results in a maximized window when the D3D device is reset, so hide before
         // Hack fix: on SDL 2.0.4 a fullscreen->windowed transition results in a maximized window when the D3D device is reset, so hide before
         SDL_HideWindow(window_);
         SDL_HideWindow(window_);

+ 6 - 5
Source/Urho3D/Graphics/Graphics.cpp

@@ -103,7 +103,7 @@ void Graphics::SetOrientations(const String& orientations)
 
 
 bool Graphics::ToggleFullscreen()
 bool Graphics::ToggleFullscreen()
 {
 {
-    return SetMode(width_, height_, !fullscreen_, borderless_, resizable_, highDPI_, vsync_, tripleBuffer_, multiSample_);
+    return SetMode(width_, height_, !fullscreen_, borderless_, resizable_, highDPI_, vsync_, tripleBuffer_, multiSample_, monitor_, refreshRate_);
 }
 }
 
 
 void Graphics::SetShaderParameter(StringHash param, const Variant& value)
 void Graphics::SetShaderParameter(StringHash param, const Variant& value)
@@ -172,9 +172,9 @@ IntVector2 Graphics::GetWindowPosition() const
     return IntVector2::ZERO;
     return IntVector2::ZERO;
 }
 }
 
 
-PODVector<IntVector2> Graphics::GetResolutions() const
+PODVector<IntVector3> Graphics::GetResolutions(int monitor) const
 {
 {
-    PODVector<IntVector2> ret;
+    PODVector<IntVector3> ret;
     // Emscripten is not able to return a valid list
     // Emscripten is not able to return a valid list
 #ifndef __EMSCRIPTEN__
 #ifndef __EMSCRIPTEN__
     unsigned numModes = (unsigned)SDL_GetNumDisplayModes(0);
     unsigned numModes = (unsigned)SDL_GetNumDisplayModes(0);
@@ -185,12 +185,13 @@ PODVector<IntVector2> Graphics::GetResolutions() const
         SDL_GetDisplayMode(0, i, &mode);
         SDL_GetDisplayMode(0, i, &mode);
         int width = mode.w;
         int width = mode.w;
         int height = mode.h;
         int height = mode.h;
+        int rate = mode.refresh_rate;
 
 
         // Store mode if unique
         // Store mode if unique
         bool unique = true;
         bool unique = true;
         for (unsigned j = 0; j < ret.Size(); ++j)
         for (unsigned j = 0; j < ret.Size(); ++j)
         {
         {
-            if (ret[j].x_ == width && ret[j].y_ == height)
+            if (ret[j].x_ == width && ret[j].y_ == height && ret[j].z_ == rate)
             {
             {
                 unique = false;
                 unique = false;
                 break;
                 break;
@@ -198,7 +199,7 @@ PODVector<IntVector2> Graphics::GetResolutions() const
         }
         }
 
 
         if (unique)
         if (unique)
-            ret.Push(IntVector2(width, height));
+            ret.Push(IntVector3(width, height, rate));
     }
     }
 #endif
 #endif
 
 

+ 14 - 4
Source/Urho3D/Graphics/Graphics.h

@@ -101,7 +101,7 @@ public:
     /// Set screen mode. Return true if successful.
     /// Set screen mode. Return true if successful.
     bool SetMode
     bool SetMode
         (int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer,
         (int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer,
-            int multiSample);
+            int multiSample, int monitor, int refreshRate);
     /// Set screen resolution only. Return true if successful.
     /// Set screen resolution only. Return true if successful.
     bool SetMode(int width, int height);
     bool SetMode(int width, int height);
     /// Set whether the main window uses sRGB conversion on write.
     /// Set whether the main window uses sRGB conversion on write.
@@ -300,6 +300,12 @@ public:
     /// Return whether vertical sync is on.
     /// Return whether vertical sync is on.
     bool GetVSync() const { return vsync_; }
     bool GetVSync() const { return vsync_; }
 
 
+    /// Return refresh rate when using vsync in fullscreen
+    int GetRefreshRate() const { return refreshRate_; }
+
+    /// Return the current monitor index. Effective on in fullscreen
+    int GetMonitor() const { return monitor_; }
+
     /// Return whether triple buffering is enabled.
     /// Return whether triple buffering is enabled.
     bool GetTripleBuffer() const { return tripleBuffer_; }
     bool GetTripleBuffer() const { return tripleBuffer_; }
 
 
@@ -360,8 +366,8 @@ public:
     /// Return whether sRGB conversion on rendertarget writing is supported.
     /// Return whether sRGB conversion on rendertarget writing is supported.
     bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
     bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
 
 
-    /// Return supported fullscreen resolutions. Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
-    PODVector<IntVector2> GetResolutions() const;
+    /// Return supported fullscreen resolutions (third component is refreshRate). Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
+    PODVector<IntVector3> GetResolutions(int monitor = 0) const;
     /// Return supported multisampling levels.
     /// Return supported multisampling levels.
     PODVector<int> GetMultiSampleLevels() const;
     PODVector<int> GetMultiSampleLevels() const;
     /// Return the desktop resolution.
     /// Return the desktop resolution.
@@ -560,7 +566,7 @@ private:
     /// Create the application window icon.
     /// Create the application window icon.
     void CreateWindowIcon();
     void CreateWindowIcon();
     /// Adjust the window for new resolution and fullscreen mode.
     /// Adjust the window for new resolution and fullscreen mode.
-    void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless);
+    void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless, int& monitor);
     /// Create the Direct3D11 device and swap chain. Requires an open window. Can also be called again to recreate swap chain. Return true on success.
     /// Create the Direct3D11 device and swap chain. Requires an open window. Can also be called again to recreate swap chain. Return true on success.
     bool CreateDevice(int width, int height, int multiSample);
     bool CreateDevice(int width, int height, int multiSample);
     /// Update Direct3D11 swap chain state for a new mode and create views for the backbuffer & default depth buffer. Return true on success.
     /// Update Direct3D11 swap chain state for a new mode and create views for the backbuffer & default depth buffer. Return true on success.
@@ -640,6 +646,10 @@ private:
     bool highDPI_;
     bool highDPI_;
     /// Vertical sync flag.
     /// Vertical sync flag.
     bool vsync_;
     bool vsync_;
+    /// Refresh rate in Hz. Only used in fullscreen, 0 when windowed
+    int refreshRate_;
+    /// Monitor index. Only used in fullscreen, 0 when windowed
+    int monitor_;
     /// Triple buffering flag.
     /// Triple buffering flag.
     bool tripleBuffer_;
     bool tripleBuffer_;
     /// Flush GPU command buffer flag.
     /// Flush GPU command buffer flag.

+ 5 - 1
Source/Urho3D/LuaScript/pkgs/Graphics/Graphics.pkg

@@ -8,7 +8,7 @@ class Graphics : public Object
     void SetWindowPosition(const IntVector2& position);
     void SetWindowPosition(const IntVector2& position);
     void SetWindowPosition(int x, int y);
     void SetWindowPosition(int x, int y);
 
 
-    bool SetMode(int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer, int multiSample);
+    bool SetMode(int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer, int multiSample, int monitor, int refreshRate);
     bool SetMode(int width, int height);
     bool SetMode(int width, int height);
 
 
     void SetSRGB(bool enable);
     void SetSRGB(bool enable);
@@ -39,6 +39,8 @@ class Graphics : public Object
     bool GetResizable() const;
     bool GetResizable() const;
     bool GetBorderless() const;
     bool GetBorderless() const;
     bool GetVSync() const;
     bool GetVSync() const;
+    int GetMonitor() const;
+    int GetRefreshRate() const;
     bool GetTripleBuffer() const;
     bool GetTripleBuffer() const;
     bool GetSRGB() const;
     bool GetSRGB() const;
     bool GetDither() const;
     bool GetDither() const;
@@ -91,6 +93,8 @@ class Graphics : public Object
     tolua_readonly tolua_property__get_set bool resizable;
     tolua_readonly tolua_property__get_set bool resizable;
     tolua_readonly tolua_property__get_set bool borderless;
     tolua_readonly tolua_property__get_set bool borderless;
     tolua_readonly tolua_property__get_set bool vSync;
     tolua_readonly tolua_property__get_set bool vSync;
+    tolua_readonly tolua_property__get_set int refreshRate;
+    tolua_readonly tolua_property__get_set int monitor;
     tolua_readonly tolua_property__get_set bool tripleBuffer;
     tolua_readonly tolua_property__get_set bool tripleBuffer;
     tolua_property__get_set bool sRGB;
     tolua_property__get_set bool sRGB;
     tolua_property__get_set bool dither;
     tolua_property__get_set bool dither;