Fixed: #980 Create a setScreenMode method in OpenGL driver
This commit is contained in:
parent
0563292006
commit
c6fefbcc4c
2 changed files with 110 additions and 91 deletions
|
@ -846,6 +846,7 @@ private:
|
||||||
|
|
||||||
bool restoreScreenMode();
|
bool restoreScreenMode();
|
||||||
bool saveScreenMode();
|
bool saveScreenMode();
|
||||||
|
bool setScreenMode(const GfxMode &mode);
|
||||||
|
|
||||||
// Get the proj matrix setupped in GL
|
// Get the proj matrix setupped in GL
|
||||||
void refreshProjMatrixFromGL();
|
void refreshProjMatrixFromGL();
|
||||||
|
|
|
@ -209,6 +209,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
uint width = mode.Width;
|
uint width = mode.Width;
|
||||||
uint height = mode.Height;
|
uint height = mode.Height;
|
||||||
|
|
||||||
|
if (!setScreenMode(mode))
|
||||||
|
return false;
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
// Driver caps.
|
// Driver caps.
|
||||||
|
@ -541,32 +544,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
|
||||||
WndFlags=WS_POPUP;
|
WndFlags=WS_POPUP;
|
||||||
|
|
||||||
_FullScreen= true;
|
_FullScreen= true;
|
||||||
DEVMODE devMode;
|
|
||||||
_OldScreenMode.dmSize= sizeof(DEVMODE);
|
|
||||||
_OldScreenMode.dmDriverExtra= 0;
|
|
||||||
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &_OldScreenMode);
|
|
||||||
_OldScreenMode.dmFields= DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY ;
|
|
||||||
|
|
||||||
devMode.dmSize= sizeof(DEVMODE);
|
|
||||||
devMode.dmDriverExtra= 0;
|
|
||||||
devMode.dmFields= DM_PELSWIDTH | DM_PELSHEIGHT;
|
|
||||||
devMode.dmPelsWidth= width;
|
|
||||||
devMode.dmPelsHeight= height;
|
|
||||||
|
|
||||||
if(mode.Depth > 0)
|
|
||||||
{
|
|
||||||
devMode.dmBitsPerPel= mode.Depth;
|
|
||||||
devMode.dmFields |= DM_BITSPERPEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mode.Frequency > 0)
|
|
||||||
{
|
|
||||||
devMode.dmDisplayFrequency= mode.Frequency;
|
|
||||||
devMode.dmFields |= DM_DISPLAYFREQUENCY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
WndRect.left=0;
|
WndRect.left=0;
|
||||||
WndRect.top=0;
|
WndRect.top=0;
|
||||||
|
@ -877,51 +854,122 @@ bool CDriverGL::restoreScreenMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
bool CDriverGL::setMode(const GfxMode& mode)
|
bool CDriverGL::setScreenMode(const GfxMode &mode)
|
||||||
{
|
{
|
||||||
H_AUTO_OGL(CDriverGL_setMode)
|
H_AUTO_OGL(CDriverGL_setScreenMode)
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
if (mode.Windowed)
|
if (mode.Windowed)
|
||||||
{
|
{
|
||||||
|
// if fullscreen, switch back to desktop screen mode
|
||||||
if (_FullScreen)
|
if (_FullScreen)
|
||||||
{
|
|
||||||
restoreScreenMode();
|
restoreScreenMode();
|
||||||
modifyStyle(_hWnd, GWL_STYLE, WS_POPUP, WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS);
|
|
||||||
}
|
|
||||||
_WindowWidth = mode.Width;
|
|
||||||
_WindowHeight = mode.Height;
|
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// save previous screen mode only if switching from windowed to fullscreen
|
||||||
// get old mode.
|
|
||||||
if (!_FullScreen)
|
if (!_FullScreen)
|
||||||
saveScreenMode();
|
saveScreenMode();
|
||||||
|
|
||||||
// setup new mode
|
// if switching exactly to the same screen mode, doesn't change it
|
||||||
DEVMODE newDevMode;
|
GfxMode previousMode;
|
||||||
newDevMode.dmSize= sizeof(DEVMODE);
|
if (getCurrentScreenMode(previousMode)
|
||||||
newDevMode.dmDriverExtra= 0;
|
&& mode.Width == previousMode.Width
|
||||||
newDevMode.dmFields= DM_PELSWIDTH | DM_PELSHEIGHT;
|
&& mode.Height == previousMode.Height
|
||||||
newDevMode.dmPelsWidth= mode.Width;
|
&& mode.Depth == previousMode.Depth
|
||||||
newDevMode.dmPelsHeight= mode.Height;
|
&& mode.Frequency == previousMode.Frequency)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#if defined(NL_OS_WINDOWS)
|
||||||
|
|
||||||
|
DEVMODE devMode;
|
||||||
|
memset(&devMode, 0, sizeof(DEVMODE));
|
||||||
|
devMode.dmSize = sizeof(DEVMODE);
|
||||||
|
devMode.dmDriverExtra = 0;
|
||||||
|
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||||
|
devMode.dmPelsWidth = mode.Width;
|
||||||
|
devMode.dmPelsHeight = mode.Height;
|
||||||
|
|
||||||
if(mode.Depth > 0)
|
if(mode.Depth > 0)
|
||||||
{
|
{
|
||||||
newDevMode.dmBitsPerPel= mode.Depth;
|
devMode.dmBitsPerPel = mode.Depth;
|
||||||
newDevMode.dmFields |= DM_BITSPERPEL;
|
devMode.dmFields |= DM_BITSPERPEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode.Frequency > 0)
|
if(mode.Frequency > 0)
|
||||||
{
|
{
|
||||||
newDevMode.dmDisplayFrequency= mode.Frequency;
|
devMode.dmDisplayFrequency = mode.Frequency;
|
||||||
newDevMode.dmFields |= DM_DISPLAYFREQUENCY;
|
devMode.dmFields |= DM_DISPLAYFREQUENCY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to really change the display mode
|
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
||||||
if (ChangeDisplaySettings(&newDevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
{
|
||||||
|
nlwarning("Fullscreen mode switch failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
|
||||||
|
#if defined(XF86VIDMODE)
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
// Find the requested mode and use it
|
||||||
|
XF86VidModeModeInfo **modes;
|
||||||
|
int nmodes;
|
||||||
|
if (XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &modes))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nmodes; i++)
|
||||||
|
{
|
||||||
|
nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
|
||||||
|
if (modes[i]->hdisplay == width && modes[i]->vdisplay == height)
|
||||||
|
{
|
||||||
|
if (XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), modes[i]))
|
||||||
|
{
|
||||||
|
nlinfo("3D: Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
|
||||||
|
XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), 0, 0);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#endif // XF86VIDMODE
|
||||||
|
|
||||||
|
#endif // NL_OS_WINDOWS
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
bool CDriverGL::setMode(const GfxMode& mode)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_setMode)
|
||||||
|
|
||||||
|
if (!setScreenMode(mode))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
if (mode.Windowed)
|
||||||
|
{
|
||||||
|
if (_FullScreen)
|
||||||
|
modifyStyle(_hWnd, GWL_STYLE, WS_POPUP, WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS);
|
||||||
|
|
||||||
|
_WindowWidth = mode.Width;
|
||||||
|
_WindowHeight = mode.Height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// mode ok => copy changes
|
// mode ok => copy changes
|
||||||
_WindowWidth = mode.Width;
|
_WindowWidth = mode.Width;
|
||||||
_WindowHeight = mode.Height;
|
_WindowHeight = mode.Height;
|
||||||
|
@ -961,42 +1009,11 @@ bool CDriverGL::setMode(const GfxMode& mode)
|
||||||
_FullScreen = !mode.Windowed;
|
_FullScreen = !mode.Windowed;
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
||||||
|
|
||||||
NL3D::MAC::setMode(mode);
|
NL3D::MAC::setMode(mode);
|
||||||
|
|
||||||
#elif defined(NL_OS_UNIX)
|
#elif defined(NL_OS_UNIX)
|
||||||
|
|
||||||
#ifdef XF86VIDMODE
|
|
||||||
if (!mode.Windowed)
|
|
||||||
{
|
|
||||||
int screen = DefaultScreen(_dpy);
|
|
||||||
|
|
||||||
// Store old mdoe in order to restore it when leaving fullscreen
|
|
||||||
if (mode.Windowed == _FullScreen)
|
|
||||||
saveScreenMode();
|
|
||||||
|
|
||||||
// Find the requested mode and use it
|
|
||||||
XF86VidModeModeInfo **modes;
|
|
||||||
int nmodes;
|
|
||||||
if (XF86VidModeGetAllModeLines(_dpy, screen, &nmodes, &modes))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < nmodes; i++)
|
|
||||||
{
|
|
||||||
nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
|
|
||||||
if(modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height)
|
|
||||||
{
|
|
||||||
if(XF86VidModeSwitchToMode(_dpy, screen, modes[i]))
|
|
||||||
{
|
|
||||||
nlinfo("3D: Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
|
|
||||||
XF86VidModeSetViewPort(_dpy, screen, 0, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode.Windowed == _FullScreen)
|
|
||||||
restoreScreenMode();
|
|
||||||
#endif // XF86VIDMODE
|
|
||||||
|
|
||||||
// Update WM hints (update size and disallow resizing)
|
// Update WM hints (update size and disallow resizing)
|
||||||
XSizeHints size_hints;
|
XSizeHints size_hints;
|
||||||
size_hints.x = 0;
|
size_hints.x = 0;
|
||||||
|
@ -1048,6 +1065,7 @@ bool CDriverGL::setMode(const GfxMode& mode)
|
||||||
XMapWindow(_dpy, _win);
|
XMapWindow(_dpy, _win);
|
||||||
|
|
||||||
#endif // NL_OS_UNIX
|
#endif // NL_OS_UNIX
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue