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)
 {
-    return VectorToArray<IntVector2>(ptr->GetResolutions(), "Array<IntVector2>");
+    return VectorToArray<IntVector3>(ptr->GetResolutions(), "Array<IntVector3>");
 }
 
 static CScriptArray* GraphicsGetMultiSampleLevels(Graphics* ptr)
@@ -1867,7 +1867,7 @@ static Graphics* GetGraphics()
 static void RegisterGraphics(asIScriptEngine* engine)
 {
     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", "void SetWindowPosition(int, int)", asMETHODPR(Graphics, SetWindowPosition, (int, int), void), 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_VSYNC, 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;
 
@@ -865,6 +867,14 @@ VariantMap Engine::ParseParameters(const Vector<String>& arguments)
                 ret[EP_WINDOW_HEIGHT] = ToInt(value);
                 ++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())
             {
                 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_LOW_QUALITY_SHADOWS = "LowQualityShadows";
 static const String EP_MATERIAL_QUALITY = "MaterialQuality";
+static const String EP_MONITOR = "Monitor";
 static const String EP_MULTI_SAMPLE = "MultiSample";
 static const String EP_ORIENTATIONS = "Orientations";
 static const String EP_PACKAGE_CACHE_DIR = "PackageCacheDir";
 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_PATHS = "ResourcePaths";
 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),
     highDPI_(false),
     vsync_(false),
+    monitor_(0),
+    refreshRate_(0),
     tripleBuffer_(false),
     flushGPU_(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 tripleBuffer, int multiSample)
+    bool tripleBuffer, int multiSample, int monitor, int refreshRate)
 {
     URHO3D_PROFILE(SetScreenMode);
 
@@ -336,9 +338,14 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
     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)
     SDL_DisplayMode mode;
-    SDL_GetDesktopDisplayMode(0, &mode);
+    SDL_GetDesktopDisplayMode(monitor, &mode);
     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
@@ -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
     if (fullscreen)
     {
-        PODVector<IntVector2> resolutions = GetResolutions();
+        PODVector<IntVector3> resolutions = GetResolutions(monitor);
         if (resolutions.Size())
         {
             unsigned best = 0;
@@ -412,6 +419,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
             width = resolutions[best].x_;
             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;
     }
 
-    AdjustWindow(width, height, fullscreen, borderless);
+    AdjustWindow(width, height, fullscreen, borderless, monitor);
 
     if (maximize)
     {
@@ -451,7 +459,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     impl_->presentParams_.EnableAutoDepthStencil = TRUE;
     impl_->presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
     impl_->presentParams_.Flags = D3DPRESENT_LINEAR_CONTENT;
-    impl_->presentParams_.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
+    impl_->presentParams_.FullScreen_RefreshRateInHz = fullscreen ? refreshRate : D3DPRESENT_RATE_DEFAULT;
 
     if (vsync)
         impl_->presentParams_.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
@@ -466,10 +474,12 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     highDPI_ = highDPI;
     vsync_ = vsync;
     tripleBuffer_ = tripleBuffer;
+    monitor_ = monitor;
+    refreshRate_ = refreshRate;
 
     if (!impl_->device_)
     {
-        unsigned adapter = D3DADAPTER_DEFAULT;
+        unsigned adapter = monitor;
         unsigned deviceType = D3DDEVTYPE_HAL;
 
         // 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)
 {
-    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)
@@ -2330,7 +2340,7 @@ bool Graphics::OpenWindow(int width, int height, bool resizable, bool borderless
     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_)
     {
@@ -2339,8 +2349,17 @@ void Graphics::AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen,
             SDL_MaximizeWindow(window_);
             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);
+        }
 
         // 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_);

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

@@ -103,7 +103,7 @@ void Graphics::SetOrientations(const String& orientations)
 
 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)
@@ -172,9 +172,9 @@ IntVector2 Graphics::GetWindowPosition() const
     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
 #ifndef __EMSCRIPTEN__
     unsigned numModes = (unsigned)SDL_GetNumDisplayModes(0);
@@ -185,12 +185,13 @@ PODVector<IntVector2> Graphics::GetResolutions() const
         SDL_GetDisplayMode(0, i, &mode);
         int width = mode.w;
         int height = mode.h;
+        int rate = mode.refresh_rate;
 
         // Store mode if unique
         bool unique = true;
         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;
                 break;
@@ -198,7 +199,7 @@ PODVector<IntVector2> Graphics::GetResolutions() const
         }
 
         if (unique)
-            ret.Push(IntVector2(width, height));
+            ret.Push(IntVector3(width, height, rate));
     }
 #endif
 

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

@@ -101,7 +101,7 @@ public:
     /// Set screen mode. Return true if successful.
     bool SetMode
         (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.
     bool SetMode(int width, int height);
     /// Set whether the main window uses sRGB conversion on write.
@@ -300,6 +300,12 @@ public:
     /// Return whether vertical sync is on.
     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.
     bool GetTripleBuffer() const { return tripleBuffer_; }
 
@@ -360,8 +366,8 @@ public:
     /// Return whether sRGB conversion on rendertarget writing is supported.
     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.
     PODVector<int> GetMultiSampleLevels() const;
     /// Return the desktop resolution.
@@ -560,7 +566,7 @@ private:
     /// Create the application window icon.
     void CreateWindowIcon();
     /// 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.
     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.
@@ -640,6 +646,10 @@ private:
     bool highDPI_;
     /// Vertical sync flag.
     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.
     bool tripleBuffer_;
     /// 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(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);
 
     void SetSRGB(bool enable);
@@ -39,6 +39,8 @@ class Graphics : public Object
     bool GetResizable() const;
     bool GetBorderless() const;
     bool GetVSync() const;
+    int GetMonitor() const;
+    int GetRefreshRate() const;
     bool GetTripleBuffer() const;
     bool GetSRGB() 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 borderless;
     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_property__get_set bool sRGB;
     tolua_property__get_set bool dither;