Specify monitor when changing display mode
This commit is contained in:
parent
b62024f94c
commit
f65a9e835f
13 changed files with 187 additions and 24 deletions
|
@ -72,6 +72,7 @@ struct IOcclusionQuery;
|
|||
/// A Graphic Mode descriptor.
|
||||
struct GfxMode
|
||||
{
|
||||
std::string DisplayDevice;
|
||||
bool OffScreen;
|
||||
bool Windowed;
|
||||
uint16 Width;
|
||||
|
@ -90,7 +91,7 @@ struct GfxMode
|
|||
Frequency = 0;
|
||||
AntiAlias = -1;
|
||||
}
|
||||
GfxMode(uint16 w, uint16 h, uint8 d, bool windowed = true, bool offscreen = false, uint frequency = 0, sint8 aa = -1);
|
||||
GfxMode(uint16 w, uint16 h, uint8 d, bool windowed = true, bool offscreen = false, uint frequency = 0, sint8 aa = -1, const std::string &displayDevice = std::string());
|
||||
};
|
||||
|
||||
// ****************************************************************************
|
||||
|
|
|
@ -72,6 +72,11 @@ public:
|
|||
void getTextures();
|
||||
void recycleTextures();
|
||||
|
||||
/// Attach the driver to the display
|
||||
virtual void attachToDisplay();
|
||||
/// Detach the driver from the display
|
||||
virtual void detachFromDisplay();
|
||||
|
||||
/// Gets the required screen resolution for this device
|
||||
virtual bool getScreenResolution(uint &width, uint &height);
|
||||
/// Set latest camera position etcetera
|
||||
|
|
|
@ -95,6 +95,11 @@ public:
|
|||
/// Sets driver and generates necessary render targets
|
||||
virtual void setDriver(NL3D::UDriver *driver) = 0;
|
||||
|
||||
/// Attach the driver to the display
|
||||
virtual void attachToDisplay() = 0;
|
||||
/// Detach the driver from the display
|
||||
virtual void detachFromDisplay() = 0;
|
||||
|
||||
/// Gets the required screen resolution for this device
|
||||
virtual bool getScreenResolution(uint &width, uint &height) = 0;
|
||||
/// Set latest camera position etcetera
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include <nel/3d/frustum.h>
|
||||
#include <nel/3d/viewport.h>
|
||||
#include <nel/3d/u_material.h>
|
||||
#include <nel/3d/u_driver.h>
|
||||
#include <nel/3d/index_buffer.h>
|
||||
#include <nel/3d/vertex_buffer.h>
|
||||
|
||||
|
@ -89,6 +90,11 @@ public:
|
|||
/// Sets driver and generates necessary render targets
|
||||
virtual void setDriver(NL3D::UDriver *driver);
|
||||
|
||||
/// Attach the driver to the display
|
||||
virtual void attachToDisplay();
|
||||
/// Detach the driver from the display
|
||||
virtual void detachFromDisplay();
|
||||
|
||||
/// Gets the required screen resolution for this device
|
||||
virtual bool getScreenResolution(uint &width, uint &height);
|
||||
/// Set latest camera position etcetera
|
||||
|
@ -194,6 +200,11 @@ private:
|
|||
|
||||
UMaterial m_UnlitMat;
|
||||
|
||||
UDriver::CMode m_OriginalMode;
|
||||
sint32 m_OriginalWinPosX;
|
||||
sint32 m_OriginalWinPosY;
|
||||
bool m_AttachedDisplay;
|
||||
|
||||
/*
|
||||
NL3D::UMaterial m_BarrelMat;
|
||||
NLMISC::CQuadUV m_BarrelQuadLeft;
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
/// A Graphic Mode descriptor.
|
||||
struct CMode
|
||||
{
|
||||
std::string DisplayDevice;
|
||||
bool Windowed;
|
||||
uint16 Width;
|
||||
uint16 Height;
|
||||
|
@ -108,8 +109,9 @@ public:
|
|||
Frequency = 0;
|
||||
AntiAlias = -1;
|
||||
}
|
||||
CMode(uint16 w, uint16 h, uint8 d, bool windowed= true, uint frequency = 0, sint8 aa = -1)
|
||||
CMode(uint16 w, uint16 h, uint8 d, bool windowed= true, uint frequency = 0, sint8 aa = -1, const std::string &displayDevice = std::string())
|
||||
{
|
||||
DisplayDevice = displayDevice;
|
||||
Windowed = windowed;
|
||||
Width = w;
|
||||
Height = h;
|
||||
|
|
|
@ -123,8 +123,9 @@ bool IDriver::release(void)
|
|||
|
||||
|
||||
// ***************************************************************************
|
||||
GfxMode::GfxMode(uint16 w, uint16 h, uint8 d, bool windowed, bool offscreen, uint frequency, sint8 aa)
|
||||
GfxMode::GfxMode(uint16 w, uint16 h, uint8 d, bool windowed, bool offscreen, uint frequency, sint8 aa, const std::string &displayDevice)
|
||||
{
|
||||
DisplayDevice = displayDevice;
|
||||
Windowed = windowed;
|
||||
Width = w;
|
||||
Height = h;
|
||||
|
|
|
@ -1271,10 +1271,62 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info)
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
#if defined(NL_OS_WINDOWS)
|
||||
|
||||
struct CMonitorEnumParams
|
||||
{
|
||||
public:
|
||||
HWND Window;
|
||||
const char *deviceName;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
|
||||
{
|
||||
CMonitorEnumParams *p = reinterpret_cast<CMonitorEnumParams *>(dwData);
|
||||
|
||||
MONITORINFOEXA monitorInfo;
|
||||
memset(&monitorInfo, 0, sizeof(monitorInfo));
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
GetMonitorInfoA(hMonitor, &monitorInfo);
|
||||
nldebug("3D: Monitor: '%s'", monitorInfo.szDevice);
|
||||
|
||||
size_t devLen = strlen(monitorInfo.szDevice);
|
||||
size_t targetLen = strlen(p->deviceName);
|
||||
|
||||
nlassert(devLen < 32);
|
||||
size_t minLen = min(devLen, targetLen);
|
||||
if (!memcmp(monitorInfo.szDevice, p->deviceName, minLen))
|
||||
{
|
||||
if (devLen == targetLen
|
||||
|| (devLen < targetLen && (p->deviceName[minLen] == '\\'))
|
||||
|| (devLen > targetLen && (monitorInfo.szDevice[minLen] == '\\')))
|
||||
{
|
||||
nldebug("3D: Remap '%s' to '%s'", p->deviceName, monitorInfo.szDevice);
|
||||
nldebug("Found our monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top);
|
||||
LONG dwStyle = GetWindowLong(p->Window, GWL_STYLE);
|
||||
SetWindowLong(p->Window, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
|
||||
SetWindowPos(p->Window, NULL,
|
||||
monitorInfo.rcMonitor.left,
|
||||
monitorInfo.rcMonitor.top,
|
||||
monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
|
||||
monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
|
||||
SWP_FRAMECHANGED);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE; // continue
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::setScreenMode(const GfxMode &mode)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setScreenMode)
|
||||
|
||||
nldebug("3D: setScreenMode");
|
||||
|
||||
if (mode.Windowed)
|
||||
{
|
||||
// if fullscreen, switch back to desktop screen mode
|
||||
|
@ -1284,13 +1336,16 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!mode.DisplayDevice.empty())
|
||||
restoreScreenMode();
|
||||
|
||||
// save previous screen mode only if switching from windowed to fullscreen
|
||||
if (_CurrentMode.Windowed)
|
||||
saveScreenMode();
|
||||
|
||||
// if switching exactly to the same screen mode, doesn't change it
|
||||
GfxMode previousMode;
|
||||
if (getCurrentScreenMode(previousMode)
|
||||
if (mode.DisplayDevice.empty() && getCurrentScreenMode(previousMode)
|
||||
&& mode.Width == previousMode.Width
|
||||
&& mode.Height == previousMode.Height
|
||||
&& mode.Depth == previousMode.Depth
|
||||
|
@ -1299,7 +1354,9 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
|
|||
|
||||
#if defined(NL_OS_WINDOWS)
|
||||
|
||||
DEVMODE devMode;
|
||||
const char *deviceName = mode.DisplayDevice.c_str();
|
||||
|
||||
DEVMODEA devMode;
|
||||
memset(&devMode, 0, sizeof(DEVMODE));
|
||||
devMode.dmSize = sizeof(DEVMODE);
|
||||
devMode.dmDriverExtra = 0;
|
||||
|
@ -1319,11 +1376,31 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
|
|||
devMode.dmFields |= DM_DISPLAYFREQUENCY;
|
||||
}
|
||||
|
||||
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
||||
if (deviceName[0])
|
||||
{
|
||||
// First attempt exclusive fullscreen
|
||||
nldebug("3D: ChangeDisplaySettingsEx");
|
||||
LONG resex;
|
||||
if ((resex = ChangeDisplaySettingsExA(deviceName, &devMode, NULL, CDS_FULLSCREEN, NULL)) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
nlwarning("3D: Fullscreen mode switch failed (%i)", (sint)resex);
|
||||
// Workaround, resize to monitor and make borderless
|
||||
CMonitorEnumParams p;
|
||||
p.deviceName = deviceName;
|
||||
p.Window = _win;
|
||||
EnumDisplayMonitors(NULL, NULL, monitorEnumProcFullscreen, (LPARAM)&p);
|
||||
return false; // FIXME: This is a hack, don't process further
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nldebug("3D: ChangeDisplaySettings");
|
||||
if (ChangeDisplaySettingsA(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
nlwarning("3D: Fullscreen mode switch failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(NL_OS_MAC)
|
||||
|
||||
|
|
|
@ -249,7 +249,7 @@ bool CDriverUser::setDisplay(nlWindow wnd, const CMode &mode, bool show, bool
|
|||
NL3D_HAUTO_UI_DRIVER;
|
||||
|
||||
// window init.
|
||||
if (_Driver->setDisplay(wnd, GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias), show, resizeable))
|
||||
if (_Driver->setDisplay(wnd, GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias, mode.DisplayDevice), show, resizeable))
|
||||
{
|
||||
// Always true
|
||||
nlverify (activate());
|
||||
|
@ -293,7 +293,7 @@ bool CDriverUser::setDisplay(nlWindow wnd, const CMode &mode, bool show, bool
|
|||
// ***************************************************************************
|
||||
bool CDriverUser::setMode(const CMode& mode)
|
||||
{
|
||||
return _Driver->setMode(GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias));
|
||||
return _Driver->setMode(GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias, mode.DisplayDevice));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -319,7 +319,7 @@ bool CDriverUser::getModes(std::vector<CMode> &modes)
|
|||
bool res = _Driver->getModes(vTmp);
|
||||
modes.clear();
|
||||
for (uint i = 0; i < vTmp.size(); ++i)
|
||||
modes.push_back(CMode(vTmp[i].Width, vTmp[i].Height, vTmp[i].Depth, vTmp[i].Windowed, vTmp[i].Frequency, vTmp[i].AntiAlias));
|
||||
modes.push_back(CMode(vTmp[i].Width, vTmp[i].Height, vTmp[i].Depth, vTmp[i].Windowed, vTmp[i].Frequency, vTmp[i].AntiAlias, vTmp[i].DisplayDevice));
|
||||
|
||||
std::sort(modes.begin(), modes.end(), CModeSorter());
|
||||
|
||||
|
|
|
@ -629,11 +629,8 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass, bool doTrav, boo
|
|||
// clip
|
||||
ClipTrav.traverse();
|
||||
|
||||
if (doTrav)
|
||||
{
|
||||
// animDetail
|
||||
AnimDetailTrav.traverse();
|
||||
}
|
||||
|
||||
// loadBalance
|
||||
LoadBalancingTrav.traverse();
|
||||
|
|
|
@ -211,6 +211,16 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
|
|||
}
|
||||
}
|
||||
|
||||
void CStereoDebugger::attachToDisplay()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CStereoDebugger::detachFromDisplay()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CStereoDebugger::getTextures()
|
||||
{
|
||||
nlassert(!m_LeftTexU);
|
||||
|
@ -437,12 +447,12 @@ bool CStereoDebugger::wantInterface2D()
|
|||
|
||||
bool CStereoDebugger::isSceneFirst()
|
||||
{
|
||||
return m_Stage == 1;
|
||||
return m_Stage != 3;
|
||||
}
|
||||
|
||||
bool CStereoDebugger::isSceneLast()
|
||||
{
|
||||
return m_Stage == 2;
|
||||
return m_Stage != 3;
|
||||
}
|
||||
|
||||
/// Returns true if a new render target was set, always fase if not using render targets
|
||||
|
|
|
@ -165,7 +165,7 @@ static float lerp(float f0, float f1, float factor)
|
|||
return (f1 * factor) + (f0 * (1.0f - factor));
|
||||
}
|
||||
|
||||
CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f)
|
||||
CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NULL), m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f), m_AttachedDisplay(false)
|
||||
{
|
||||
nlctassert(NL_OVR_EYE_COUNT == ovrEye_Count);
|
||||
|
||||
|
@ -371,6 +371,11 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *factory) : m_DevicePtr(NUL
|
|||
|
||||
CStereoOVR::~CStereoOVR()
|
||||
{
|
||||
if (m_AttachedDisplay)
|
||||
{
|
||||
detachFromDisplay();
|
||||
}
|
||||
|
||||
if (!m_UnlitMat.empty())
|
||||
{
|
||||
m_Driver->deleteMaterial(m_UnlitMat);
|
||||
|
@ -439,6 +444,38 @@ bool CStereoOVR::getScreenResolution(uint &width, uint &height)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CStereoOVR::attachToDisplay()
|
||||
{
|
||||
nldebug("OVR: Attach to display '%s'", m_DevicePtr->DisplayDeviceName);
|
||||
|
||||
if (!m_AttachedDisplay)
|
||||
{
|
||||
m_Driver->getCurrentScreenMode(m_OriginalMode);
|
||||
m_Driver->getWindowPos(m_OriginalWinPosX, m_OriginalWinPosY);
|
||||
}
|
||||
|
||||
UDriver::CMode mode;
|
||||
mode.DisplayDevice = m_DevicePtr->DisplayDeviceName;
|
||||
mode.Windowed = false;
|
||||
mode.Width = m_DevicePtr->Resolution.w;
|
||||
mode.Height = m_DevicePtr->Resolution.h;
|
||||
m_Driver->setMode(mode);
|
||||
m_AttachedDisplay = true;
|
||||
}
|
||||
|
||||
void CStereoOVR::detachFromDisplay()
|
||||
{
|
||||
if (!m_OriginalMode.Windowed)
|
||||
{
|
||||
m_OriginalMode.Windowed = true;
|
||||
m_Driver->setMode(m_OriginalMode);
|
||||
m_OriginalMode.Windowed = false;
|
||||
}
|
||||
m_Driver->setMode(m_OriginalMode);
|
||||
m_Driver->setWindowPos(m_OriginalWinPosX, m_OriginalWinPosY);
|
||||
m_AttachedDisplay = false;
|
||||
}
|
||||
|
||||
void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera)
|
||||
{
|
||||
m_OriginalFrustum[cid] = camera->getFrustum();
|
||||
|
@ -679,6 +716,8 @@ bool CStereoOVR::isSceneFirst()
|
|||
{
|
||||
case 3:
|
||||
return true;
|
||||
case 4:
|
||||
return false;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
@ -687,6 +726,8 @@ bool CStereoOVR::isSceneLast()
|
|||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 3:
|
||||
return false;
|
||||
case 4:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
// 3D Interface.
|
||||
#include "nel/3d/u_driver.h"
|
||||
#include "nel/3d/u_text_context.h"
|
||||
#include <nel/3d/stereo_display.h>
|
||||
// Game Share
|
||||
//#include "game_share/gd_time.h" // \todo GUIGUI : TO DELETE/CHANGE
|
||||
#include "game_share/gender.h"
|
||||
|
@ -217,6 +218,9 @@ void connectionRestaureVideoMode ()
|
|||
setVideoMode(mode);
|
||||
}
|
||||
|
||||
if (StereoDisplay)
|
||||
StereoDisplay->attachToDisplay();
|
||||
|
||||
// And setup hardware mouse if we have to
|
||||
InitMouseWithCursor (ClientCfg.HardwareCursor);
|
||||
SetMouseFreeLook ();
|
||||
|
@ -253,6 +257,9 @@ void setOutGameFullScreen()
|
|||
// NB: don't setup fullscreen if player wants to play in window
|
||||
if (!ClientCfg.Local && ClientCfg.SelectCharacter == -1)
|
||||
{
|
||||
if (StereoDisplay)
|
||||
StereoDisplay->detachFromDisplay();
|
||||
|
||||
UDriver::CMode currMode;
|
||||
Driver->getCurrentScreenMode(currMode);
|
||||
UDriver::CMode wantedMode;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <nel/3d/u_driver.h>
|
||||
#include <nel/3d/u_cloud_scape.h>
|
||||
#include <nel/3d/fxaa.h>
|
||||
#include <nel/3d/stereo_display.h>
|
||||
|
||||
#include "game_share/scenario_entry_points.h"
|
||||
|
||||
|
@ -60,6 +61,8 @@ void updateFromClientCfg()
|
|||
nldebug("Apply VR device change");
|
||||
releaseStereoDisplayDevice();
|
||||
initStereoDisplayDevice();
|
||||
if (StereoDisplay)
|
||||
StereoDisplay->attachToDisplay();
|
||||
}
|
||||
|
||||
// GRAPHICS - GENERAL
|
||||
|
@ -69,10 +72,13 @@ void updateFromClientCfg()
|
|||
(ClientCfg.Height != LastClientCfg.Height) ||
|
||||
(ClientCfg.Depth != LastClientCfg.Depth) ||
|
||||
(ClientCfg.Frequency != LastClientCfg.Frequency))
|
||||
{
|
||||
if (!StereoDisplay) // TODO
|
||||
{
|
||||
setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth,
|
||||
ClientCfg.Windowed, ClientCfg.Frequency));
|
||||
}
|
||||
}
|
||||
|
||||
if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue